/* thread.c -- linux threading support (stolen mostly from one of linus' posts on linux-kernel) */ #include #include #include #include #include /* flags to use when creating a new thread */ #define CSIGNAL 0x000000ff /* signal mask sent at exit */ #define CLONE_MEM 0x00000100 /* set to share memory */ #define CLONE_FS 0x00000200 /* set to share "fs info" (?) */ #define CLONE_FILES 0x00000400 /* set to share open files */ #define CLONE_SIGHAND 0x00000800 /* set to share signal handlers */ typedef void (*clonefunc)(void *); /* create a new thread -- returns pid or -1 on error */ int new_thread(fn,data,flags,stacksize) clonefunc fn; void *data; unsigned int stacksize,flags; { long retval; void **newstack; /* make the new stack: */ newstack=(void **)nmalloc(stacksize); if (!newstack) return (-1); /* rearrange pointer so it's at the other end of the memory block */ newstack=(void **)(stacksize+(char *)newstack); /* put the (void *)data on the new stack */ *--newstack=data; /* now linus does some assembly in this weird psued-language i have */ /* no clue about... sheesh. */ __asm__ __volatile__( "int $0x80\n\t" "testl %0,%0\n\t" "jne 1f\n\t" "call *%3\n\t" "movl %2,%0\n\t" "int $0x80\n" "1:\t" :"=a" (retval) :"0" (__NR_clone),"i" (__NR_exit), "r" (fn),"b" (flags|SIGCHLD),"c" (newstack)); if (retval<0) { errno=(-retval); retval=(-1); } return retval; }