allocator_bucket_alloc.c

来自「MPI stands for the Message Passing Inter」· C语言 代码 · 共 393 行 · 第 1/2 页

C
393
字号
        bucket_size >>= 1;        bucket_num++;    }    bucket_size = 1;    bucket_size <<= MCA_ALLOCATOR_BUCKET_1_BITSHIFTS + bucket_num;     /* if were allocated more memory then we actually need, then we will try to     * break it up into multiple chunks in the current bucket */    allocated_size -= aligned_max_size;    chunk = segment_header->first_chunk = first_chunk;    /* we now need to get a lock on the bucket */    OPAL_THREAD_LOCK(&(mem_options->buckets[bucket_num].lock));    /* add the segment into the segment list */    segment_header->next_segment = mem_options->buckets[bucket_num].segment_head;    mem_options->buckets[bucket_num].segment_head = segment_header;    if(allocated_size >= bucket_size) {        mem_options->buckets[bucket_num].free_chunk =                        (mca_allocator_bucket_chunk_header_t *) ((char *) chunk + bucket_size);        chunk->next_in_segment = (mca_allocator_bucket_chunk_header_t *)                                   ((char *)chunk + bucket_size);        while(allocated_size >= bucket_size) {            chunk = (mca_allocator_bucket_chunk_header_t *) ((char *) chunk + bucket_size);            chunk->u.next_free = (mca_allocator_bucket_chunk_header_t *)                                 ((char *) chunk + bucket_size);            chunk->next_in_segment = chunk->u.next_free;            allocated_size -= bucket_size;        }        chunk->next_in_segment = first_chunk;        chunk->u.next_free = NULL;    } else {        first_chunk->next_in_segment = first_chunk;    }    first_chunk->u.bucket = bucket_num;    OPAL_THREAD_UNLOCK(&(mem_options->buckets[bucket_num].lock));    /* return the aligned memory */    return((void *) (aligned_memory));}/*  * function to reallocate the segment of memory  */void * mca_allocator_bucket_realloc(    mca_allocator_base_module_t * mem,    void * ptr,     size_t size,     mca_mpool_base_registration_t** registration){    mca_allocator_bucket_t * mem_options = (mca_allocator_bucket_t *) mem;    /* initialize for later bit shifts */    size_t bucket_size = 1;    int bucket_num;    void * ret_ptr;    /* get the header of the chunk */    mca_allocator_bucket_chunk_header_t * chunk = (mca_allocator_bucket_chunk_header_t *) ptr - 1;    bucket_num = chunk->u.bucket;    bucket_size <<= (bucket_num + MCA_ALLOCATOR_BUCKET_1_BITSHIFTS);    /* since the header area is not available to the user, we need to     * subtract off the header size                 */    bucket_size -= sizeof(mca_allocator_bucket_chunk_header_t);    /* if the requested size is less than or equal to what they ask for,     * just give them back what they passed in      */    if(size <= bucket_size) {        return(ptr);    }    /* we need a new space in memory, so let's get it */    ret_ptr = mca_allocator_bucket_alloc((mca_allocator_base_module_t *) mem_options, size, registration);    if(NULL == ret_ptr) {        /* we were unable to get a larger area of memory */        return(NULL);    }    /* copy what they have in memory to the new spot */    memcpy(ret_ptr, ptr, bucket_size);    /* free the old area in memory */    mca_allocator_bucket_free((mca_allocator_base_module_t *) mem_options, ptr);    return(ret_ptr); }/*   * Frees the passed region of memory   *   */void mca_allocator_bucket_free(mca_allocator_base_module_t * mem, void * ptr){    mca_allocator_bucket_t * mem_options = (mca_allocator_bucket_t *) mem;    mca_allocator_bucket_chunk_header_t * chunk  = (mca_allocator_bucket_chunk_header_t *) ptr - 1;     int bucket_num = chunk->u.bucket;    OPAL_THREAD_LOCK(&(mem_options->buckets[bucket_num].lock));    chunk->u.next_free = mem_options->buckets[bucket_num].free_chunk;     mem_options->buckets[bucket_num].free_chunk = chunk;    OPAL_THREAD_UNLOCK(&(mem_options->buckets[bucket_num].lock));}/*   * Frees all the memory from all the buckets back to the system. Note that   * this function only frees memory that was previously freed with   * mca_allocator_bucket_free().   *   */int mca_allocator_bucket_cleanup(mca_allocator_base_module_t * mem){    mca_allocator_bucket_t * mem_options = (mca_allocator_bucket_t *) mem;    int i;    mca_allocator_bucket_chunk_header_t * next_chunk;    mca_allocator_bucket_chunk_header_t * chunk;    mca_allocator_bucket_chunk_header_t * first_chunk;    mca_allocator_bucket_segment_head_t ** segment_header;    mca_allocator_bucket_segment_head_t * segment;    bool empty = true;    for(i = 0; i < mem_options->num_buckets; i++) {        OPAL_THREAD_LOCK(&(mem_options->buckets[i].lock));        segment_header = &(mem_options->buckets[i].segment_head);        if( NULL == (*segment_header) ) {            OPAL_THREAD_UNLOCK(&(mem_options->buckets[i].lock));            continue;        }        /* first we suppose the execution is correct and all chunks         * have been correctly released. Therefore, if we make sure         * all segments only contain free items then we can release         * everything in one go.         */        empty = true;        segment = mem_options->buckets[i].segment_head;        while( (true == empty) && (NULL != segment) ) {            first_chunk = segment->first_chunk;             chunk = first_chunk;            /* determine if the segment is free */            do {                if(chunk->u.bucket == i) {                    empty = false;                    break;                }                chunk = chunk->next_in_segment;            } while(chunk != first_chunk);            /* go to next segment */            segment = segment->next_segment;        }        if( true == empty ) {  /* all segments ready for release */            mca_allocator_bucket_segment_head_t* next_segment;            segment = mem_options->buckets[i].segment_head;            while( NULL != segment ) {                next_segment = segment->next_segment;                /* free the memory */                if(mem_options->free_mem_fn)                    mem_options->free_mem_fn(mem->alc_mpool, segment);                segment = next_segment;            }            mem_options->buckets[i].free_chunk = NULL;            mem_options->buckets[i].segment_head = NULL;        } else {            /* traverse the list of segment headers until we hit NULL */            while(NULL != *segment_header) {                first_chunk = (*segment_header)->first_chunk;                 chunk = first_chunk;                empty = true;                /* determine if the segment is free */                do {                    if(chunk->u.bucket == i) {                        empty = false;                    }                    chunk = chunk->next_in_segment;                } while(empty && (chunk != first_chunk));                if(empty) {                    chunk = first_chunk;                    /* remove the chunks from the free list */                    do {                        if(mem_options->buckets[i].free_chunk == chunk) {                            mem_options->buckets[i].free_chunk = chunk->u.next_free;                        } else {                            next_chunk = mem_options->buckets[i].free_chunk;                            while(next_chunk->u.next_free != chunk) {                                next_chunk = next_chunk->u.next_free;                            }                            next_chunk->u.next_free = chunk->u.next_free;                         }                    } while((chunk = chunk->next_in_segment) != first_chunk);                    /* set the segment list to point to the next segment */                    segment = *segment_header;                    *segment_header = segment->next_segment;                    /* free the memory */                    if(mem_options->free_mem_fn)                        mem_options->free_mem_fn(mem->alc_mpool, segment);                } else {                    /* go to next segment */                    segment_header = &((*segment_header)->next_segment);                }            }        }        /* relese the lock on the bucket */        OPAL_THREAD_UNLOCK(&(mem_options->buckets[i].lock));    }    return(OMPI_SUCCESS);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?