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 + -
显示快捷键?