00001
00002
00003
00004
00005
00006
00007
00008
00009 #define CMK_ISOMALLOC_EXCLUDE_FORTRAN_CALLS 0
00010
00011 #if ! CMK_MEMORY_BUILD_OS
00012
00013 #include "memory-gnu.C"
00014 #endif
00015
00016 #include "memory-isomalloc.h"
00017
00018
00019 CpvStaticDeclare(CmiIsomallocBlockList *,isomalloc_blocklist);
00020 CpvStaticDeclare(CmiIsomallocBlockList *,pushed_blocklist);
00021
00022 #define ISOMALLOC_PUSH \
00023 CmiIsomallocBlockList *pushed_blocklist=CpvAccess(isomalloc_blocklist);\
00024 CpvAccess(isomalloc_blocklist)=NULL;\
00025
00026 #define ISOMALLOC_POP \
00027 CpvAccess(isomalloc_blocklist)=pushed_blocklist;\
00028
00029
00030
00031
00032 void CmiDisableIsomalloc()
00033 {
00034 CpvAccess(pushed_blocklist)=CpvAccess(isomalloc_blocklist);
00035 CpvAccess(isomalloc_blocklist)=NULL;
00036 }
00037
00038 void CmiEnableIsomalloc()
00039 {
00040 CpvAccess(isomalloc_blocklist)=CpvAccess(pushed_blocklist);
00041 }
00042
00043 #if CMK_HAS_TLS_VARIABLES
00044
00051 static CMK_THREADLOCAL int isomalloc_thread = 0;
00052 #else
00053 #if BIGSIM_OUT_OF_CORE && BIGSIM_OOC_PREFETCH
00054 #error TLS support is required for bigsim out-of-core prefetch optimization
00055 #endif
00056 #endif
00057
00058 static int meta_inited = 0;
00059 extern int _sync_iso;
00060 extern int _sync_iso_warned;
00061
00062 static void meta_init(char **argv)
00063 {
00064 if (CmiMyRank()==0) CmiMemoryIs_flag|=CMI_MEMORY_IS_ISOMALLOC;
00065 CpvInitialize(CmiIsomallocBlockList *,isomalloc_blocklist);
00066 CpvInitialize(CmiIsomallocBlockList *,pushed_blocklist);
00067 CpvAccess(isomalloc_blocklist) = NULL;
00068 CpvAccess(pushed_blocklist) = NULL;
00069 #if CMK_HAS_TLS_VARIABLES
00070 isomalloc_thread = 1;
00071 #endif
00072 if (CmiMyRank()==0) meta_inited = 1;
00073 #if CMK_SMP
00074 if (CmiMyPe()==0 && _sync_iso == 0 && _sync_iso_warned == 0) {
00075 _sync_iso_warned = 1;
00076 printf("Warning> Using Isomalloc in SMP mode, you may need to run with '+isomalloc_sync'.\n");
00077 }
00078 #endif
00079 }
00080
00081 static void *meta_malloc(size_t size)
00082 {
00083 void *ret=NULL;
00084 #if CMK_HAS_TLS_VARIABLES
00085 int _isomalloc_thread = isomalloc_thread;
00086 if (CmiThreadIs(CMI_THREAD_IS_TLS)) _isomalloc_thread = 1;
00087 #endif
00088 if (meta_inited && CpvInitialized(isomalloc_blocklist) && CpvAccess(isomalloc_blocklist)
00089 #if CMK_HAS_TLS_VARIABLES
00090 && _isomalloc_thread
00091 #endif
00092 )
00093 {
00094 ISOMALLOC_PUSH
00095 #if CMK_ISOMALLOC_EXCLUDE_FORTRAN_CALLS
00096 if (CmiIsFortranLibraryCall()==1) {
00097 ret=mm_malloc(size);
00098 }
00099 else
00100 #endif
00101 ret=CmiIsomallocBlockListMalloc(pushed_blocklist,size);
00102 ISOMALLOC_POP
00103 }
00104 else
00105 ret=mm_malloc(size);
00106 return ret;
00107 }
00108
00109 static void meta_free(void *mem)
00110 {
00111 if (mem != NULL && CmiIsomallocInRange(mem))
00112 {
00113 ISOMALLOC_PUSH
00114 CmiIsomallocBlockListFree(mem);
00115 ISOMALLOC_POP
00116 }
00117 else
00118 mm_free(mem);
00119 }
00120
00121 static void *meta_calloc(size_t nelem, size_t size)
00122 {
00123 void *ret=meta_malloc(nelem*size);
00124 if (ret != NULL) memset(ret,0,nelem*size);
00125 return ret;
00126 }
00127
00128 static void meta_cfree(void *mem)
00129 {
00130 meta_free(mem);
00131 }
00132
00133 static void *meta_realloc(void *oldBuffer, size_t newSize)
00134 {
00135 void *newBuffer;
00136
00137 if (!CmiIsomallocInRange(oldBuffer))
00138 return mm_realloc(oldBuffer,newSize);
00139
00140 newBuffer = meta_malloc(newSize);
00141 if ( newBuffer && oldBuffer ) {
00142
00143
00144 size_t size=CmiIsomallocLength(((CmiIsomallocBlockList *)oldBuffer)-1)-
00145 sizeof(CmiIsomallocBlockList);
00146 if (size>newSize) size=newSize;
00147 if (size > 0)
00148 memcpy(newBuffer, oldBuffer, size);
00149 }
00150 if (oldBuffer)
00151 meta_free(oldBuffer);
00152 return newBuffer;
00153 }
00154
00155 static void *meta_memalign(size_t align, size_t size)
00156 {
00157 void *ret=NULL;
00158 if (CpvInitialized(isomalloc_blocklist) && CpvAccess(isomalloc_blocklist))
00159 {
00160 ISOMALLOC_PUSH
00161 #if CMK_ISOMALLOC_EXCLUDE_FORTRAN_CALLS
00162 if (CmiIsFortranLibraryCall()==1) {
00163 ret=mm_memalign(align, size);
00164 }
00165 else
00166 #endif
00167 ret=CmiIsomallocBlockListMallocAlign(pushed_blocklist,align,size);
00168 ISOMALLOC_POP
00169 }
00170 else
00171 ret=mm_memalign(align, size);
00172 return ret;
00173 }
00174
00175 static int meta_posix_memalign(void **outptr, size_t align, size_t size)
00176 {
00177 int ret = 0;
00178 if (CpvInitialized(isomalloc_blocklist) && CpvAccess(isomalloc_blocklist))
00179 {
00180 ISOMALLOC_PUSH
00181 #if CMK_ISOMALLOC_EXCLUDE_FORTRAN_CALLS
00182 if (CmiIsFortranLibraryCall()==1) {
00183 ret=mm_posix_memalign(outptr, align, size);
00184 }
00185 else
00186 #endif
00187 *outptr = CmiIsomallocBlockListMallocAlign(pushed_blocklist,align,size);
00188 ISOMALLOC_POP
00189 }
00190 else
00191 ret=mm_posix_memalign(outptr, align, size);
00192 return ret;
00193 }
00194
00195 static void *meta_aligned_alloc(size_t align, size_t size)
00196 {
00197 void *ret=NULL;
00198 if (CpvInitialized(isomalloc_blocklist) && CpvAccess(isomalloc_blocklist))
00199 {
00200 ISOMALLOC_PUSH
00201 #if CMK_ISOMALLOC_EXCLUDE_FORTRAN_CALLS
00202 if (CmiIsFortranLibraryCall()==1) {
00203 ret=mm_aligned_alloc(align, size);
00204 }
00205 else
00206 #endif
00207 ret=CmiIsomallocBlockListMallocAlign(pushed_blocklist,align,size);
00208 ISOMALLOC_POP
00209 }
00210 else
00211 ret=mm_aligned_alloc(align, size);
00212 return ret;
00213 }
00214
00215 static void *meta_valloc(size_t size)
00216 {
00217 return meta_memalign(CmiGetPageSize(), size);
00218 }
00219
00220 static void *meta_pvalloc(size_t size)
00221 {
00222 const size_t pagesize = CmiGetPageSize();
00223 return meta_memalign(pagesize, (size + pagesize - 1) & ~(pagesize - 1));
00224 }
00225
00226 #define CMK_MEMORY_HAS_NOMIGRATE
00227
00228 void *malloc_nomigrate(size_t size) {
00229 void *result;
00230 CmiMemLock();
00231 result = mm_malloc(size);
00232 CmiMemUnlock();
00233 return result;
00234 }
00235
00236 void free_nomigrate(void *mem)
00237 {
00238 CmiMemLock();
00239 mm_free(mem);
00240 CmiMemUnlock();
00241 }
00242
00243 #define CMK_MEMORY_HAS_ISOMALLOC
00244
00245
00246
00247 CmiIsomallocBlockList *CmiIsomallocBlockListActivate(CmiIsomallocBlockList *l)
00248 {
00249 CmiIsomallocBlockList **s=&CpvAccess(isomalloc_blocklist);
00250 CmiIsomallocBlockList *ret=*s;
00251 *s=l;
00252 return ret;
00253 }
00254
00255 CmiIsomallocBlockList *CmiIsomallocBlockListCurrent(void){
00256 return CpvAccess(isomalloc_blocklist);
00257 }
00258
00259
00260
00261