diff options
author | Quincey Koziol <koziol@koziol.gov> | 2020-03-10 23:37:55 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@koziol.gov> | 2020-03-10 23:37:55 (GMT) |
commit | 04b8cc82a858aeb8a0beb3738984240b528952dc (patch) | |
tree | 708c35662a0be75429403326035b767693640437 /src/H5FL.c | |
parent | 9abbdeaa66c70a00b6a7bedee9c76d2493a8e947 (diff) | |
download | hdf5-04b8cc82a858aeb8a0beb3738984240b528952dc.zip hdf5-04b8cc82a858aeb8a0beb3738984240b528952dc.tar.gz hdf5-04b8cc82a858aeb8a0beb3738984240b528952dc.tar.bz2 |
Add routines to query the library's free list sizes and allocation stats.
Diffstat (limited to 'src/H5FL.c')
-rw-r--r-- | src/H5FL.c | 484 |
1 files changed, 282 insertions, 202 deletions
@@ -130,17 +130,23 @@ static H5FL_track_t *H5FL_out_head_g = NULL; #endif /* H5FL_TRACK */ /* Forward declarations of local static functions */ +static void * H5FL__malloc(size_t mem_size); +static herr_t H5FL__reg_init(H5FL_reg_head_t *head); static herr_t H5FL__reg_gc(void); static herr_t H5FL__reg_gc_list(H5FL_reg_head_t *head); static int H5FL__reg_term(void); -static herr_t H5FL__arr_gc(void); -static herr_t H5FL__arr_gc_list(H5FL_arr_head_t *head); -static int H5FL__arr_term(void); -static herr_t H5FL__blk_gc(void); +static H5FL_blk_node_t *H5FL__blk_find_list(H5FL_blk_node_t **head, size_t size); +static H5FL_blk_node_t *H5FL__blk_create_list(H5FL_blk_node_t **head, size_t size); +static herr_t H5FL__blk_init(H5FL_blk_head_t *head); static herr_t H5FL__blk_gc_list(H5FL_blk_head_t *head); +static herr_t H5FL__blk_gc(void); static int H5FL__blk_term(void); -static herr_t H5FL__fac_gc(void); +static herr_t H5FL__arr_init(H5FL_arr_head_t *head); +static herr_t H5FL__arr_gc_list(H5FL_arr_head_t *head); +static herr_t H5FL__arr_gc(void); +static int H5FL__arr_term(void); static herr_t H5FL__fac_gc_list(H5FL_fac_head_t *head); +static herr_t H5FL__fac_gc(void); static int H5FL__fac_term_all(void); /* Declare a free list to manage the H5FL_blk_node_t struct */ @@ -217,7 +223,7 @@ H5FL_term_package(void) /*------------------------------------------------------------------------- - * Function: H5FL_malloc + * Function: H5FL__malloc * * Purpose: Attempt to allocate space using malloc. If malloc fails, garbage * collect and try again. If malloc fails again, then return NULL. @@ -228,16 +234,14 @@ H5FL_term_package(void) * Programmer: Quincey Koziol * Tuesday, August 1, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static void * -H5FL_malloc(size_t mem_size) +H5FL__malloc(size_t mem_size) { void *ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Attempt to allocate the memory requested */ if(NULL==(ret_value=H5MM_malloc(mem_size))) { @@ -252,11 +256,11 @@ H5FL_malloc(size_t mem_size) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FL_malloc() */ +} /* end H5FL__malloc() */ /*------------------------------------------------------------------------- - * Function: H5FL_reg_init + * Function: H5FL__reg_init * * Purpose: Initialize a free list for a certain type. Right now, this just * adds the free list to the list of things to garbage collect. @@ -267,17 +271,15 @@ done: * Programmer: Quincey Koziol * Friday, March 24, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5FL_reg_init(H5FL_reg_head_t *head) +H5FL__reg_init(H5FL_reg_head_t *head) { H5FL_reg_gc_node_t *new_node; /* Pointer to the node for the new list to garbage collect */ herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Allocate a new garbage collection node */ if(NULL == (new_node = (H5FL_reg_gc_node_t *)H5MM_malloc(sizeof(H5FL_reg_gc_node_t)))) @@ -304,7 +306,7 @@ H5FL_reg_init(H5FL_reg_head_t *head) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FL_reg_init() */ +} /* end H5FL__reg_init() */ /*------------------------------------------------------------------------- @@ -317,8 +319,6 @@ done: * Programmer: Quincey Koziol * Friday, March 24, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -403,8 +403,6 @@ done: * Programmer: Quincey Koziol * Friday, March 24, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -419,7 +417,7 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) /* Make certain the list is initialized first */ if(!head->init) - if(H5FL_reg_init(head)<0) + if(H5FL__reg_init(head) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'regular' blocks") /* Check for nodes available on the free list first */ @@ -438,7 +436,7 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) } /* end if */ /* Otherwise allocate a node */ else { - if (NULL==(ret_value = H5FL_malloc(head->size))) + if(NULL == (ret_value = H5FL__malloc(head->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Increment the number of blocks allocated in list */ @@ -480,8 +478,6 @@ done: * Programmer: Quincey Koziol * Monday, December 23, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -524,35 +520,34 @@ static herr_t H5FL__reg_gc_list(H5FL_reg_head_t *head) { H5FL_reg_node_t *free_list; /* Pointer to nodes in free list being garbage collected */ - size_t total_mem; /* Total memory used on list */ FUNC_ENTER_STATIC_NOERR - /* Calculate the total memory used on this list */ - total_mem = head->onlist * head->size; - /* For each free list being garbage collected, walk through the nodes and free them */ free_list = head->list; while(free_list != NULL) { - void *tmp; /* Temporary node pointer */ + H5FL_reg_node_t *tmp; /* Temporary node pointer */ + /* Get the pointer to the next node */ tmp = free_list->next; - /* Decrement the count of nodes allocated and free the node */ - head->allocated--; - + /* Free the block */ H5MM_free(free_list); - free_list = (H5FL_reg_node_t *)tmp; + /* Advance to the next node */ + free_list = tmp; } /* end while */ + /* Decrement the count of nodes allocated and free the node */ + head->allocated -= head->onlist; + + /* Decrement global count of free memory on "regular" lists */ + H5FL_reg_gc_head.mem_freed -= (head->onlist * head->size); + /* Indicate no free nodes on the free list */ head->list = NULL; head->onlist = 0; - /* Decrement global count of free memory on "regular" lists */ - H5FL_reg_gc_head.mem_freed -= total_mem; - FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FL__reg_gc_list() */ @@ -568,10 +563,6 @@ H5FL__reg_gc_list(H5FL_reg_head_t *head) * Programmer: Quincey Koziol * Friday, March 24, 2000 * - * Modifications: - * Broke into two parts, one for looping over all the free lists and - * another for freeing each list - QAK 7/25/00 - * *------------------------------------------------------------------------- */ static herr_t @@ -670,7 +661,7 @@ HDprintf("%s: head->name = %s, head->allocated = %d\n", FUNC, H5FL_reg_gc_head.f /*------------------------------------------------------------------------- - * Function: H5FL_blk_find_list + * Function: H5FL__blk_find_list * * Purpose: Finds the free list for blocks of a given size. Also moves that * free list node to the head of the priority queue (if it isn't there @@ -684,16 +675,14 @@ HDprintf("%s: head->name = %s, head->allocated = %d\n", FUNC, H5FL_reg_gc_head.f * Programmer: Quincey Koziol * Thursday, March 23, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static H5FL_blk_node_t * -H5FL_blk_find_list(H5FL_blk_node_t **head, size_t size) +H5FL__blk_find_list(H5FL_blk_node_t **head, size_t size) { H5FL_blk_node_t *temp = NULL; /* Temp. pointer to node in the native list */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Find the correct free list */ temp=*head; @@ -729,11 +718,11 @@ H5FL_blk_find_list(H5FL_blk_node_t **head, size_t size) } /* end if */ FUNC_LEAVE_NOAPI(temp) -} /* end H5FL_blk_find_list() */ +} /* end H5FL__blk_find_list() */ /*------------------------------------------------------------------------- - * Function: H5FL_blk_create_list + * Function: H5FL__blk_create_list * * Purpose: Creates a new free list for blocks of the given size at the * head of the priority queue. @@ -745,47 +734,38 @@ H5FL_blk_find_list(H5FL_blk_node_t **head, size_t size) * Programmer: Quincey Koziol * Thursday, March 23, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static H5FL_blk_node_t * -H5FL_blk_create_list(H5FL_blk_node_t **head, size_t size) +H5FL__blk_create_list(H5FL_blk_node_t **head, size_t size) { - H5FL_blk_node_t *temp; /* Temp. pointer to node in the list */ H5FL_blk_node_t *ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Allocate room for the new free list node */ - if(NULL==(temp=H5FL_MALLOC(H5FL_blk_node_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk info") + if(NULL == (ret_value = H5FL_CALLOC(H5FL_blk_node_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "memory allocation failed for chunk info") /* Set the correct values for the new free list */ - temp->size=size; - temp->list=NULL; + ret_value->size = size; /* Attach to head of priority queue */ - if(*head==NULL) { - *head=temp; - temp->next=temp->prev=NULL; - } /* end if */ + if(NULL == *head) + *head = ret_value; else { - temp->next=*head; - (*head)->prev=temp; - temp->prev=NULL; - *head=temp; + ret_value->next = *head; + (*head)->prev = ret_value; + *head = ret_value; } /* end else */ - ret_value=temp; - done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FL_blk_create_list() */ +} /* end H5FL__blk_create_list() */ /*------------------------------------------------------------------------- - * Function: H5FL_blk_init + * Function: H5FL__blk_init * * Purpose: Initialize a priority queue of a certain type. Right now, this just * adds the PQ to the list of things to garbage collect. @@ -796,17 +776,15 @@ done: * Programmer: Quincey Koziol * Saturday, March 25, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5FL_blk_init(H5FL_blk_head_t *head) +H5FL__blk_init(H5FL_blk_head_t *head) { H5FL_blk_gc_node_t *new_node; /* Pointer to the node for the new list to garbage collect */ herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Allocate a new garbage collection node */ if(NULL == (new_node = (H5FL_blk_gc_node_t *)H5MM_malloc(sizeof(H5FL_blk_gc_node_t)))) @@ -824,7 +802,7 @@ H5FL_blk_init(H5FL_blk_head_t *head) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FL_blk_init() */ +} /* end H5FL__blk_init() */ /*------------------------------------------------------------------------- @@ -839,8 +817,6 @@ done: * Programmer: Quincey Koziol * Monday, December 16, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ htri_t @@ -856,10 +832,11 @@ H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size) /* check if there is a free list for blocks of this size */ /* and if there are any blocks available on the list */ - if((free_list = H5FL_blk_find_list(&(head->head), size)) != NULL && free_list->list != NULL) + if((free_list = H5FL__blk_find_list(&(head->head), size)) != NULL && free_list->list != NULL) ret_value = TRUE; else ret_value = FALSE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_blk_free_block_avail() */ @@ -878,8 +855,6 @@ H5FL_blk_free_block_avail(H5FL_blk_head_t *head, size_t size) * Programmer: Quincey Koziol * Thursday, March 23, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -897,31 +872,40 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) /* Make certain the list is initialized first */ if(!head->init) - if(H5FL_blk_init(head)<0) + if(H5FL__blk_init(head) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'block' list") /* check if there is a free list for blocks of this size */ /* and if there are any blocks available on the list */ - if((free_list=H5FL_blk_find_list(&(head->head),size))!=NULL && free_list->list!=NULL) { + if(NULL != (free_list = H5FL__blk_find_list(&(head->head), size)) && NULL != free_list->list) { /* Remove the first node from the free list */ temp=free_list->list; free_list->list=free_list->list->next; /* Decrement the number of blocks & memory used on free list */ + free_list->onlist--; head->onlist--; head->list_mem-=size; /* Decrement the amount of global "block" free list memory in use */ H5FL_blk_gc_head.mem_freed-=size; - } /* end if */ /* No free list available, or there are no nodes on the list, allocate a new node to give to the user */ else { + /* Check if there was no free list for native blocks of this size */ + if(NULL == free_list) + /* Create a new list node and insert it to the queue */ + free_list = H5FL__blk_create_list(&(head->head), size); + HDassert(free_list); + /* Allocate new node, with room for the page info header and the actual page data */ - if(NULL == (temp = (H5FL_blk_list_t *)H5FL_malloc(sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE + size))) + if(NULL == (temp = (H5FL_blk_list_t *)H5FL__malloc(sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE + size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for chunk") - /* Increment the number of blocks allocated */ + /* Increment the number of blocks of this size */ + free_list->allocated++; + + /* Increment the total number of blocks allocated */ head->allocated++; } /* end else */ @@ -970,8 +954,6 @@ done: * Programmer: Quincey Koziol * Monday, December 23, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1011,8 +993,6 @@ done: * Programmer: Quincey Koziol * Thursday, March 23, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1055,7 +1035,7 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) #endif /* H5FL_TRACK */ /* Get the pointer to the native block info header in front of the native block to free */ - temp = (H5FL_blk_list_t *)((void *)((unsigned char *)block - sizeof(H5FL_blk_list_t))); /*lint !e826 Pointer-to-pointer cast is appropriate here */ + temp = (H5FL_blk_list_t *)((void *)((unsigned char *)block - (sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE))); /*lint !e826 Pointer-to-pointer cast is appropriate here */ /* Save the block's size for later */ free_size=temp->size; @@ -1064,20 +1044,18 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) HDmemset(temp,255,free_size + sizeof(H5FL_blk_list_t) + H5FL_TRACK_SIZE); #endif /* H5FL_DEBUG */ - /* check if there is a free list for native blocks of this size */ - if((free_list=H5FL_blk_find_list(&(head->head),free_size))==NULL) { + /* Check if there is a free list for native blocks of this size */ + if(NULL == (free_list = H5FL__blk_find_list(&(head->head), free_size))) /* No free list available, create a new list node and insert it to the queue */ - free_list=H5FL_blk_create_list(&(head->head),free_size); - HDassert(free_list); - } /* end if */ + free_list = H5FL__blk_create_list(&(head->head), free_size); + HDassert(free_list); /* Prepend the free'd native block to the front of the free list */ - if(free_list!=NULL) { - temp->next=free_list->list; /* Overwrites the size field in union */ - free_list->list=temp; - } /* end if */ + temp->next = free_list->list; /* Note: Overwrites the size field in union */ + free_list->list = temp; /* Increment the number of blocks on free list */ + free_list->onlist++; head->onlist++; head->list_mem += free_size; @@ -1113,8 +1091,6 @@ done: * Programmer: Quincey Koziol * Thursday, March 23, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1191,44 +1167,70 @@ done: static herr_t H5FL__blk_gc_list(H5FL_blk_head_t *head) { + H5FL_blk_node_t *blk_head; /* Temp. ptr to the free list page node */ + FUNC_ENTER_STATIC_NOERR /* Loop through all the nodes in the block free list queue */ - while(head->head != NULL) { - H5FL_blk_list_t *list; /* The free list of native nodes of a particular size */ - void *temp; /* Temp. ptr to the free list page node */ + blk_head = head->head; + while(blk_head != NULL) { + H5FL_blk_node_t *blk_next; /* Temp. ptr to the next free list node */ + H5FL_blk_list_t *list; /* The free list of native nodes of a particular size */ - temp = head->head->next; + /* Sanity check */ + HDassert((blk_head->onlist && blk_head->list) || (0 == blk_head->onlist && NULL == blk_head->list)); /* Loop through all the blocks in the free list, freeing them */ - list = head->head->list; + list = blk_head->list; while(list != NULL) { - void *next; /* Temp. ptr to the free list list node */ + H5FL_blk_list_t *next; /* Temp. ptr to the free list list node */ + /* Get the pointer to the next node */ next = list->next; - /* Decrement the number of blocks & memory allocated from this PQ */ - head->allocated--; - head->list_mem -= head->head->size; - - /* Decrement global count of free memory on "block" lists */ - H5FL_blk_gc_head.mem_freed -= head->head->size; - /* Free the block */ H5MM_free(list); - list = (H5FL_blk_list_t *)next; + /* Advance to the next node */ + list = next; } /* end while */ - /* Free the free list node */ - head->head = H5FL_FREE(H5FL_blk_node_t, head->head); + /* Decrement the number of blocks allocated from this list */ + blk_head->allocated -= blk_head->onlist; + head->allocated -= blk_head->onlist; + + /* Decrement count of free memory on this "block" list */ + head->list_mem -= (blk_head->onlist * blk_head->size); + + /* Decrement global count of free memory on "block" lists */ + H5FL_blk_gc_head.mem_freed -= (blk_head->onlist * blk_head->size); + + /* Indicate no free nodes on the free list */ + blk_head->list = NULL; + blk_head->onlist = 0; - /* Advance to the next free list */ - head->head = (H5FL_blk_node_t *)temp; + /* Get pointer to next node */ + blk_next = blk_head->next; + + /* Check for list completely unused now */ + if(0 == blk_head->allocated) { + /* Patch this node out of the PQ */ + if(head->head == blk_head) + head->head = blk_head->next; + if(blk_head->prev) + blk_head->prev->next = blk_head->next; + if(blk_head->next) + blk_head->next->prev = blk_head->prev; + + /* Free the free list node */ + H5FL_FREE(H5FL_blk_node_t, blk_head); + } /* end if */ + + /* Advance to the next node */ + blk_head = blk_next; } /* end while */ /* Indicate no free nodes on the free list */ - head->head = NULL; head->onlist = 0; /* Double check that all the memory on this list is recycled */ @@ -1257,7 +1259,7 @@ H5FL__blk_gc(void) H5FL_blk_gc_node_t *gc_node; /* Pointer into the list of things to garbage collect */ herr_t ret_value = SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Walk through all the free lists, free()'ing the nodes */ gc_node = H5FL_blk_gc_head.first; @@ -1341,7 +1343,7 @@ HDprintf("%s: head->name = %s, head->allocated = %d\n", FUNC, H5FL_blk_gc_head.f /*------------------------------------------------------------------------- - * Function: H5FL_arr_init + * Function: H5FL__arr_init * * Purpose: Initialize a free list for a arrays of certain type. Right now, * this just adds the free list to the list of things to garbage collect. @@ -1352,18 +1354,16 @@ HDprintf("%s: head->name = %s, head->allocated = %d\n", FUNC, H5FL_blk_gc_head.f * Programmer: Quincey Koziol * Saturday, March 25, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5FL_arr_init(H5FL_arr_head_t *head) +H5FL__arr_init(H5FL_arr_head_t *head) { H5FL_gc_arr_node_t *new_node; /* Pointer to the node for the new list to garbage collect */ size_t u; /* Local index variable */ herr_t ret_value=SUCCEED; /* return value*/ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Allocate a new garbage collection node */ if(NULL == (new_node = (H5FL_gc_arr_node_t *)H5MM_malloc(sizeof(H5FL_gc_arr_node_t)))) @@ -1389,7 +1389,7 @@ H5FL_arr_init(H5FL_arr_head_t *head) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FL_arr_init() */ +} /* end H5FL__arr_init() */ /*------------------------------------------------------------------------- @@ -1403,8 +1403,6 @@ done: * Programmer: Quincey Koziol * Friday, March 24, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1481,8 +1479,6 @@ done: * Programmer: Quincey Koziol * Saturday, March 25, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1500,7 +1496,7 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) /* Make certain the list is initialized first */ if(!head->init) - if(H5FL_arr_init(head)<0) + if(H5FL__arr_init(head) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't initialize 'array' blocks") /* Sanity check that the number of elements is supported */ @@ -1527,10 +1523,13 @@ H5FL_arr_malloc(H5FL_arr_head_t *head, size_t elem) } /* end if */ /* Otherwise allocate a node */ else { - if(NULL == (new_obj = (H5FL_arr_list_t *)H5FL_malloc(sizeof(H5FL_arr_list_t)+mem_size))) + if(NULL == (new_obj = (H5FL_arr_list_t *)H5FL__malloc(sizeof(H5FL_arr_list_t)+mem_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Increment the number of blocks allocated in list */ + /* Increment the number of blocks of this size */ + head->list_arr[elem].allocated++; + + /* Increment the number of blocks allocated in list, of all sizes */ head->allocated++; } /* end else */ @@ -1556,8 +1555,6 @@ done: * Programmer: Quincey Koziol * Monday, December 23, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1594,8 +1591,6 @@ done: * Programmer: Quincey Koziol * Saturday, March 25, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1667,34 +1662,35 @@ H5FL__arr_gc_list(H5FL_arr_head_t *head) for(u = 0; u < (unsigned)head->maxelem; u++) { if(head->list_arr[u].onlist > 0) { H5FL_arr_list_t *arr_free_list; /* Pointer to nodes in free list being garbage collected */ - size_t total_mem; /* Total memory used on list */ - - /* Calculate the total memory used on this list */ - total_mem = head->list_arr[u].onlist * head->list_arr[u].size; /* For each free list being garbage collected, walk through the nodes and free them */ arr_free_list = head->list_arr[u].list; while(arr_free_list != NULL) { - void *tmp; /* Temporary node pointer */ + H5FL_arr_list_t *tmp; /* Temporary node pointer */ + /* Get the pointer to the next node */ tmp = arr_free_list->next; - /* Decrement the count of nodes allocated and free the node */ - head->allocated--; + /* Free the node */ H5MM_free(arr_free_list); - arr_free_list = (H5FL_arr_list_t *)tmp; + /* Advance to the next node */ + arr_free_list = tmp; } /* end while */ - /* Indicate no free nodes on the free list */ - head->list_arr[u].list = NULL; - head->list_arr[u].onlist = 0; + /* Decrement the count of nodes allocated */ + head->list_arr[u].allocated -= head->list_arr[u].onlist; + head->allocated -= head->list_arr[u].onlist; /* Decrement count of free memory on this "array" list */ - head->list_mem -= total_mem; + head->list_mem -= (head->list_arr[u].onlist * head->list_arr[u].size); /* Decrement global count of free memory on "array" lists */ - H5FL_arr_gc_head.mem_freed -= total_mem; + H5FL_arr_gc_head.mem_freed -= (head->list_arr[u].onlist * head->list_arr[u].size); + + /* Indicate no free nodes on the free list */ + head->list_arr[u].list = NULL; + head->list_arr[u].onlist = 0; } /* end if */ } /* end for */ @@ -1820,8 +1816,6 @@ HDprintf("%s: head->name = %s, head->allocated = %d\n", FUNC, H5FL_arr_gc_head.f * Programmer: Quincey Koziol * Saturday, April 3, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1856,8 +1850,6 @@ H5FL_seq_free(H5FL_seq_head_t *head, void *obj) * Programmer: Quincey Koziol * Saturday, April 3, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1889,8 +1881,6 @@ H5FL_seq_malloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) * Programmer: Quincey Koziol * Saturday, April 3, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1922,8 +1912,6 @@ H5FL_seq_calloc(H5FL_seq_head_t *head, size_t elem H5FL_TRACK_PARAMS) * Programmer: Quincey Koziol * Saturday, April 3, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ void * @@ -1955,11 +1943,6 @@ H5FL_seq_realloc(H5FL_seq_head_t *head, void * obj, size_t new_elem H5FL_TRACK_P * Programmer: Quincey Koziol * Wednesday, February 2, 2005 * - * Modifications: - * Neil Fortner - * Friday, December 19, 2008 - * Totally rewritten to support new factory implementation - * *------------------------------------------------------------------------- */ H5FL_fac_head_t * @@ -2032,11 +2015,6 @@ done: * Programmer: Quincey Koziol * Wednesday, February 2, 2005 * - * Modifications: - * Neil Fortner - * Friday, December 19, 2008 - * Totally rewritten to support new factory implementation - * *------------------------------------------------------------------------- */ void * @@ -2120,11 +2098,6 @@ done: * Programmer: Quincey Koziol * Wednesday, February 2, 2005 * - * Modifications: - * Neil Fortner - * Friday, December 19, 2008 - * Totally rewritten to support new factory implementation - * *------------------------------------------------------------------------- */ void * @@ -2155,7 +2128,7 @@ H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) } /* end if */ /* Otherwise allocate a node */ else { - if (NULL==(ret_value = H5FL_malloc(head->size))) + if(NULL == (ret_value = H5FL__malloc(head->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Increment the number of blocks allocated in list */ @@ -2197,11 +2170,6 @@ done: * Programmer: Quincey Koziol * Wednesday, February 2, 2005 * - * Modifications: - * Neil Fortner - * Friday, December 19, 2008 - * Totally rewritten to support new factory implementation - * *------------------------------------------------------------------------- */ void * @@ -2245,35 +2213,34 @@ static herr_t H5FL__fac_gc_list(H5FL_fac_head_t *head) { H5FL_fac_node_t *free_list; /* Pointer to nodes in free list being garbage collected */ - size_t total_mem; /* Total memory used on list */ FUNC_ENTER_STATIC_NOERR - /* Calculate the total memory used on this list */ - total_mem = head->onlist * head->size; - /* For each free list being garbage collected, walk through the nodes and free them */ free_list = head->list; while(free_list != NULL) { - void *tmp; /* Temporary node pointer */ + H5FL_fac_node_t *tmp; /* Temporary node pointer */ + /* Get the pointer to the next node */ tmp = free_list->next; - /* Decrement the count of nodes allocated and free the node */ - head->allocated--; - + /* Free the block */ H5MM_free(free_list); - free_list = (H5FL_fac_node_t *)tmp; + /* Advance to the next node */ + free_list = tmp; } /* end while */ + /* Decrement the count of nodes allocated and free the node */ + head->allocated -= head->onlist; + + /* Decrement global count of free memory on "factory" lists */ + H5FL_fac_gc_head.mem_freed -= (head->onlist * head->size); + /* Indicate no free nodes on the free list */ head->list = NULL; head->onlist = 0; - /* Decrement global count of free memory on "factory" lists */ - H5FL_fac_gc_head.mem_freed -= total_mem; - FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FL__fac_gc_list() */ @@ -2329,11 +2296,6 @@ done: * Programmer: Quincey Koziol * Wednesday, February 2, 2005 * - * Modifications: - * Neil Fortner - * Friday, December 19, 2008 - * Totally rewritten to support new factory implementation - * *------------------------------------------------------------------------- */ herr_t @@ -2438,8 +2400,6 @@ HDprintf("%s: head->size = %d, head->allocated = %d\n", FUNC, (int)H5FL_fac_gc_h * Programmer: Quincey Koziol * Friday, March 24, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -2495,10 +2455,6 @@ done: * Programmer: Quincey Koziol * Wednesday, August 2, 2000 * - * Modifications: Neil Fortner - * Wednesday, April 8, 2009 - * Added support for factory free lists - * *------------------------------------------------------------------------- */ herr_t @@ -2531,3 +2487,127 @@ H5FL_set_free_list_limits(int reg_global_lim, int reg_list_lim, int arr_global_l FUNC_LEAVE_NOAPI(ret_value) } /* end H5FL_set_free_list_limits() */ + +/*------------------------------------------------------------------------- + * Function: H5FL_get_free_list_sizes + * + * Purpose: Gets the current size of the different kinds of free lists. + * These lists are global for the entire library. The size returned + * included nodes that are freed and awaiting garbage collection / + * reallocation. + * + * Parameters: + * size_t *reg_size; OUT: The current size of all "regular" free list memory used + * size_t *arr_size; OUT: The current size of all "array" free list memory used + * size_t *blk_size; OUT: The current size of all "block" free list memory used + * size_t *fac_size; OUT: The current size of all "factory" free list memory used + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Friday, March 6, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FL_get_free_list_sizes(size_t *reg_size, size_t *arr_size, size_t *blk_size, + size_t *fac_size) +{ + FUNC_ENTER_NOAPI_NOERR + + /* Retrieve the amount of "regular" memory used */ + if(reg_size) { + H5FL_reg_gc_node_t *gc_node; /* Pointer into the list of lists */ + + /* Walk through all the free lists, counting the amount of memory */ + *reg_size = 0; + gc_node = H5FL_reg_gc_head.first; + while(gc_node != NULL) { + H5FL_reg_head_t *reg_list = gc_node->list; /* Head of list */ + + /* Sanity check */ + HDassert(reg_list->init); + + /* Add the amount of memory for this list */ + *reg_size += (reg_list->size * reg_list->allocated); + + /* Go on to the next free list */ + gc_node = gc_node->next; + } /* end while */ + } /* end if */ + + /* Retrieve the amount of "array" memory used */ + if(arr_size) { + H5FL_gc_arr_node_t *gc_arr_node; /* Pointer into the list of things to garbage collect */ + + /* Walk through all the free lists, counting the amount of memory */ + *arr_size = 0; + gc_arr_node = H5FL_arr_gc_head.first; + while(gc_arr_node != NULL) { + H5FL_arr_head_t *head = gc_arr_node->list; /* Head of array list elements */ + + /* Sanity check */ + HDassert(head->init); + + /* Check for any allocated elements in this list */ + if(head->allocated > 0) { + unsigned u; + + /* Walk through the free lists for array sizes */ + for(u = 0; u < (unsigned)head->maxelem; u++) + /* Add the amount of memory for this size */ + *arr_size += head->list_arr[u].allocated * head->list_arr[u].size; + } /* end if */ + + /* Go on to the next free list */ + gc_arr_node = gc_arr_node->next; + } /* end while */ + } /* end if */ + + /* Retrieve the amount of "block" memory used */ + if(blk_size) { + H5FL_blk_gc_node_t *gc_blk_node; /* Pointer into the list of things */ + + /* Walk through all the free lists */ + gc_blk_node = H5FL_blk_gc_head.first; + *blk_size = 0; + while(gc_blk_node != NULL) { + H5FL_blk_node_t *blk_head; /* Temp. ptr to the free list block node */ + + /* Loop through all the nodes in the block free list queue */ + blk_head = gc_blk_node->pq->head; + while(blk_head != NULL) { + /* Add size of blocks on this list */ + *blk_size += (blk_head->allocated * blk_head->size); + + /* Get pointer to next node */ + blk_head = blk_head->next; + } /* end while */ + + /* Go on to the next free list */ + gc_blk_node = gc_blk_node->next; + } /* end while */ + } /* end if */ + + /* Retrieve the amount of "factory" memory used */ + if(fac_size) { + H5FL_fac_gc_node_t *gc_fac_node; /* Pointer into the list of things to garbage collect */ + + /* Walk through all the free lists */ + gc_fac_node = H5FL_fac_gc_head.first; + *fac_size = 0; + while(gc_fac_node != NULL) { + H5FL_fac_head_t *fac_head = gc_fac_node->list; /* Head node for factory list */ + + /* Add size of blocks on this list */ + *fac_size += (fac_head->allocated * fac_head->size); + + /* Go on to the next free list to garbage collect */ + gc_fac_node = gc_fac_node->next; + } /* end while */ + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FL_get_free_list_sizes() */ + |