Re: on pagefaults and nonsense :) + a sound-related problem

Jeremy Fitzhardinge (jeremy@zip.com.au)
Thu, 31 Jul 1997 13:06:57 +1000


This is a multi-part message in MIME format.
--------------C32EF7B4161FACFE6C593C08
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Teunis Peters wrote:
> Is there a way to do userspace pagefault handling?
>
> This was talked about last year but I never heard anymore about it...

There's lots of uses for it (garbage collection is another one which
springs to mind). The most common, mostly portable way, is to catch
SIGSEGV and do something with it. Actually finding out what address was
the cause of the fault is not portable, but its not very tricky and easy
to isolate. I've attached a program to give you the general idea.

Linux is pretty good at this: other Unixes are *very* slow at handling
SIGSEGV, presumeably on the misguided assumption that its "just a
debugging thing for bad programs". Still, I sped up Linux's SIGSEGV
handling by 20% by changing the order of a couple of tests: see
www.linuxhq.com for the patch.

> As I'm writing a JIT (it's the same program I've mentioned before as a GUI
> + a couple of other things... <G>) this could be of some use...

Perhaps. I've found there's generally better ways of doing an on-demand
compile of code. Using pages is pretty coarse. Handling a pagefault is
somewhere around 5000-10000 cycles effort, so you'd better make sure its
worthwhile. Also, if you get a pagefault, you have to compile a whole
page's worth of code, which is probably lots more than you want to.

> Oh, and on sound : Any idea how to use /dev/dsp (or the like)
> bidirectionally? The docs aren't all that clear [as a matter of fact,
> they seem to be nonexistant].

There's some detail on it on http://www.4front-tech.com/pguide.

> Oh, and one last question: Would it be a good idea to use asm/spinlock.h
> as a model for doing thread locks? This is for assembly code (or lisp).
>
> [need read-many/write-once and read/write locks - just like 'spinlock.h'
> has]

You could do, but its not very portable (you'd have difficulty using
them in usermode on non-Intel machines, let alone other operating
systems). You'd probably be better off using pthreads, at least until
you've decided that there's a real performance issue.

> I only have one processor and wish to make my code SMP-friendly (or at
> least SMP-safe).. the code is very multithreaded.

What are you working on? Sounds interesting...

J
--------------C32EF7B4161FACFE6C593C08
Content-Type: text/plain; charset=us-ascii; name="timefault.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="timefault.c"

#include <sys/mman.h>
#include <signal.h>
#include <asm/sigcontext.h>

static void fault(int sig, struct sigcontext si);

static struct sigaction sa = {
fault, 0, SA_RESTART, 0
};

#ifndef PROT
#define PROT PROT_NONE
#endif

static int pagesize;

static void fault(int sig, struct sigcontext si)
{
void *faultaddr = (void *)si.cr2;

/* printf("fault addr %p\n", faultaddr); */

mprotect(faultaddr, pagesize, PROT_READ|PROT_WRITE);
}

int main(int argc, char **argv)
{
int i;
char *mem;

pagesize = getpagesize();
mem = mmap(0, pagesize, PROT,
MAP_PRIVATE|MAP_ANON, 0, 0);

if (mem == (char *)-1)
perror("mmap failed");

if (sigaction(SIGSEGV, &sa, 0) == -1)
perror("failed to set signal");

for(i = 0; i < 1000000; i++)
{
*mem = 'a';
if ((PROT) == PROT_NONE)
mprotect(mem, pagesize, PROT);
}

return 0;
}

--------------C32EF7B4161FACFE6C593C08--