int main() { int dummy; long ps = GETPAGESIZE(); jmp_buf b; register int x = (int)strlen("a"); /* 1, slightly disguised */ static int y = 0; printf("This appears to be a %s running %s\n", MACH_TYPE, OS_TYPE); if (nested_sp() < &dummy) { printf("Stack appears to grow down, which is the default.\n"); printf("A good guess for STACKBOTTOM on this machine is 0x%lx.\n", ((unsigned long)(&dummy) + ps) & ~(ps-1)); } else { printf("Stack appears to grow up.\n"); printf("Define STACK_GROWS_UP in gc_private.h\n"); printf("A good guess for STACKBOTTOM on this machine is 0x%lx.\n", ((unsigned long)(&dummy) + ps) & ~(ps-1)); } printf("Note that this may vary between machines of ostensibly\n"); printf("the same architecture (e.g. Sun 3/50s and 3/80s).\n"); printf("On many machines the value is not fixed.\n"); printf("A good guess for ALIGNMENT on this machine is %ld.\n", (unsigned long)(&(a.a_b))-(unsigned long)(&a)); printf("The following is a very dubious test of one root marking" " strategy.\n"); printf("Results may not be accurate/useful:\n"); /* Encourage the compiler to keep x in a callee-save register */ x = 2*x-1; printf(""); x = 2*x-1; setjmp(b); if (y == 1) { if (x == 2) { printf("Setjmp-based generic mark_regs code probably wont work.\n"); printf("But we rarely try that anymore. If you have getcontect()\n"); printf("this probably doesn't matter.\n"); } else if (x == 1) { printf("Setjmp-based register marking code may work.\n"); } else { printf("Very strange setjmp implementation.\n"); } } y++; x = 2; if (y == 1) longjmp(b,1); printf("Some GC internal configuration stuff: \n"); printf("\tWORDSZ = %d, ALIGNMENT = %d, GC_GRANULE_BYTES = %d\n", WORDSZ, ALIGNMENT, GC_GRANULE_BYTES); printf("\tUsing one mark "); # if defined(USE_MARK_BYTES) printf("byte"); # elif defined(USE_MARK_BITS) printf("bit"); # endif printf(" per "); # if defined(MARK_BIT_PER_OBJ) printf("object.\n"); # elif defined(MARK_BIT_PER_GRANULE) printf("granule.\n"); # endif # ifdef THREAD_LOCAL_ALLOC printf("Thread local allocation enabled.\n"); # endif # ifdef PARALLEL_MARK printf("Parallel marking enabled.\n"); # endif return(0); }
/** * Load the contents of a text file. There are two separate implementations, * depending up on whether mmap(3) is available. * * If not available, malloc the file length plus one byte. Read it in * and NUL terminate. * * If available, first check to see if the text file size is a multiple of a * page size. If it is, map the file size plus an extra page from either * anonymous memory or from /dev/zero. Then map the file text on top of the * first pages of the anonymous/zero pages. Otherwise, just map the file * because there will be NUL bytes provided at the end. * * @param mapinfo a structure holding everything we need to know * about the mapping. * * @param pzFile name of the file, for error reporting. */ static void load_text_file(tmap_info_t * mapinfo, char const * pzFile) { #if ! defined(HAVE_MMAP) mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text"); if (mapinfo->txt_data == NULL) { mapinfo->txt_errno = ENOMEM; return; } { size_t sz = mapinfo->txt_size; char* pz = mapinfo->txt_data; while (sz > 0) { ssize_t rdct = read(mapinfo->txt_fd, pz, sz); if (rdct <= 0) { mapinfo->txt_errno = errno; fserr_warn("libopts", "read", pzFile); free(mapinfo->txt_data); return; } pz += rdct; sz -= rdct; } *pz = NUL; } mapinfo->txt_errno = 0; #else /* HAVE mmap */ size_t const pgsz = (size_t)GETPAGESIZE(); void * map_addr = NULL; (void)pzFile; mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1); if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) { /* * The text is a multiple of a page boundary. We must map an * extra page so the text ends with a NUL. */ #if defined(MAP_ANONYMOUS) map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0); #else mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY); if (mapinfo->txt_zero_fd == AO_INVALID_FD) { mapinfo->txt_errno = errno; return; } map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, mapinfo->txt_zero_fd, 0); #endif if (map_addr == MAP_FAILED_PTR) { mapinfo->txt_errno = errno; return; } mapinfo->txt_flags |= MAP_FIXED; } mapinfo->txt_data = mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot, mapinfo->txt_flags, mapinfo->txt_fd, 0); if (mapinfo->txt_data == MAP_FAILED_PTR) mapinfo->txt_errno = errno; #endif /* HAVE_MMAP */ }
int ThrStart( int tmax, int ticks ) { Thread t ; /* * Initialize scheduler module */ if ( (ThrPageSize = GETPAGESIZE()) <= 0 ) { ThrPanic( "GETPAGESIZE(): %m." ) ; } if ( (ThrDevZero = open( "/dev/zero", O_RDWR ) ) < 0 ) { ThrPanic( "open(/dev/zero): %m." ) ; } if ( tmax < 2 || THREAD_ID_MAX < tmax ) { ThrPanic( "ThrStart() : Invalid thread max = %d.", tmax ) ; } thrThreadTable = malloc( sizeof(ThreadRec) * tmax ) ; if ( thrThreadTable == NULL ) { ThrPanic( "ThrStart() Can't malloc Thread table[%d]: %m.", tmax ) ; } thrThreadTableBreak = thrThreadTable + tmax ; t = thrThreadTableBreak ; while ( thrThreadTable != t -- ) { t->tid = 0 ; t->next = thrFreeThreads ; thrFreeThreads = t ; } /* * Initialize other modules without multithread. */ StkInitialize() ; SigInitialize() ; BrkInitialize() ; /* * Startup multithread scheduler. */ SigAction( SIGALRM, thrHandlerSIGALRM ) ; SigAction( SIGSEGV, thrHandlerSIGSEGV ) ; SigAction( SIGBUS, thrHandlerSIGSEGV ) ; SigAction( SIGILL, thrHandlerSIGSEGV ) ; SigAction( SIGFPE, thrHandlerSIGSEGV ) ; SigAction( SIGTERM, thrHandlerSIGHUP ) ; SigAction( SIGHUP, thrHandlerSIGHUP ) ; /* Create idle thread (tid=0) */ ThrRunningThread = &thrMain ; thrMain.StdIn = 0 ; thrMain.StdOut = 1 ; thrMain.StdErr = 2 ; thrMain.status = READY ; thrMain.first = 0 ; thrIdleThread = ThrCreate( thrIdle, NULL, 0, 0, 0, 1, ticks ) ; /* Multithread scheduler start. */ sigBlocking = 0 ; thrSwitch( thrIdleThread ) ; /* * Cleanup multithread scheduler. */ SigAction( SIGALRM, SIG_IGN ) ; SigAction( SIGSEGV, SIG_DFL ) ; SigAction( SIGBUS, SIG_DFL ) ; SigAction( SIGILL, SIG_DFL ) ; SigAction( SIGFPE, SIG_DFL ) ; SigAction( SIGTERM, SIG_DFL ) ; SigAction( SIGHUP, SIG_DFL ) ; SigAction( SIGTRAP, SIG_DFL ) ; /* * Shutdown other modules without multithread. */ BrkShutdown() ; SigShutdown() ; StkShutdown() ; /* * Shutdown scheduler module */ close( ThrDevZero ) ; free( thrThreadTable ) ; return( thrMain.aborted ) ; }