/*! * \brief pmsCustomDealloc() * * \param[in] data to be freed or returned to the storage * \return void */ void pmsCustomDealloc(void *data) { l_int32 level; L_PIX_MEM_STORE *pms; L_PTRA *pa; PROCNAME("pmsCustomDealloc"); if ((pms = CustomPMS) == NULL) { L_ERROR("pms not defined\n", procName); return; } if (pmsGetLevelForDealloc(data, &level) == 1) { L_ERROR("level not found\n", procName); return; } if (level < 0) { /* no logging; just free the data */ LEPT_FREE(data); } else { /* return the data to the store */ pa = ptraaGetPtra(pms->paa, level, L_HANDLE_ONLY); ptraAdd(pa, data); if (pms->logfile) pms->meminuse[level]--; } return; }
/*! * ptraaDestroy() * * Input: &paa (<to be nulled>) * freeflag (TRUE to free each remaining item in each ptra) * warnflag (TRUE to warn if any remaining items are not destroyed) * Return: void * * Notes: * (1) See ptraDestroy() for use of @freeflag and @warnflag. * (2) To destroy the ptraa, we destroy each ptra, then the ptr array, * then the ptraa, and then null the contents of the input ptr. */ void ptraaDestroy(L_PTRAA **ppaa, l_int32 freeflag, l_int32 warnflag) { l_int32 i, n; L_PTRA *pa; L_PTRAA *paa; PROCNAME("ptraaDestroy"); if (ppaa == NULL) { L_WARNING("ptr address is NULL\n", procName); return; } if ((paa = *ppaa) == NULL) return; ptraaGetSize(paa, &n); for (i = 0; i < n; i++) { pa = ptraaGetPtra(paa, i, L_REMOVE); ptraDestroy(&pa, freeflag, warnflag); } FREE(paa->ptra); FREE(paa); *ppaa = NULL; return; }
/*! * ptraaFlattenToPtra() * * Input: ptraa * Return: ptra, or null on error * * Notes: * (1) This 'flattens' the ptraa to a ptra, taking the items in * each ptra, in order, starting with the first ptra, etc. * (2) As a side-effect, the ptra are all removed from the ptraa * and destroyed, leaving an empty ptraa. */ L_PTRA * ptraaFlattenToPtra(L_PTRAA *paa) { l_int32 i, n; L_PTRA *pat, *pad; PROCNAME("ptraaFlattenToPtra"); if (!paa) return (L_PTRA *) ERROR_PTR("paa not defined", procName, NULL); pad = ptraCreate(0); ptraaGetSize(paa, &n); for (i = 0; i < n; i++) { pat = ptraaGetPtra(paa, i, L_REMOVE); if (!pat) continue; ptraJoin(pad, pat); ptraDestroy(&pat, FALSE, FALSE); /* they're all empty */ } return pad; }
/*! * pmsCustomAlloc() * * Input: nbytes (min number of bytes in the chunk to be retrieved) * Return: data (ptr to chunk) * * Notes: * (1) This attempts to find a suitable pre-allocated chunk. * If not found, it dynamically allocates the chunk. * (2) If logging is turned on, the allocations that are not taken * from the memory store, and are at least as large as the * minimum size the store can handle, are logged to file. */ void * pmsCustomAlloc(size_t nbytes) { l_int32 level; void *data; L_PIX_MEM_STORE *pms; L_PTRA *pa; PROCNAME("pmsCustomAlloc"); if ((pms = CustomPMS) == NULL) return (void *)ERROR_PTR("pms not defined", procName, NULL); pmsGetLevelForAlloc(nbytes, &level); if (level < 0) { /* size range invalid; must alloc */ if ((data = pmsGetAlloc(nbytes)) == NULL) return (void *)ERROR_PTR("data not made", procName, NULL); } else { /* get from store */ pa = ptraaGetPtra(pms->paa, level, L_HANDLE_ONLY); data = ptraRemoveLast(pa); if (data && pms->logfile) { pms->memused[level]++; pms->meminuse[level]++; if (pms->meminuse[level] > pms->memmax[level]) pms->memmax[level]++; } if (!data) { /* none left at this level */ data = pmsGetAlloc(nbytes); if (pms->logfile) pms->memempty[level]++; } } return data; }