Exemple #1
0
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);
    }
}
Exemple #2
0
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);
}
Exemple #10
0
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;
}
Exemple #12
0
	/*******************************************************
		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 */
Exemple #13
0
/*
 * 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 */
Exemple #14
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
}
Exemple #15
0
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;
}
Exemple #16
0
	/*******************************************************
		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;
}
Exemple #19
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 */
Exemple #20
0
	/*******************************************************
		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 */
}
Exemple #22
0
	/*******************************************************
		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);
}
Exemple #23
0
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;
}
Exemple #25
0
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 */
}
Exemple #26
0
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;
}
Exemple #27
0
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;
}
Exemple #29
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 */
}
Exemple #30
0
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;
}