/* tic.h - main header file for tic backends */ /* see copyright.txt for usage terms */ #ifndef TIC_H #define TIC_H #include "backend-defines.h" #include #include #include #include #include #include #include #include /* .......... * * GC stuff - MUST come before pthread stuff and GASNet * * .......... */ #ifndef USE_GC_NONE #include "gc/include/gc.h" #endif /* ........................ * * Message Layer * * ........................ */ #if defined(GLUNIX) #include #endif #define LOWWORD(i) ((julong)(i) & 0xFFFFFFFFUL) #define HIGHWORD(i) LOWWORD((julong)(i) >> 32) #define SETLOWWORD(ptr, i) (*(ptr)) = (HIGHWORD(*(ptr)) << 32) | LOWWORD(i) #define SETHIGHWORD(ptr, i) (*(ptr)) = (LOWWORD(((julong)(i))) << 32) | LOWWORD(*(ptr)) #ifdef COMM_AM2 #if defined(COMM_GASNET) #include #define AM2_HAS_HUGE_SEGMENTS 1 /* supports them, by GASNet SEGMENT_EVERYTHING configuration */ #define AM2_REPLY_REQUIRED 0 #elif defined(COMM_AMUDP) #include #include #define AM2_HAS_HUGE_SEGMENTS 0 /* supports them, but no perf advantage */ #define AM2_REPLY_REQUIRED 0 #elif defined(COMM_AMMPI) #include #include #define AM2_HAS_HUGE_SEGMENTS 0 /* supports them, but no perf advantage */ #define AM2_REPLY_REQUIRED 0 #elif defined(COMM_AMLAPI) #include #include #define AM2_HAS_HUGE_SEGMENTS 1 #define AM2_REPLY_REQUIRED 0 #elif defined(COMM_AMNOW) #include #define AM2_HAS_HUGE_SEGMENTS 0 /* OS limit for DMA registration prevents this */ #define AM2_REPLY_REQUIRED 1 #elif defined(COMM_AMVIA) #include #define AM2_HAS_HUGE_SEGMENTS 0 /* OS limit for DMA registration prevents this */ #define AM2_REPLY_REQUIRED 1 #else #error unknown AM implementation #endif #define TIC_TAG 18 #endif /* portable tools that we use on all backends */ #include /* ............................. * * Control 'extern' and `inline' * * ............................. */ /* Defining TIC_INTERNAL_DEFINE has the effect of producing a * real (non-extern) version of all variables. * Exactly one .c file should define this in the distribution */ #ifdef TIC_INTERNAL_DEFINE # define EXTERN_DATA #else # define EXTERN_DATA extern #endif /* Defining TIC_DISABLE_INLINE has the effect of disabling all inlining of functions * which helps when debugging. */ #ifndef TIC_DISABLE_INLINE #ifdef NDEBUG #define TIC_DISABLE_INLINE 0 #else #define TIC_DISABLE_INLINE 1 #endif #endif #if TIC_DISABLE_INLINE #define TI_INLINE(fnname) static #else #define TI_INLINE(fnname) GASNETT_INLINE_MODIFIER(fnname) #endif #define _TIC_CONCAT_HELPER(a,b) a ## b #define TIC_CONCAT(a,b) _TIC_CONCAT_HELPER(a,b) #include #include "gp-type.h" /* .......... * * Boxes and Processors * * .......... */ #define MAX_PROCS 1024 #ifdef MEMORY_SHARED #define MAX_BOX_PROCS ((Process)1024) #define TIC_MYPROC myProcessNumber() #define TIC_MYBOXPROC myBoxProcessNumber() extern Process TIC_MYBOXPROCS; #else #define MAX_BOX_PROCS ((Process)1) extern Process TIC_MYPROC; #define TIC_MYBOXPROC ((Process)0) #define TIC_MYBOXPROCS ((Process)1) #endif extern Process TIC_PROCS; extern Box TIC_BOXES; extern Box TIC_MYBOX; /* extern tic_thread_key_t thread_key; */ #define MYPROC TIC_MYPROC #define PROCS TIC_PROCS #define MYBOX TIC_MYBOX #define MYBOXPROC TIC_MYBOXPROC #define MYBOXPROCS TIC_MYBOXPROCS #define BOXES TIC_BOXES extern int politep; extern void *tic_main(int argc, char **argv); /* .......... * * Thread operation wrappers * * .......... */ #ifndef EXTRA_SYNC_CHECKING /* set to non-zero to enable extra checking for error values */ #ifdef NDEBUG #define EXTRA_SYNC_CHECKING 0 #else #define EXTRA_SYNC_CHECKING 1 #endif #endif /* error checking macros for system functions */ #if EXTRA_SYNC_CHECKING TI_INLINE(__tic_errcheck_helper) int __tic_errcheck_helper(int actualval, int okval, int altok, char* where) { if ((!!actualval) == okval || actualval == altok) return actualval; else { char altstr[20]; if (altok != okval) sprintf(altstr, "(or %i)", altok); else altstr[0] = '\0'; fprintf(stderr, "Tic: Error while calling: %s\n", where); fprintf(stderr, "Tic: expected %s%s, got %i (%s)\n", (okval?"non-zero":"zero"), altstr, actualval, strerror(actualval)); fprintf(stderr, "Tic: errno = %i (%s)\n", errno, strerror(errno)); abort(); return actualval; } } #define __tic_errcheckZ(fn) __tic_errcheck_helper(fn, 0, 0, #fn) #define __tic_errcheckZopt(fn,opt) __tic_errcheck_helper(fn, 0, opt, #fn) #define __tic_errcheckNZ(fn) __tic_errcheck_helper(fn, 1, 1, #fn) #else /* compile away */ #define __tic_errcheckZ(fn) (fn) #define __tic_errcheckZopt(fn,opt) (fn) #define __tic_errcheckNZ(fn) (fn) #endif #if defined (THREAD) /* Solaris Threads */ #include #define tic_thread_t thread_t #define tic_thread_self() thread_self() #define tic_create_thread(func, arg, threadptr) \ thr_create(NULL, NULL, func, arg, THR_BOUND, threadptr) #define tic_thread_join(thread, retval) thr_join(0, NULL, retval) #define tic_thread_set_concurrency(conc) thr_setconcurrency(conc) #define tic_thread_key_t thread_key_t #define tic_thread_key_init(key) thr_keycreate(key, NULL) #define tic_thread_get_key_value(key, ptr) thr_getspecific(key, (void **)ptr) #define tic_thread_set_key_value(key, ptr) thr_setspecific(key, (void *)(ptr)) #elif defined(PTHREAD) #include #define tic_thread_t pthread_t #define tic_thread_self() pthread_self() extern int __tic_create_pthread(void *(*thread_func)(void *), void *arg, tic_thread_t *threadptr); #define tic_create_thread __tic_create_pthread #define tic_thread_join(thread, retval) __tic_errcheckZ(pthread_join(thread, retval)) #ifdef HAVE_PTHREAD_SETCONCURRENCY /* this isn't supported in all pthread implementations - however, it's just a hint to the pthread scheduler anyhow */ #define tic_thread_set_concurrency(conc) __tic_errcheckZ(pthread_setconcurrency(conc)) #else #define tic_thread_set_concurrency(conc) #endif #define tic_thread_key_t pthread_key_t #define tic_thread_key_init(key) __tic_errcheckZ(pthread_key_create(key, NULL)) #define tic_thread_get_key_value(key, ptr) (*ptr) = pthread_getspecific(key) #define tic_thread_set_key_value(key, ptr) __tic_errcheckZ(pthread_setspecific(key, ptr)) #else /* NO Threads */ #define tic_thread_t int #define tic_thread_self() 0 #define tic_create_thread(func, arg, threadptr) (abort(),0) #define tic_thread_join(thread, retval) (abort(),0) #define tic_thread_set_concurrency(conc) 0 #define tic_thread_key_t void ** #define tic_thread_key_init(key) ((*key) = (void **)ti_malloc(sizeof(void *)), (int)!(*key)) #define tic_thread_get_key_value(key, ptr) ((*(void **)ptr) = (*key), 0) #define tic_thread_set_key_value(key, ptr) ((*key) = (void *)ptr, 0) #endif /* Threads */ /* Locks and Mutexes */ #ifndef MEMORY_SHARED #define ti_lock_t int #define ti_cond_t int #define ti_lock_init(lock) 0 #define ti_lock_initializer 0 #define ti_lock_decl_initializer 0 #define ti_cond_init(cond, lock) #define ti_cond_initializer 0 #define ti_cond_decl_initializer 0 #define ti_lock(lock) 0 #define ti_try_lock(lock) 1 #define ti_unlock(lock) 0 #define ti_mon_wait(mon) abort() #define ti_mon_timedwait(mon, tm) abort() #define ti_mon_signal(mon) abort() #define ti_mon_broadcast(mon) abort() #define ti_lock_destroy(lock) 0 #define ti_cond_destroy(cond) 0 #define ti_time_t struct timespec #elif defined (THREAD) /* Solaris Threads */ #define ti_lock_t mutex_t #define ti_cond_t cond_t /* If at runtime we know there's only one processor on this box, we don't need to perform synchronization. */ #define ti_lock_init(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(mutex_init(lock, USYNC_THREAD, NULL)) : 0) TI_INLINE(__tic_new_lock) ti_lock_t __tic_new_lock(void) { ti_lock_t var = DEFAULT_MUTEX; return var; } #define ti_lock_initializer __tic_new_lock() #define ti_lock_decl_initializer DEFAULT_MUTEX #define ti_cond_init(cond, lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(cond_init(cond, USYNC_THREAD, NULL)) : 0) TI_INLINE(__tic_new_cond) ti_cond_t __tic_new_cond(void) { ti_cond_t var = DEFAULTCV; return var; } #define ti_cond_initializer __tic_new_cond() #define ti_cond_decl_initializer DEFAULTCV #define ti_lock(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(mutex_lock(lock)) : 0) #define ti_try_lock(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZopt(mutex_trylock(lock), EBUSY) : 1) #define ti_unlock(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(mutex_unlock(lock)) : 0) #define ti_mon_wait(mon) \ do { if (MYBOXPROCS > 1) { \ __tic_errcheckZ(cond_wait(&(mon->condvar), &(mon->lock))); \ } else { \ fprintf(stderr, "Tic: INTERNAL ERROR: called ti_mon_wait with MYBOXPROCS==1"); \ abort(); \ } \ } while(0) #define ti_mon_timedwait(mon, tm) do { \ if (MYBOXPROCS > 1) \ __tic_errcheckZopt(cond_timedwait(&(mon->condvar), &(mon->lock), tm), ETIMEDOUT); \ else ti_sleepuntil(tm); \ } while(0) #define ti_mon_signal(mon) \ do { if (MYBOXPROCS > 1) __tic_errcheckZ(cond_signal(&(mon->condvar))); } while(0) #define ti_mon_broadcast(mon) \ do { if (MYBOXPROCS > 1) __tic_errcheckZ(cond_broadcast(&(mon->condvar))); } while(0) #define ti_lock_destroy(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(mutex_destroy(lock)) : 0) #define ti_cond_destroy(cond) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(cond_destroy(cond)) : 0) #define ti_time_t timestruc_t #elif defined(PTHREAD) #define ti_lock_t pthread_mutex_t #define ti_cond_t pthread_cond_t /* If at runtime we know there's only one processor on this box, we don't need to perform synchronization. */ #if EXTRA_SYNC_CHECKING && defined(LINUX) TI_INLINE(__tic_new_lock) ti_lock_t __tic_new_lock(void) { ti_lock_t lock; pthread_mutexattr_t attr; __tic_errcheckZ(pthread_mutexattr_init(&attr)); __tic_errcheckZ(pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_ERRORCHECK_NP)); __tic_errcheckZ(pthread_mutex_init(&lock, &attr)); __tic_errcheckZ(pthread_mutexattr_destroy(&attr)); return lock; } #define ti_lock_init(lock) \ ((MYBOXPROCS > 1) ? *lock = __tic_new_lock(), 0 : 0) #else #define ti_lock_init(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(pthread_mutex_init(lock, NULL)) : 0) TI_INLINE(__tic_new_lock) ti_lock_t __tic_new_lock(void) { ti_lock_t var = PTHREAD_MUTEX_INITIALIZER; return var; } #endif #define ti_lock_decl_initializer PTHREAD_MUTEX_INITIALIZER #define ti_lock_initializer __tic_new_lock() #define ti_cond_init(cond, lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(pthread_cond_init(cond, NULL)) : 0) TI_INLINE(__tic_new_cond) ti_cond_t __tic_new_cond(void) { ti_cond_t var = PTHREAD_COND_INITIALIZER; return var; } #define ti_cond_initializer __tic_new_cond() #define ti_cond_decl_initializer PTHREAD_COND_INITIALIZER #define ti_lock(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(__tic_mutex_lock(lock)) : 0) #define ti_try_lock(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZopt(pthread_mutex_trylock(lock), EBUSY) : 0) #define ti_unlock(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(pthread_mutex_unlock(lock)) : 0) #if 1 TI_INLINE(__tic_mutex_lock) int __tic_mutex_lock(ti_lock_t *lock) { int retval; if (politep) return pthread_mutex_lock(lock); else { do { retval = pthread_mutex_trylock(lock); } while (retval == EBUSY); return retval; } } #else #define __tic_mutex_lock pthread_mutex_lock #endif #define CAUTIOUS_MONITORS 1 /* We've empricially observed that cautious monitors are necessary when: defined(IRIX) || defined(FREEBSD) || defined(HPUX) || defined(OSF) || defined(AIX) The POSIX spec essentially requires us to use cautious monitors to protect against spurious wakeups, and thanks to the signals generated by our GC's threaded stop-the-world, it turns out that we actually observe spurious wakeups quite often on many platforms - so we now force CAUTIOUS_MONITORS to be enabled everywhere. */ #ifdef CAUTIOUS_MONITORS /* some pthread implementations need special help for wait/notify - specifically, IRIX pthreads frequently return prematurely from a wait so we must explicitly check the condition upon return the extra fields in the monitor data structure are protected by the lock, which already must be held in order to call these wait/notify functions */ #define ti_mon_wait(mon) do { if (MYBOXPROCS > 1) { \ mon->numwaiting++; /* about to wait */ \ do { \ __tic_errcheckZ(pthread_cond_wait(&(mon->condvar), &(mon->lock))); \ } while (!mon->numsignaled); \ mon->numwaiting--; /* we're no longer waiting */ \ mon->numsignaled--; /* we're awaking - consume one signal */ \ } else { \ fprintf(stderr, "Tic: INTERNAL ERROR: called ti_mon_wait with MYBOXPROCS==1"); \ abort(); \ } \ } while(0) #define ti_mon_timedwait(mon, tm) do { if (MYBOXPROCS > 1) { \ int retval = 0; \ mon->numwaiting++; /* about to wait */ \ do { \ retval = __tic_errcheckZopt(pthread_cond_timedwait(&(mon->condvar), \ &(mon->lock), tm), ETIMEDOUT); \ } while (!mon->numsignaled && retval != ETIMEDOUT); \ mon->numwaiting--; /* we're no longer waiting */ \ if (retval != ETIMEDOUT) mon->numsignaled--; /* we're awaking - consume one signal */ \ } else ti_sleepuntil(tm); } while(0) #define ti_mon_signal(mon) do { if (MYBOXPROCS > 1) { \ if (mon->numwaiting > mon->numsignaled) /* some waiter still needs a signal */ \ mon->numsignaled++; /* add one signal */ \ __tic_errcheckZ(pthread_cond_signal(&(mon->condvar))); \ } } while(0) #define ti_mon_broadcast(mon) do { if (MYBOXPROCS > 1) { \ mon->numsignaled = mon->numwaiting; /* ensure a signal for each current waiter */ \ __tic_errcheckZ(pthread_cond_broadcast(&(mon->condvar))); \ } } while(0) #else #define ti_mon_wait(mon) \ do { if (MYBOXPROCS > 1) __tic_errcheckZ(pthread_cond_wait(&(mon->condvar), &(mon->lock))); } while (0) #define ti_mon_timedwait(mon, tm) do { \ if (MYBOXPROCS > 1) __tic_errcheckZopt(pthread_cond_timedwait(&(mon->condvar), \ &(mon->lock), tm),ETIMEDOUT); \ else ti_sleepuntil(tm); \ } while (0) #define ti_mon_signal(mon) \ do { if (MYBOXPROCS > 1) __tic_errcheckZ(pthread_cond_signal(&(mon->condvar))); } while (0) #define ti_mon_broadcast(mon) \ do { if (MYBOXPROCS > 1) __tic_errcheckZ(pthread_cond_broadcast(&(mon->condvar))); } while (0) #endif #define ti_lock_destroy(lock) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(pthread_mutex_destroy(lock)) : 0) #define ti_cond_destroy(cond) \ ((MYBOXPROCS > 1) ? __tic_errcheckZ(pthread_cond_destroy(cond)) : 0) #define ti_time_t struct timespec #endif /* Timer-related macros/functions */ /* ti_time_t is defined separately for each platform above */ /* set a time structure for given millis from right now */ #define ti_set_wait_timer(tm, millis) do { \ struct timeval now; \ gettimeofday(&now, NULL); \ (tm)->tv_sec = now.tv_sec; \ (tm)->tv_sec += (now.tv_usec + millis*1000)/1000000; \ (tm)->tv_nsec = ((now.tv_usec + millis*1000)%1000000) * 1000; \ } while (0) /* block until the given absolute time has approximately been reached */ #define ti_sleepuntil(tm) do { \ int millis; \ struct timeval now; \ gettimeofday(&now, NULL); \ millis = ((tm)->tv_sec - now.tv_sec) * 1000 + \ ((tm)->tv_nsec / 1000 - now.tv_usec) / 1000; \ if (millis > 0) m5sleepJmT6Thread4lang4java(millis); \ } while (0) /* return the number of milliseconds from now until the time indicated by tm * (will be negative if the time indicated by tm has already passed) */ TI_INLINE(ti_millisuntil) int ti_millisuntil(ti_time_t* tm) { int millis; struct timeval now; gettimeofday(&now, NULL); millis = ((tm)->tv_sec - now.tv_sec) * 1000 + ((tm)->tv_nsec / 1000 - now.tv_usec) / 1000; return millis; } #ifdef __MTA__ #include #define tic_sched_yield() mta_yield() #elif defined(__blrts__) #define tic_sched_yield() (sleep(0),0) /* not implemented - just ignore it */ #elif defined(HAVE_SCHED_YIELD) #include #define tic_sched_yield() __tic_errcheckZ(sched_yield()) #else extern void __os_yield(long usecs); #define tic_sched_yield() __os_yield(0) #endif #if HAVE_ALLOCA_H && ALLOCA_IN_C #include #define tic_alloca(sz) alloca(sz) #define TRUE_ALLOCA 1 #else #define tic_alloca(sz) ti_malloc(sz) #define TRUE_ALLOCA 0 #endif /* local memory barriers tic_local_wmb() - ensure all previous stores to local mem from this proc are globally completed across this SMP tic_local_rmb() - ensure no subsequent loads on local mem from this proc begin until all prior instructions are complete */ #if !defined(MEMORY_SHARED) && !defined(MEMORY_DISTRIBUTED) #define tic_local_wmb() #define tic_local_rmb() #else #define tic_local_wmb() gasnett_local_wmb() #define tic_local_rmb() gasnett_local_rmb() #endif /* source line tracing for gasnet-* backends call this from macros which are expanded into generated code (only!) to register the current Ti-level source line number with the GASNet tracing system */ #if defined(GASNET_TRACE) && !defined(TI_NO_SRCPOS) #define ti_srcpos() \ GASNETT_TRACE_SETSOURCELINE(__FILE__,__LINE__) #define ti_srcpos_decl() \ char _dummy = (GASNETT_TRACE_SETSOURCELINE(__FILE__,__LINE__),0); #else #define ti_srcpos() ((void)0) #define ti_srcpos_decl() #endif #if defined(GASNET_TRACE) #define TI_TRACE #define ti_srcpos_freeze() GASNETT_TRACE_FREEZESOURCELINE() #define ti_srcpos_unfreeze() GASNETT_TRACE_UNFREEZESOURCELINE() #define ti_trace_printf(parenthesized_args) ( \ ti_srcpos(), \ (GASNETT_TRACE_ENABLED ? \ GASNETT_TRACE_PRINTF parenthesized_args : \ ((void)0)), \ ((void)0)) #define ti_set_srcpos(file,line) GASNETT_TRACE_SETSOURCELINE(file,line) #define ti_get_srcpos(file,line) GASNETT_TRACE_GETSOURCELINE(file,line) #else #undef TI_TRACE #define ti_srcpos_freeze() 0 #define ti_srcpos_unfreeze() 0 #define ti_trace_printf(parenthesized_args) ((void)0) #define ti_set_srcpos(file,line) ((void)0) #define ti_get_srcpos(file,line) ((void)0) #endif #define ti_trace_enterregion(name) ti_trace_printf(("GASNET_TRACE_ENTERREGION: %s", name)) #define ti_trace_leaveregion(name) ti_trace_printf(("GASNET_TRACE_LEAVEREGION: %s", name)) #include #include extern tic_thread_key_t tic_thread_key; TI_INLINE(_tic_lookup_myProcess) processInfo *_tic_lookup_myProcess() __attribute__ ((const)); TI_INLINE(_tic_lookup_myProcess) processInfo *_tic_lookup_myProcess() { processInfo *pi; tic_thread_get_key_value(tic_thread_key, &pi); return (pi); } #ifdef MEMORY_SHARED /* Here we use a clever trick - myProcess() uses the sizeof(_tic_threadinfo_cache) to determine whether _tic_threadinfo_cache was bound a value posted by TIC_BEGIN_FUNCTION() or if it bound to the globally declared dummy variables. Even a very stupid C optimizer should constant-fold away the unused calls to gasneti_get_threadinfo() and discard the unused variables */ static uint8_t _tic_threadinfo_cache = sizeof(_tic_threadinfo_cache); /* silly little trick to prevent unused variable warning on gcc -Wall */ #define _TIC_BEGIN_FUNCTION \ processInfo *_tic_threadinfo_cache = NULL; /* if you get an unused variable warning on gasnete_threadinfo_cache, it means you POST'ed in a function which made no tic calls that needed it */ #define myProcess() \ ( (sizeof(_tic_threadinfo_cache) == 1) ? \ (processInfo *)_tic_lookup_myProcess() : \ ( (uintptr_t)_tic_threadinfo_cache == 0 ? \ ((*(processInfo **)&_tic_threadinfo_cache) = \ (processInfo *)_tic_lookup_myProcess()) : \ (processInfo *)(uintptr_t)_tic_threadinfo_cache) ) #else /* !MEMORY_SHARED */ #define myProcess() _tic_lookup_myProcess() #define _TIC_BEGIN_FUNCTION #endif #define myProcessNumber() (myProcess()->processNumber) #define myBoxProcessNumber() (myProcess()->boxProcessNumber) #ifdef COMM_GASNET #define TIC_BEGIN_FUNCTION \ ti_srcpos_decl() /* intentional lack of semicolon */ \ _TIC_BEGIN_FUNCTION \ GASNET_BEGIN_FUNCTION(); #else #define TIC_BEGIN_FUNCTION _TIC_BEGIN_FUNCTION #endif /* ........................ * * Synchronization counters * * ........................ */ #ifdef __MTA__ #define Counter tic_Counter #endif typedef volatile int Counter; #ifdef COMM_AM2 TI_INLINE(sync_ctr) void sync_ctr(Counter *ctr) { tic_poll_while(*ctr); } #else #define sync_ctr(a) #endif /* AMII */ #ifdef COMM_AM2 TI_INLINE(is_sync_ctr) int is_sync_ctr(Counter *ctr) { tic_poll(); return !*ctr; } #else #define is_sync_ctr(a) (1) #endif /* AMII */ /* ............... * * Global pointers * * ............... */ #include /* ............. * * Handlers * * ............. */ #include /* ............. * * Global memory * * ............. */ /* Constants specifying when to use segments * (these should go somewhere else... -TvE */ #define STORE_STRUCT_LEN 60 #define PUT_STRUCT_LEN 32 /* for distributed GC performance, it helps to know whether bulk transfers may contain pointers */ typedef enum { tic_no_ptrs, /* no embedded pointers at all */ tic_gp_only, /* the only embedded pointers are global pointers */ tic_has_ptrs /* may have global or local pointers embedded */ } tic_ptr_embedding; /* Ack-ed reads and writes */ #include /* Non-ack-ed stores */ #include #include #include /************************************************************* * * Global communication * *************************************************************/ #include extern int usingAMSPMD; /* true for workers using the AMUDP/AMMPI SPMD job startup API */ /* Enrionment variable handling */ /* getenvMaster() retrieves environment information from the console node */ #ifdef COMM_GASNET #define getenvMaster gasnet_getenv #elif defined(COMM_AMUDP) TI_INLINE(getenvMaster) const char *getenvMaster(const char *name) { if (usingAMSPMD) return AMUDP_SPMDgetenvMaster(name); else return getenv(name); } #else TI_INLINE(getenvMaster) const char *getenvMaster(const char *name) { return getenv(name); } #endif #if !defined(HAVE_SETENV) && defined(HAVE_PUTENV) TI_INLINE(setenv) int setenv(const char *name, const char *value, int overwrite) { if (overwrite || !getenv(name)) { char tmp[1024]; assert(strlen(name)+strlen(value)+1 < 1024); sprintf(tmp,"%s=%s",name,value); return putenv(tmp); } else return 0; } #endif /* .............. * * Global control * * .............. */ #include /* public stuff. Maybe should be here verbatim? */ /* ........................ * * Barrier * * ........................ */ #include /* ........................ * * Monitors * * ........................ */ #include /* ......................... * * Timer library * * ......................... */ extern double get_seconds(); /* ......................... * * Full titanium GC support * * ......................... */ #include #endif