void removeBackRef(BackRefIdx backRefIdx) { MALLOC_ASSERT(!backRefIdx.isInvalid(), ASSERT_TEXT); MALLOC_ASSERT(backRefIdx.getMaster()<=backRefMaster->lastUsed && backRefIdx.getOffset()<BR_MAX_CNT, ASSERT_TEXT); BackRefBlock *currBlock = backRefMaster->backRefBl[backRefIdx.getMaster()]; FreeObject *freeObj = (FreeObject*)((uintptr_t)currBlock + sizeof(BackRefBlock) + backRefIdx.getOffset()*sizeof(void*)); MALLOC_ASSERT(((uintptr_t)freeObj>(uintptr_t)currBlock && (uintptr_t)freeObj<(uintptr_t)currBlock + slabSize), ASSERT_TEXT); { MallocMutex::scoped_lock lock(currBlock->blockMutex); freeObj->next = currBlock->freeList; MALLOC_ASSERT(!freeObj->next || ((uintptr_t)freeObj->next > (uintptr_t)currBlock && (uintptr_t)freeObj->next < (uintptr_t)currBlock + slabSize), ASSERT_TEXT); currBlock->freeList = freeObj; currBlock->allocatedCount--; } // TODO: do we need double-check here? if (!currBlock->addedToForUse && currBlock!=backRefMaster->active) { MallocMutex::scoped_lock lock(masterMutex); if (!currBlock->addedToForUse && currBlock!=backRefMaster->active) backRefMaster->addToForUseList(currBlock); } }
BackRefIdx BackRefIdx::newBackRef(bool largeObj) { BackRefBlock *blockToUse; void **toUse; BackRefIdx res; bool lastBlockFirstUsed = false; do { MALLOC_ASSERT(backRefMaster, ASSERT_TEXT); blockToUse = backRefMaster->findFreeBlock(); if (!blockToUse) return BackRefIdx(); toUse = NULL; { // the block is locked to find a reference MallocMutex::scoped_lock lock(blockToUse->blockMutex); if (blockToUse->freeList) { toUse = (void**)blockToUse->freeList; blockToUse->freeList = blockToUse->freeList->next; MALLOC_ASSERT(!blockToUse->freeList || ((uintptr_t)blockToUse->freeList>=(uintptr_t)blockToUse && (uintptr_t)blockToUse->freeList < (uintptr_t)blockToUse + slabSize), ASSERT_TEXT); } else if (blockToUse->allocatedCount < BR_MAX_CNT) { toUse = (void**)blockToUse->bumpPtr; blockToUse->bumpPtr = (FreeObject*)((uintptr_t)blockToUse->bumpPtr - sizeof(void*)); if (blockToUse->allocatedCount == BR_MAX_CNT-1) { MALLOC_ASSERT((uintptr_t)blockToUse->bumpPtr < (uintptr_t)blockToUse+sizeof(BackRefBlock), ASSERT_TEXT); blockToUse->bumpPtr = NULL; } } if (toUse) { if (!blockToUse->allocatedCount && !backRefMaster->listForUse) lastBlockFirstUsed = true; blockToUse->allocatedCount++; } } // end of lock scope } while (!toUse); // The first thread that uses the last block requests new space in advance; // possible failures are ignored. if (lastBlockFirstUsed) backRefMaster->requestNewSpace(); res.master = blockToUse->myNum; uintptr_t offset = ((uintptr_t)toUse - ((uintptr_t)blockToUse + sizeof(BackRefBlock)))/sizeof(void*); // Is offset too big? MALLOC_ASSERT(!(offset >> 15), ASSERT_TEXT); res.offset = offset; if (largeObj) res.largeObj = largeObj; return res; }
int flush_dir_compress(FiletransferOptions const *opts, int which, const char *compress_dir, const char *send_dir){ //check for files in compress_dir. Assumption: a file which lies here, should have been compressed, but that action was interrupted. //As it can arrive here only by a rename, it is most likely to be a complete file struct dirent *dp; DIR *dir; dir = opendir(compress_dir); if(dir != NULL) { while((dp = readdir(dir)) != NULL) { if(dp->d_type != DT_REG) continue; DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, old file found in compress-directory.")); //compress file into to_send dir int len = strlen(compress_dir)+strlen(dp->d_name)+2; char *cd_filename = malloc(len); MALLOC_ASSERT(cd_filename); snprintf(cd_filename,len,"%s/%s",compress_dir,dp->d_name); len = strlen(send_dir)+strlen(dp->d_name)+strlen(COMPRESS_EXTENSION)+2; char *dst_tosend = malloc(len);//the resulting filename in .tosend +2 for 1*"/", +1 for \0 + .gz MALLOC_ASSERT(dst_tosend); snprintf(dst_tosend,len,"%s/%s%s",send_dir,dp->d_name,COMPRESS_EXTENSION); if (compress_file_to(cd_filename,dst_tosend, opts->CompressionLevel[which]) != 0){ free(dst_tosend); free(cd_filename); closedir(dir); return -1; } //send file send_dumped_file(opts,dst_tosend); free(dst_tosend); free(cd_filename); } } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not open directory"), DLT_STRING(compress_dir)); return -1; } closedir(dir);//end: compress_dir return 0; }
LargeMemoryBlock *LargeObjectCache::get(size_t size) { MALLOC_ASSERT( size%largeBlockCacheStep==0, ASSERT_TEXT ); MALLOC_ASSERT( size>=minLargeSize, ASSERT_TEXT ); if ( size < maxHugeSize) { uintptr_t currTime = getCurrTime(); cleanupCacheIfNeeded(currTime); return size < maxLargeSize? largeCache.get(currTime, size) : hugeCache.get(currTime, size); } return NULL; }
bool LargeObjectCacheImpl<Props>::CacheBin:: cleanToThreshold(Backend *backend, BinBitMask *bitMask, uintptr_t currTime, int idx) { LargeMemoryBlock *toRelease = NULL; bool released = false; #if MALLOC_DEBUG uintptr_t nextAge = 0; #endif /* oldest may be more recent then age, that's why cast to signed type was used. age overflow is also processed correctly. */ if (last && (intptr_t)(currTime - oldest) > ageThreshold) { MallocMutex::scoped_lock scoped_cs(lock); // double check if (last && (intptr_t)(currTime - last->age) > ageThreshold) { do { #if MALLOC_DEBUG // check that list ordered MALLOC_ASSERT(!nextAge || lessThanWithOverflow(nextAge, last->age), ASSERT_TEXT); nextAge = last->age; #endif cachedSize -= last->unalignedSize; last = last->prev; } while (last && (intptr_t)(currTime - last->age) > ageThreshold); if (last) { toRelease = last->next; oldest = last->age; last->next = NULL; } else { toRelease = first; first = NULL; oldest = 0; if (!usedSize) bitMask->set(idx, false); } MALLOC_ASSERT( toRelease, ASSERT_TEXT ); lastCleanedAge = toRelease->age; } else return false; } released = toRelease; while ( toRelease ) { LargeMemoryBlock *helper = toRelease->next; backend->returnLargeObject(toRelease); toRelease = helper; } return released; }
BackRefIdx BackRefIdx::newBackRef(bool largeObj) { BackRefBlock *blockToUse; void **toUse; BackRefIdx res; do { { // global lock taken to find a block MallocMutex::scoped_lock lock(backRefMutex); MALLOC_ASSERT(backRefMaster, ASSERT_TEXT); if (! (blockToUse = backRefMaster->findFreeBlock())) return BackRefIdx(); } toUse = NULL; { // the block is locked to find a reference MallocMutex::scoped_lock lock(blockToUse->blockMutex); if (blockToUse->freeList) { toUse = (void**)blockToUse->freeList; blockToUse->freeList = blockToUse->freeList->next; MALLOC_ASSERT(!blockToUse->freeList || ((uintptr_t)blockToUse->freeList>=(uintptr_t)blockToUse && (uintptr_t)blockToUse->freeList < (uintptr_t)blockToUse + blockSize), ASSERT_TEXT); } else if (blockToUse->allocatedCount < BR_MAX_CNT) { toUse = (void**)blockToUse->bumpPtr; blockToUse->bumpPtr = (FreeObject*)((uintptr_t)blockToUse->bumpPtr - sizeof(void*)); if (blockToUse->allocatedCount == BR_MAX_CNT-1) { MALLOC_ASSERT((uintptr_t)blockToUse->bumpPtr < (uintptr_t)blockToUse+sizeof(BackRefBlock), ASSERT_TEXT); blockToUse->bumpPtr = NULL; } } if (toUse) blockToUse->allocatedCount++; } // end of lock scope } while (!toUse); res.master = blockToUse->myNum; uintptr_t offset = ((uintptr_t)toUse - ((uintptr_t)blockToUse + sizeof(BackRefBlock)))/sizeof(void*); // Is offset too big? MALLOC_ASSERT(!(offset >> 15), ASSERT_TEXT); res.offset = offset; if (largeObj) res.largeObj = largeObj; return res; }
bool LargeObjectCacheImpl<Props>:: CacheBin::cleanAll(Backend *backend, BinBitMask *bitMask, int idx) { LargeMemoryBlock *toRelease = NULL; bool released = false; if (last) { MallocMutex::scoped_lock scoped_cs(lock); // double check if (last) { toRelease = first; last = NULL; first = NULL; oldest = 0; cachedSize = 0; if (!usedSize) bitMask->set(idx, false); } else return false; } released = toRelease; while ( toRelease ) { LargeMemoryBlock *helper = toRelease->next; MALLOC_ASSERT(!helper || lessThanWithOverflow(helper->age, toRelease->age), ASSERT_TEXT); backend->returnLargeObject(toRelease); toRelease = helper; } return released; }
BackRefBlock *BackRefMaster::findFreeBlock() { if (active->allocatedCount < BR_MAX_CNT) return active; if (listForUse) { // use released list active = listForUse; listForUse = listForUse->nextForUse; MALLOC_ASSERT(active->addedToForUse, ASSERT_TEXT); active->addedToForUse = false; } else if (lastUsed-1 < backRefMaster->dataSz) { // allocate new data node // This block is never released, so can prevent releasing of a region // if it's received from the backend, so prefer getRawMemory using. BackRefBlock *newBl = (BackRefBlock*) getRawMemory(BackRefBlock::bytes, /*useMapMem=*/!isMallocInitializedExt()); if (!newBl) newBl = (BackRefBlock*)backend->get16KBlock(1, /*startup=*/!isMallocInitializedExt()); if (!newBl) return NULL; lastUsed++; backRefMaster->addEmptyBackRefBlock(newBl); active = newBl; } else // no free blocks, give up return NULL; return active; }
// return artifical bin index, it's used only during sorting and never saved int LargeObjectCache::sizeToIdx(size_t size) { MALLOC_ASSERT(size < maxHugeSize, ASSERT_TEXT); return size < maxLargeSize? LargeCacheType::sizeToIdx(size) : LargeCacheType::getNumBins()+HugeCacheType::sizeToIdx(size); }
bool LargeObjectCache::CacheBin::put(ExtMemoryPool *extMemPool, LargeMemoryBlock *ptr) { bool blockCached = true; ptr->prev = NULL; ptr->age = extMemPool->loc.cleanupCacheIfNeed(extMemPool); { MallocMutex::scoped_lock scoped_cs(lock); if (lastCleanedAge) { ptr->next = first; first = ptr; if (ptr->next) ptr->next->prev = ptr; if (!last) { MALLOC_ASSERT(0 == oldest, ASSERT_TEXT); oldest = ptr->age; last = ptr; } } else { // 1st object of such size was released. // Not cache it, and remeber when this occurs // to take into account during cache miss. lastCleanedAge = ptr->age; blockCached = false; } } return blockCached; }
char *unique_name(char *src) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, creating unique temporary file name.")); time_t t = time(NULL); int ok; unsigned long l = getFileSerialNumber(src, &ok) ^ t; if (!ok){ return (char*) NULL; } char *basename_f = basename(src); // Length of ULONG_MAX + 1 int len = 11+strlen(basename_f); if (len > NAME_MAX){ DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("dlt-system-filetransfer, unique name creation needs to shorten the filename:"),DLT_STRING(basename_f)); len = NAME_MAX; } char *ret = malloc(len); MALLOC_ASSERT(ret); snprintf(ret, len, "%010lu%s", l,basename_f); return ret; }
/******************************************************* Function: create_unique_file *******************************************************/ string create_unique_file (const string path, char suffix) { string p; string base = basename (path); string new_path; int fd; /* length of tmpdir + basename of path and '/' between the dir and the basename + null terminator */ p = (string) MALLOC (strlen(tmpdir) + strlen(base) + 2); MALLOC_ASSERT (p); strcpy (p, tmpdir); strcat (p, "/"); strcat (p, base); new_path = make_temp_file (p, suffix); FREE (p); if ((fd = creat (new_path, 0666 & ~cmask)) == -1) { perror(new_path); exit(1); } CLOSE (fd); return new_path; } /* create_unique_file */
/* * Maintain list of temp. files created so they are all removed on error or * when done. Assume the first entry is "tmpdir". */ void add_to_tmp_file_list (string path) { if (tmp_list_max == 0) { tmp_list_max = DEFAULT_TMP_LIST_SIZE; tmp_list = (string *) MALLOC (tmp_list_max * sizeof(string)); MALLOC_ASSERT (tmp_list); } else if (tmp_list_size >= tmp_list_max) { tmp_list_max *= 2; tmp_list = (string *)REALLOC (tmp_list, tmp_list_max * sizeof(string)); MALLOC_ASSERT (tmp_list); } tmp_list[tmp_list_size++] = path; } /* add_to_tmp_file_list */
void init_tbbmalloc() { #if MALLOC_LD_PRELOAD if (malloc_proxy && __TBB_internal_find_original_malloc) { const char *alloc_names[] = { "malloc", "free", "realloc", "calloc"}; void *orig_alloc_ptrs[4]; if (__TBB_internal_find_original_malloc(4, alloc_names, orig_alloc_ptrs)) { (void *&)original_malloc_ptr = orig_alloc_ptrs[0]; (void *&)original_free_ptr = orig_alloc_ptrs[1]; (void *&)original_realloc_ptr = orig_alloc_ptrs[2]; (void *&)original_calloc_ptr = orig_alloc_ptrs[3]; MALLOC_ASSERT( original_malloc_ptr!=malloc_proxy, "standard malloc not found" ); /* It's workaround for a bug in GNU Libc 2.9 (as it shipped with Fedora 10). 1st call to libc's malloc should be not from threaded code. */ original_free_ptr(original_malloc_ptr(1024)); original_malloc_found = 1; } } #endif /* MALLOC_LD_PRELOAD */ #if DO_ITT_NOTIFY MallocInitializeITT(); #endif }
void setBackRef(BackRefIdx backRefIdx, void *newPtr) { MALLOC_ASSERT(backRefIdx.getMaster()<=backRefMaster->lastUsed && backRefIdx.getOffset()<BR_MAX_CNT, ASSERT_TEXT); *(void**)((uintptr_t)backRefMaster->backRefBl[backRefIdx.getMaster()] + sizeof(BackRefBlock) + backRefIdx.getOffset()*sizeof(void*)) = newPtr; }
/******************************************************* Function: ipa_opt *******************************************************/ static int ipa_opt (char **argv ) { if (ipa_argc == 0) { ipa_argv = (string *) MALLOC (orig_iargc_size * sizeof (string)); MALLOC_ASSERT (ipa_argv); } else if (ipa_argc >= orig_iargc_size) { orig_iargc_size *=2; ipa_argv = (string *) REALLOC (ipa_argv, (orig_iargc_size * sizeof(string))); MALLOC_ASSERT (ipa_argv); } ipa_argv[ipa_argc++] = ipa_copy_of(argv[0]); return 1; } /* ipa_opt */
/** * @param opts FiletransferOptions * @param which which directory is affected -> position in list of opts->Directory * @return Returns 0 if everything was okay. If there was a failure a value < 0 will be returned. */ int flush_dir(FiletransferOptions const *opts, int which) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, flush directory of old files.")); char *compress_dir; char *send_dir; int len = strlen(opts->Directory[which])+strlen(SUBDIR_COMPRESS)+2; compress_dir = malloc (len); MALLOC_ASSERT(compress_dir); snprintf(compress_dir,len,"%s/%s",opts->Directory[which],SUBDIR_COMPRESS); len = strlen(opts->Directory[which])+strlen(SUBDIR_TOSEND)+2; send_dir = malloc (len); MALLOC_ASSERT(send_dir); snprintf(send_dir,len,"%s/%s",opts->Directory[which],SUBDIR_TOSEND); //1st: scan the tosend directory. if ( 0 != flush_dir_send(opts, compress_dir, send_dir) ){ free(send_dir); free(compress_dir); return -1; } //1nd: scan the tocompress directory. if (0 != flush_dir_compress(opts, which, compress_dir, send_dir)){ free(send_dir); free(compress_dir); return -1; } free(send_dir);//no more used free(compress_dir); //last step: scan the original directory - we can reuse the send_one function if ( 0 != flush_dir_original(opts,which)){ return -1; } return 0; }
/** * compress file, delete the source file * modification: compress into subdirectory * File whis is compress will be deleted afterwards * @param src File to be sent * @param dst destination where to compress the file * @param level of compression **/ int compress_file_to(char *src, char *dst, int level) { DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, compressing file from:"),DLT_STRING(src),DLT_STRING("to:"),DLT_STRING(dst)); char *buf; char dst_mode[8]; snprintf(dst_mode,8, "wb%d", level); gzFile dst_file; FILE *src_file; dst_file = gzopen(dst, dst_mode); if(dst_file == Z_NULL) { return -1; } src_file = fopen(src, "r"); if(src_file == NULL) { gzclose(dst_file); return -1; } buf = malloc(Z_CHUNK_SZ); MALLOC_ASSERT(buf); while(!feof(src_file)) { int read = fread(buf, 1, Z_CHUNK_SZ, src_file); if(ferror(src_file)) { free(buf); gzclose(dst_file); fclose(src_file); return -1; } gzwrite(dst_file, buf, read); } if(remove(src) < 0) DLT_LOG(dltsystem, DLT_LOG_WARN, DLT_STRING("Could not remove file"), DLT_STRING(src)); free(buf); fclose(src_file); gzclose(dst_file); return 0; }
/******************************************************* Function: ipa_copy_of Allocate for and copy given string into a copy. *******************************************************/ char * ipa_copy_of (char *str) { register int len; register char *p; len = strlen(str) + 1; p = (char *) MALLOC (len); MALLOC_ASSERT (p); BCOPY (str, p, len); return p; } /* ipa_copy_of */
/******************************************************* Function: ipa_copy_of Allocate for and copy given string into a copy. *******************************************************/ char * ipa_copy_of (const char *str) { register int len; register char *p; len = strlen(str) + 1; p = (char *) MALLOC (len); MALLOC_ASSERT (p); memcpy(p, str, len); return p; } /* ipa_copy_of */
void init_tbbmalloc() { #if MALLOC_UNIXLIKE_OVERLOAD_ENABLED if (malloc_proxy && __TBB_internal_find_original_malloc) { const char *alloc_names[] = { "malloc", "free", "realloc", "calloc"}; void *orig_alloc_ptrs[4]; if (__TBB_internal_find_original_malloc(4, alloc_names, orig_alloc_ptrs)) { (void *&)original_malloc_ptr = orig_alloc_ptrs[0]; (void *&)original_free_ptr = orig_alloc_ptrs[1]; (void *&)original_realloc_ptr = orig_alloc_ptrs[2]; (void *&)original_calloc_ptr = orig_alloc_ptrs[3]; MALLOC_ASSERT( original_malloc_ptr!=malloc_proxy, "standard malloc not found" ); /* It's workaround for a bug in GNU Libc 2.9 (as it shipped with Fedora 10). 1st call to libc's malloc should be not from threaded code. */ original_free_ptr(original_malloc_ptr(1024)); original_malloc_found = 1; } } #endif /* MALLOC_UNIXLIKE_OVERLOAD_ENABLED */ #if DO_ITT_NOTIFY MallocInitializeITT(); #endif /* Preventing TBB allocator library from unloading to prevent resource leak, as memory is not released on the library unload. */ #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT // Prevent Windows from displaying message boxes if it fails to load library UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); HMODULE lib; BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |GET_MODULE_HANDLE_EX_FLAG_PIN, (LPCTSTR)&scalable_malloc, &lib); MALLOC_ASSERT(lib && ret, "Allocator can't find itself."); SetErrorMode (prev_mode); #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */ }
/******************************************************* Function: concat_names Create a new string by concating 2 other strings. *******************************************************/ string concat_names(const_string name1, const_string name2) { char *mangled_name = NULL; int len = strlen(name1)+strlen(name2)+1; mangled_name = (char *)MALLOC(len); MALLOC_ASSERT(mangled_name); strcpy(mangled_name, name1); strcat(mangled_name, name2); return(mangled_name); }
LargeMemoryBlock *LargeObjectCache::get(ExtMemoryPool *extMemPool, size_t size) { MALLOC_ASSERT( size%largeBlockCacheStep==0, ASSERT_TEXT ); LargeMemoryBlock *lmb = NULL; size_t idx = sizeToIdx(size); if (idx<numLargeBlockBins) { lmb = bin[idx].get(extMemPool, size); if (lmb) { MALLOC_ITT_SYNC_ACQUIRED(bin+idx); STAT_increment(getThreadId(), ThreadCommonCounters, allocCachedLargeBlk); } } return lmb; }
LargeMemoryBlock *LargeObjectCacheImpl<Props>::get(uintptr_t currTime, size_t size) { MALLOC_ASSERT( size%Props::CacheStep==0, ASSERT_TEXT ); int idx = sizeToIdx(size); bool setNonEmpty = false; LargeMemoryBlock *lmb = bin[idx].get(size, currTime, &setNonEmpty); // Setting to true is possible out of lock. As bitmask is used only for cleanup, // the lack of consistency is not violating correctness here. if (setNonEmpty) bitMask.set(idx, true); if (lmb) { MALLOC_ITT_SYNC_ACQUIRED(bin+idx); STAT_increment(getThreadId(), ThreadCommonCounters, allocCachedLargeObj); } return lmb; }
void init_tbbmalloc() { #if DO_ITT_NOTIFY MallocInitializeITT(); #endif /* Preventing TBB allocator library from unloading to prevent resource leak, as memory is not released on the library unload. */ #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT // Prevent Windows from displaying message boxes if it fails to load library UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); HMODULE lib; BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |GET_MODULE_HANDLE_EX_FLAG_PIN, (LPCTSTR)&scalable_malloc, &lib); MALLOC_ASSERT(lib && ret, "Allocator can't find itself."); SetErrorMode (prev_mode); #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */ }
BackRefBlock *BackRefMaster::findFreeBlock() { if (active->allocatedCount < BR_MAX_CNT) return active; if (listForUse) { // use released list MallocMutex::scoped_lock lock(masterMutex); if (active->allocatedCount == BR_MAX_CNT && listForUse) { active = listForUse; listForUse = listForUse->nextForUse; MALLOC_ASSERT(active->addedToForUse, ASSERT_TEXT); active->addedToForUse = false; } } else if (lastUsed-1 < backRefMaster->dataSz) { // allocate new data node if (!requestNewSpace()) return NULL; } else // no free space in BackRefMaster, give up return NULL; return active; }
bool LargeObjectCache::CacheBin::cleanToThreshold(ExtMemoryPool *extMemPool, uintptr_t currAge) { LargeMemoryBlock *toRelease = NULL; bool released = false; /* oldest may be more recent then age, that's why cast to signed type was used. age overflow is also processed correctly. */ if (last && (intptr_t)(currAge - oldest) > ageThreshold) { MallocMutex::scoped_lock scoped_cs(lock); // double check if (last && (intptr_t)(currAge - last->age) > ageThreshold) { do { last = last->prev; } while (last && (intptr_t)(currAge - last->age) > ageThreshold); if (last) { toRelease = last->next; oldest = last->age; last->next = NULL; } else { toRelease = first; first = NULL; oldest = 0; } MALLOC_ASSERT( toRelease, ASSERT_TEXT ); lastCleanedAge = toRelease->age; } else return false; } released = toRelease; while ( toRelease ) { LargeMemoryBlock *helper = toRelease->next; removeBackRef(toRelease->backRefIdx); extMemPool->backend.putLargeBlock(toRelease); toRelease = helper; } return released; }
int flush_dir_original(FiletransferOptions const *opts, int which){ struct dirent *dp; DIR *dir; const char *sdir = opts->Directory[which]; dir = opendir(sdir); if(dir != NULL) { while((dp = readdir(dir)) != NULL) { if(dp->d_type != DT_REG){ //we don't send directories continue; } DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, old file found in directory.")); int len = strlen(sdir)+strlen(dp->d_name)+2; char *fn = malloc(len); MALLOC_ASSERT(fn); snprintf(fn,len, "%s/%s", sdir, dp->d_name); if(send_one(fn, opts, which) < 0) { closedir(dir); free(fn); return -1; } free(fn); } } else { DLT_LOG(dltsystem, DLT_LOG_ERROR, DLT_STRING("Could not open directory"), DLT_STRING(sdir)); return -1; } closedir(dir); return 0; }
void init_tbbmalloc() { #if MALLOC_LD_PRELOAD if (malloc_proxy && __TBB_internal_find_original_malloc) { const char *alloc_names[] = { "malloc", "free", "realloc", "calloc"}; void *orig_alloc_ptrs[4]; if (__TBB_internal_find_original_malloc(4, alloc_names, orig_alloc_ptrs)) { (void *&)original_malloc_ptr = orig_alloc_ptrs[0]; (void *&)original_free_ptr = orig_alloc_ptrs[1]; (void *&)original_realloc_ptr = orig_alloc_ptrs[2]; (void *&)original_calloc_ptr = orig_alloc_ptrs[3]; MALLOC_ASSERT( original_malloc_ptr!=malloc_proxy, "standard malloc not found" ); /* It's workaround for a bug in GNU Libc 2.9 (as it shipped with Fedora 10). 1st call to libc's malloc should be not from threaded code. */ original_free_ptr(original_malloc_ptr(1024)); original_malloc_found = 1; } } #endif /* MALLOC_LD_PRELOAD */ #if DO_ITT_NOTIFY MallocInitializeITT(); #endif /* Preventing TBB allocator library from unloading to prevent resource leak, as memory is not released on the library unload. */ #if USE_WINTHREAD // Prevent Windows from displaying message boxes if it fails to load library UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); LoadLibrary(MALLOCLIB_NAME); SetErrorMode (prev_mode); #endif /* USE_PTHREAD */ }
void *ExtMemoryPool::mallocLargeObject(size_t size, size_t alignment) { size_t headersSize = sizeof(LargeMemoryBlock)+sizeof(LargeObjectHdr); // TODO: take into account that they are already largeObjectAlignment-aligned size_t allocationSize = alignUp(size+headersSize+alignment, largeBlockCacheStep); if (allocationSize < size) // allocationSize is wrapped around after alignUp return NULL; LargeMemoryBlock* lmb = loc.get(this, allocationSize); if (!lmb) { BackRefIdx backRefIdx = BackRefIdx::newBackRef(/*largeObj=*/true); if (backRefIdx.isInvalid()) return NULL; // unalignedSize is set in getLargeBlock lmb = backend.getLargeBlock(allocationSize); if (!lmb) { removeBackRef(backRefIdx); return NULL; } lmb->backRefIdx = backRefIdx; STAT_increment(getThreadId(), ThreadCommonCounters, allocNewLargeObj); } void *alignedArea = (void*)alignUp((uintptr_t)lmb+headersSize, alignment); LargeObjectHdr *header = (LargeObjectHdr*)alignedArea-1; header->memoryBlock = lmb; header->backRefIdx = lmb->backRefIdx; setBackRef(header->backRefIdx, header); lmb->objectSize = size; MALLOC_ASSERT( isLargeObject(alignedArea), ASSERT_TEXT ); return alignedArea; }