/* * This file contains wrappers to translate calls that the GCC-based * UPC developers expect into equivalent calls into the Berkeley UPC runtime. * NOTE: calls to get/put shared data are inlined via upcr_gupc.h file. */ #include #include #if HAVE_GCC_TLS_SUPPORT && UPCRI_UPC_PTHREADS # define UPCRI_THREAD_LOCAL_VARIABLE __thread #else # define UPCRI_THREAD_LOCAL_VARIABLE #endif /* In GCC UPC, the memory access calls always assume 'relaxed'. A separate call is generated by the compiler to enforce synchronization. */ /* The number of THREADS, as specified on the command line */ int THREADS = -1; /* The current thread number (range: 0..THREADS-1) */ UPCRI_THREAD_LOCAL_VARIABLE int MYTHREAD; /* Depth count used to implement the semantics of nested upc_forall statements. */ UPCRI_THREAD_LOCAL_VARIABLE int __upc_forall_depth; /* useful constants */ #undef KILOBYTE #define KILOBYTE 1024LU #undef C64K #define C64K (64*KILOBYTE) #undef MEGABYTE #define MEGABYTE (KILOBYTE*KILOBYTE) /* helper functions */ #undef min #define min(x,y) (((x) < (y)) ? (x): (y)) #undef max #define max(x,y) (((x) > (y)) ? (x): (y)) #undef abs #define abs(x) (((x) > 0) ? (x): -(x)) #undef round_up #define round_up(x, r) (((x) + (r) - 1)/(r)*(r)) /* Maximum of THREADS supported in this implementation */ #define UPC_THREADS_MAX (((sizeof (void *)*8) == 64) ? 1024 : 256) /* Max. heap size Set here as 64 gigabytes on a 64-bit implementation and 1 gigabyte on other (eg, 32 bit) implementations. */ #define UPC_MAX_HEAP_SIZE (((sizeof (void *)*8) == 64) \ ? (64L * KILOBYTE * MEGABYTE) \ : ( 1L * KILOBYTE * MEGABYTE)) /* Per-thread space reserved for UPC memory management functions */ #define UPC_DEFAULT_PER_THREAD_HEAP_SIZE (10*MEGABYTE) /* the per-thread maximum heap size */ static size_t upc_max_heap_size = UPC_DEFAULT_PER_THREAD_HEAP_SIZE; extern void upcri_init_heaps (void *start, uintptr_t len); void gccupc_pre_spawn_init(void) { THREADS = upcr_threads(); } #ifdef UPCRI_USING_GCCUPC_INIT_SECTION #define UPC_INIT_ARRAY_START UPCRL_init_array_begin #define UPC_INIT_ARRAY_END UPCRL_init_array_end typedef void (*func_ptr_t)(void); extern func_ptr_t UPC_INIT_ARRAY_START[]; extern func_ptr_t UPC_INIT_ARRAY_END[]; #endif void gccupc_per_pthread_init(void) { UPCR_BEGIN_FUNCTION(); /* thread-specific initialization */ MYTHREAD = upcr_mythread(); #ifdef UPCRI_USING_GCCUPC_INIT_SECTION { /* Call the initialization routines indirectly via the address list created in the __upc_init section. */ size_t n_init = (UPC_INIT_ARRAY_END - UPC_INIT_ARRAY_START); int i; for (i = 0; i < n_init; ++i) { func_ptr_t init_func = UPC_INIT_ARRAY_START[i]; if (init_func) (*init_func)(); } } #endif } void gccupc_heap_init (void * start, uintptr_t len) { upcri_init_heaps(start, len); } void gccupc_static_data_init (void *start, uintptr_t len) { /* copy the static initializers for shared data from the linker-generated shared data segment to the GASNet segment */ uintptr_t static_data_sz = (UPCRL_shared_end - UPCRL_shared_begin); upcri_assert(static_data_sz <= len); #if 0 printf("copying %i from %p to %p\n",(int)static_data_sz,UPCRL_shared_begin,start); #endif #ifdef UPCRI_USING_GCCUPC_INIT_STATIC_COPY memcpy(start, UPCRL_shared_begin, static_data_sz); #endif } void gccupc_cache_init (void *start, uintptr_t len) { } /* --- lock --- */ upcr_shared_ptr_t upc_global_lock_alloc (void) { UPCR_BEGIN_FUNCTION(); return upcr_global_lock_alloc (); } void upc_lock_free (upcr_shared_ptr_t lock) { UPCR_BEGIN_FUNCTION(); upcr_lock_free (lock); } void upc_all_lock_free (upcr_shared_ptr_t lock) { UPCR_BEGIN_FUNCTION(); upcr_all_lock_free (lock); } upcr_shared_ptr_t upc_all_lock_alloc (void) { UPCR_BEGIN_FUNCTION(); return upcr_all_lock_alloc (); } void upc_lock (upcr_shared_ptr_t lock) { UPCR_BEGIN_FUNCTION(); upcr_lock (lock); } int upc_lock_attempt (upcr_shared_ptr_t lock) { UPCR_BEGIN_FUNCTION(); return upcr_lock_attempt (lock); } void upc_unlock (upcr_shared_ptr_t lock) { UPCR_BEGIN_FUNCTION(); upcr_unlock (lock); } /* --- alloc --- */ upcr_shared_ptr_t upc_global_alloc (size_t nblocks, size_t nbytes) { UPCR_BEGIN_FUNCTION(); return upcr_global_alloc (nblocks, nbytes); } upcr_shared_ptr_t upc_all_alloc (size_t nblocks, size_t nbytes) { UPCR_BEGIN_FUNCTION(); return upcr_all_alloc (nblocks, nbytes); } upcr_shared_ptr_t upc_alloc (size_t nbytes) { UPCR_BEGIN_FUNCTION(); return upcr_alloc (nbytes); } void upc_free (upcr_shared_ptr_t sptr) { UPCR_BEGIN_FUNCTION(); upcr_free (sptr); } void upc_all_free (upcr_shared_ptr_t sptr) { UPCR_BEGIN_FUNCTION(); upcr_all_free (sptr); } /* --- memory functions --- */ void upc_memcpy(upcr_shared_ptr_t dst, upcr_shared_ptr_t src, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_memcpy(dst, src, n); } void upc_memget(void *dst, upcr_shared_ptr_t src, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_memget(dst, src, n); } void upc_memput(upcr_shared_ptr_t dst, const void *src, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_memput(dst, src, n); } void upc_memset(upcr_shared_ptr_t dst, int c, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_memset(dst, c, n); } void __upc_exit (int status) { UPCR_BEGIN_FUNCTION(); upcri_do_exit(status); } /* --- upc_castable --- */ void * upc_cast(upcr_shared_ptr_t sptr) { UPCR_BEGIN_FUNCTION(); return upcr_cast (sptr); } upc_thread_info_t upc_thread_info(size_t th) { UPCR_BEGIN_FUNCTION(); return upcr_thread_info(th); } /* Support for Clang UPC and IR remote pointers */ typedef unsigned int u_intQI_t __attribute__ ((__mode__(__QI__))); typedef unsigned int u_intHI_t __attribute__ ((__mode__(__HI__))); typedef unsigned int u_intSI_t __attribute__ ((__mode__(__SI__))); typedef unsigned int u_intDI_t __attribute__ ((__mode__(__DI__))); u_intQI_t __getqi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intQI_t result; upcr_get_pshared(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intQI_t __getsqi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intQI_t result; upcr_get_pshared_strict(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intHI_t __gethi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intHI_t result; upcr_get_pshared(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intHI_t __getshi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intHI_t result; upcr_get_pshared_strict(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intSI_t __getsi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intSI_t result; upcr_get_pshared(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intSI_t __getssi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intSI_t result; upcr_get_pshared_strict(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intDI_t __getdi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intDI_t result; upcr_get_pshared(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } u_intDI_t __getsdi3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); u_intDI_t result; upcr_get_pshared_strict(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } float __getsf3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); float result; upcr_get_pshared(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } float __getssf3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); float result; upcr_get_pshared_strict(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } double __getdf3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); double result; upcr_get_pshared(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } double __getsdf3 (long thread, size_t offset) { UPCR_BEGIN_FUNCTION(); double result; upcr_get_pshared_strict(&result, upcri_addrfield_to_pshared (offset, thread), 0, sizeof(result)); return result; } void __getblk4 (long thread, size_t offset, void *dest, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_get_pshared(dest, upcri_addrfield_to_pshared (offset, thread), offset, n); } void __getsblk4 (long thread, size_t offset, void *dest, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_get_pshared_strict(dest, upcri_addrfield_to_pshared (offset, thread), offset, n); } void __putqi3 (long thread, size_t offset, u_intQI_t v) { UPCR_BEGIN_FUNCTION(); const u_intQI_t src = v; upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putsqi3 (long thread, size_t offset, u_intQI_t v) { UPCR_BEGIN_FUNCTION(); const u_intQI_t src = v; upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __puthi3 (long thread, size_t offset, u_intHI_t v) { UPCR_BEGIN_FUNCTION(); const u_intHI_t src = v; upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putshi3 (long thread, size_t offset, u_intHI_t v) { UPCR_BEGIN_FUNCTION(); const u_intHI_t src = v; upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putsi3 (long thread, size_t offset, u_intSI_t v) { UPCR_BEGIN_FUNCTION(); const u_intSI_t src = v; upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putssi3 (long thread, size_t offset, u_intSI_t v) { UPCR_BEGIN_FUNCTION(); const u_intSI_t src = v; upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putdi3 (long thread, size_t offset, u_intDI_t v) { UPCR_BEGIN_FUNCTION(); const u_intDI_t src = v; upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putsdi3 (long thread, size_t offset, u_intDI_t v) { UPCR_BEGIN_FUNCTION(); const u_intDI_t src = v; upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putsf3 (long thread, size_t offset, float v) { UPCR_BEGIN_FUNCTION(); const float src = v; upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putssf3 (long thread, size_t offset, float v) { UPCR_BEGIN_FUNCTION(); const float src = v; upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putdf3 (long thread, size_t offset, double v) { UPCR_BEGIN_FUNCTION(); const double src = v; upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putsdf3 (long thread, size_t offset, double v) { UPCR_BEGIN_FUNCTION(); const double src = v; upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, (void *) &src, sizeof(src)); } void __putblk4 (void *src, long thread, size_t offset, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_put_shared (upcri_addrfield_to_pshared (offset, thread), 0, src, sizeof(src)); } void __putsblk4 (void *src, long thread, size_t offset, size_t n) { UPCR_BEGIN_FUNCTION(); upcr_put_shared_strict (upcri_addrfield_to_pshared (offset, thread), 0, src, sizeof(src)); } void __copyblk5 (long dthread, size_t doffset, long sthread, size_t soffset, size_t n) { upcr_memcpy(upcri_addrfield_to_pshared(doffset, dthread), upcri_addrfield_to_pshared(soffset, sthread), n); }