[gforth] / gforth / unix / pthread.fs  

gforth: gforth/unix/pthread.fs

Diff for /gforth/unix/pthread.fs between version 1.1 and 1.2

version 1.1, Tue Mar 13 22:56:39 2012 UTC version 1.2, Wed Mar 14 14:43:33 2012 UTC
Line 22 
Line 22 
     \c #include <limits.h>      \c #include <limits.h>
     \c #include <sys/mman.h>      \c #include <sys/mman.h>
     \c #include <unistd.h>      \c #include <unistd.h>
     \c extern void * alloc_mmap(Cell size);      \c #define wholepage(n) (((n)+pagesize-1)&~(pagesize-1))
     \c extern void page_noaccess(void *a);  
     \c #define wholepage(n) (((n)+p-1)&~(p-1))  
     \c typedef struct {      \c typedef struct {
     \c   Cell data_stack_size;      \c   Cell data_stack_size;
     \c   Cell fp_stack_size;      \c   Cell fp_stack_size;
     \c   Cell return_stack_size;      \c   Cell return_stack_size;
     \c   Cell locals_stack_size;      \c   Cell locals_stack_size;
     \c   void *boot_entry;      \c   Cell sp0, fp0, rp0, lp0;
     \c } ImageHeader;      \c   Cell boot_entry;
     \c void *gforth_thread(ImageHeader * header)      \c } threadId;
     \c {      \c int pagesize = 1;
     \c   Cell *sp0;      \c void page_noaccess(void *a)
     \c   Cell *rp0;      \c {
     \c   Float *fp0;      \c   /* try mprotect first; with munmap the page might be allocated later */
     \c   char *lp0;      \c   if (mprotect(a, pagesize, PROT_NONE)==0) {
     \c   Cell      \c     return;
       \c   }
       \c   if (munmap(a,pagesize)==0) {
       \c     return;
       \c   }
       \c }
       \c void * alloc_mmap(Cell size)
       \c {
       \c   void *r;
       \c
       \c #if defined(MAP_ANON)
       \c   r = mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
       \c #else /* !defined(MAP_ANON) */
       \c   /* Ultrix (at least) does not define MAP_FILE and MAP_PRIVATE (both are
       \c      apparently defaults) */
       \c   static int dev_zero=-1;
       \c
       \c   if (dev_zero == -1)
       \c     dev_zero = open("/dev/zero", O_RDONLY);
       \c   if (dev_zero == -1) {
       \c     r = MAP_FAILED;
       \c   } else {
       \c     r=mmap(NULL, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, dev_zero, 0);
       \c   }
       \c #endif /* !defined(MAP_ANON) */
       \c   return r;
       \c }
       \c void *gforth_thread(threadId * t)
       \c {
     \c #if HAVE_GETPAGESIZE      \c #if HAVE_GETPAGESIZE
     \c   p=getpagesize(); /* Linux/GNU libc offers this */      \c   pagesize=getpagesize(); /* Linux/GNU libc offers this */
     \c #elif HAVE_SYSCONF && defined(_SC_PAGESIZE)      \c #elif HAVE_SYSCONF && defined(_SC_PAGESIZE)
     \c   p=sysconf(_SC_PAGESIZE); /* POSIX.4 */      \c   pagesize=sysconf(_SC_PAGESIZE); /* POSIX.4 */
     \c #elif PAGESIZE      \c #elif PAGESIZE
     \c   p=PAGESIZE; /* in limits.h according to Gallmeister's POSIX.4 book */      \c   pagesize=PAGESIZE; /* in limits.h according to Gallmeister's POSIX.4 book */
     \c #endif      \c #endif
     \c   Cell dsize = wholepage(header->data_stack_size);      \c   Cell dsize = wholepage(t->data_stack_size);
     \c   Cell rsize = wholepage(header->return_stack_size);      \c   Cell rsize = wholepage(t->return_stack_size);
     \c   Cell fsize = wholepage(header->fp_stack_size);      \c   Cell fsize = wholepage(t->fp_stack_size);
     \c   Cell lsize = wholepage(header->locals_stack_size);      \c   Cell lsize = wholepage(t->locals_stack_size);
     \c   size_t totalsize = dsize+fsize+rsize+lsize+5*p;      \c   size_t totalsize = dsize+fsize+rsize+lsize+5*pagesize;
     \c   void *a = alloc_mmap(totalsize);      \c   Cell a = (Cell)alloc_mmap(totalsize);
     \c   if (a != (void *)MAP_FAILED) {      \c   if (a != (Cell)MAP_FAILED) {
     \c     page_noaccess(a); a+=p; a+=dsize; sp0=a;      \c     page_noaccess((void*)a); a+=pagesize; a+=dsize; t->sp0=a;
     \c     page_noaccess(a); a+=p; a+=fsize; fp0=a;      \c     page_noaccess((void*)a); a+=pagesize; a+=fsize; t->fp0=a;
     \c     page_noaccess(a); a+=p; a+=rsize; rp0=a;      \c     page_noaccess((void*)a); a+=pagesize; a+=rsize; t->rp0=a;
     \c     page_noaccess(a); a+=p; a+=lsize; lp0=a;      \c     page_noaccess((void*)a); a+=pagesize; a+=lsize; t->lp0=a;
     \c     page_noaccess(a);      \c     page_noaccess((void*)a);
     \c     return gforth_engine(header->boot_entry, sp0, rp0, fp0, lp0, 0);      \c     return gforth_engine((void*)(t->boot_entry), (Cell*)(t->sp0), (Cell*)(t->rp0), (Float*)(t->fp0), (void*)(t->lp0), 0);
     \c   }      \c   }
     \c   return NULL;      \c   return NULL;
     \c }      \c }
Line 79 
Line 105 
     c-function thread_start gforth_thread_p -- a ( -- addr )      c-function thread_start gforth_thread_p -- a ( -- addr )
     c-function pthread_create pthread_create a a a a -- n ( thread attr start arg )      c-function pthread_create pthread_create a a a a -- n ( thread attr start arg )
 end-c-library  end-c-library
   
   begin-structure threadId
   field: data_stack_size
   field: fp_stack_size
   field: return_stack_size
   field: locals_stack_size
   field: t_sp0
   field: t_fp0
   field: t_rp0
   field: t_lp0
   field: boot_entry
   0 pthread+ +field t_pthread
   end-structure
   
   : new-thread ( xt -- id )
       threadId allocate throw >r
       forthstart 3 cells + r@ 4 cells move
       >body r@ boot_entry !
       r@ t_pthread 0 thread_start r@ pthread_create
       drop \ fixme
       r> ;
   
   0 [IF] \ test
       : test-thread
           BEGIN  ." Thread-Test" cr 1000 ms  AGAIN ;
   
       ' test-thread new-thread Constant test-id
   [THEN]


Generate output suitable for use with a patch program
Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

CVS Admin

Powered by ViewCVS 1.0-dev
(Powered by ViewCVS)

ViewCVS and CVS Help