static int PoolTestInit06 (void) { int retval = 0; void *data = NULL; void *data2 = NULL; Pool *p = PoolInit(1,0,PoolTestAlloc,NULL,PoolTestFree); if (p == NULL) goto end; if (p->allocated != 0) { printf("p->allocated 0 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } data = PoolGet(p); if (data == NULL) { printf("PoolGet returned NULL: "); retval = 0; goto end; } if (p->allocated != 1) { printf("p->allocated 1 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } data2 = PoolGet(p); if (data2 != NULL) { printf("PoolGet returned %p, expected NULL: ", data2); retval = 0; goto end; } PoolReturn(p,data); data = NULL; if (p->allocated != 1) { printf("p->allocated 1 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } if (p->alloc_list_size != 1) { printf("p->alloc_list_size 1 != %" PRIu32 ": ", p->alloc_list_size); retval = 0; goto end; } retval = 1; end: if (data != NULL) SCFree(data); if (data2 != NULL) SCFree(data2); if (p != NULL) PoolFree(p); return retval; }
static int PoolTestInit02 (void) { int retval = 0; Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree); if (p == NULL) goto end; if (p->alloc_list == NULL || p->empty_list == NULL) { printf("list(s) not properly initialized (a:%p e:%p): ", p->alloc_list, p->empty_list); retval = 0; goto end; } if (p->Alloc != PoolTestAlloc) { printf("Alloc func ptr %p != %p: ", p->Alloc, PoolTestAlloc); retval = 0; goto end; } if (p->Cleanup != PoolTestFree) { printf("Free func ptr %p != %p: ", p->Cleanup, PoolTestFree); retval = 0; goto end; } retval = 1; end: if (p != NULL) PoolFree(p); return retval; }
void MIMETypeDestroy(MIMEType * const MIMETypeP) { PoolFree(&MIMETypeP->pool); free(MIMETypeP); }
static int PoolTestInit03 (void) { int retval = 0; void *data = NULL; Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree); if (p == NULL) goto end; data = PoolGet(p); if (data == NULL) { printf("PoolGet returned NULL: "); retval = 0; goto end; } if (p->alloc_list_size != 4) { printf("p->alloc_list_size 4 != %" PRIu32 ": ", p->alloc_list_size); retval = 0; goto end; } if (p->empty_list_size != 6) { printf("p->empty_list_size 6 != %" PRIu32 ": ", p->empty_list_size); retval = 0; goto end; } retval = 1; end: if (p != NULL) PoolFree(p); return retval; }
static int PoolTestInit01 (void) { Pool *p = PoolInit(10,5,10,PoolTestAlloc,NULL,NULL,PoolTestFree); if (p == NULL) return 0; PoolFree(p); return 1; }
static void handleDirectory(TSession *const sessionP, const char *const dirName, time_t const fileModTime, MIMEType *const mimeTypeP) { bool text; bool ascending; uint16_t sort; /* 1=by name, 2=by date */ const char *error; determineSortType(sessionP->requestInfo.query, &ascending, &sort, &text, &error); if (error) { ResponseStatus(sessionP, 400); xmlrpc_strfree(error); } else if (notRecentlyModified(sessionP, fileModTime)) { ResponseStatus(sessionP, 304); ResponseWriteStart(sessionP); } else { TPool pool; bool succeeded; succeeded = PoolCreate(&pool, 1024); if (!succeeded) ResponseStatus(sessionP, 500); else { TList list; uint16_t responseStatus; const char *error; generateListing(&list, dirName, sessionP->requestInfo.uri, &pool, &error, &responseStatus); if (error) { ResponseStatus(sessionP, responseStatus); xmlrpc_strfree(error); } else { ResponseStatus(sessionP, 200); ResponseContentType(sessionP, text ? "text/plain" : "text/html"); addLastModifiedHeader(sessionP, fileModTime); ResponseChunked(sessionP); ResponseWriteStart(sessionP); if (sessionP->requestInfo.method != m_head) sendDirectoryDocument(&list, ascending, sort, text, sessionP->requestInfo.uri, mimeTypeP, sessionP); HTTPWriteEndChunk(sessionP); ListFree(&list); } PoolFree(&pool); } } }
void StreamMsgQueuesDeinit(char quiet) { SCMutexLock(&stream_msg_pool_mutex); PoolFree(stream_msg_pool); SCMutexUnlock(&stream_msg_pool_mutex); #ifdef DEBUG SCMutexDestroy(&stream_pool_memuse_mutex); if (quiet == FALSE) SCLogDebug("stream_pool_memuse %"PRIu64", stream_pool_memcnt %"PRIu64"", stream_pool_memuse, stream_pool_memcnt); #endif }
void uTaskFree( IN void *pMem ) { /* Disable interrupts, allowing pool frees during isr execution */ int PrevState = uTaskInterruptDisable(); /* * Release the pool block, caution if in an isr pool over write * detection cannot print if executing in isr context. */ PoolFree(pMem); /* Restore the interrupt state */ uTaskInterruptRestore(PrevState); }
static void sacClassFlush(SAC sac, Index i, Size blockSize, Count blockCount) { Addr cb, fl; Count j; mps_sac_t esac; esac = ExternalSACOfSAC(sac); for (j = 0, fl = esac->_freelists[i]._blocks; j < blockCount; ++j) { /* @@@@ ignoring shields for now */ cb = fl; fl = *ADDR_PTR(Addr, cb); PoolFree(sac->pool, cb, blockSize); } esac->_freelists[i]._count -= blockCount; esac->_freelists[i]._blocks = fl; }
void PoolThreadFree(PoolThread *pt) { int i; if (pt == NULL) return; if (pt->array != NULL) { for (i = 0; i < (int)pt->size; i++) { PoolThreadElement *e = &pt->array[i]; SCMutexLock(&e->lock); PoolFree(e->pool); SCMutexUnlock(&e->lock); SCMutexDestroy(&e->lock); } SCFree(pt->array); } SCFree(pt); }
void StreamMsgQueuesDeinit(char quiet) { if (quiet == FALSE) { if (stream_msg_pool->max_outstanding > stream_msg_pool->allocated) SCLogInfo("TCP segment chunk pool had a peak use of %u chunks, " "more than the prealloc setting of %u", stream_msg_pool->max_outstanding, stream_msg_pool->allocated); } SCMutexLock(&stream_msg_pool_mutex); PoolFree(stream_msg_pool); SCMutexUnlock(&stream_msg_pool_mutex); #ifdef DEBUG SCMutexDestroy(&stream_pool_memuse_mutex); if (quiet == FALSE) SCLogDebug("stream_pool_memuse %"PRIu64", stream_pool_memcnt %"PRIu64"", stream_pool_memuse, stream_pool_memcnt); #endif }
static int PoolTestInit04 (void) { int retval = 0; char *str = NULL; Pool *p = PoolInit(10,5,PoolTestAllocArg,(void *)"test",PoolTestFree); if (p == NULL) goto end; str = PoolGet(p); if (str == NULL) { printf("PoolGet returned NULL: "); retval = 0; goto end; } if (strcmp(str, "test") != 0) { printf("Memory not properly initialized: "); retval = 0; goto end; } if (p->alloc_list_size != 4) { printf("p->alloc_list_size 4 != %" PRIu32 ": ", p->alloc_list_size); retval = 0; goto end; } if (p->empty_list_size != 6) { printf("p->empty_list_size 6 != %" PRIu32 ": ", p->empty_list_size); retval = 0; goto end; } retval = 1; end: if (str != NULL) SCFree(str); if (p != NULL) PoolFree(p); return retval; }
/* ResizeWindow - change the size of a window, update pContent. * * arguments: * hWnd handle to window to resize * pBox pointer to box to check * * return value: * returns TRUE if window needs repainting * * IMPORTANT : * ResizeWindow does not update the screen. */ FLAG PASCAL INTERNAL ResizeWindow ( HW hWnd, PBOX pBox ) { INT windSize = 0; FitWinToScrn ( pBox ); if (hWnd->win.left == pBox->left && hWnd->win.right == pBox->right && hWnd->win.top == pBox->top && hWnd->win.bottom == pBox->bottom) return FALSE; hWnd->win = *pBox; if (hWnd->pContent != NULL) { windSize = TWINWIDTH (hWnd) * TWINHEIGHT (hWnd) * sizeof(CHAR); if ( (UINT)windSize > hWnd->contSize ) { PoolFree ( hWnd->pContent ); hWnd->pContent = PoolAlloc ( windSize ); hWnd->contSize = windSize; } SendMessage ( hWnd, REGENCONT, NULL ); } return TRUE; }
/* defWndProc - default window proc * * Handles most common operations */ VOID PASCAL INTERNAL defWndProc (HW hWnd, INT command, WDATA data) { INT width = TWINWIDTH (hWnd); INT height = TWINHEIGHT (hWnd); switch (command) { /* Paint a line on the screen. If there's a content area and * the line to be painted is within the screen, output it * from the content area */ case PAINT: if (hWnd->pContent != NULL) if ((INT)data < height) WzTextOut (hWnd, 0, (INT)data, hWnd->pContent + data * width, width, DefNorm); break; case CLOSE: if (hWnd->pContent) PoolFree (hWnd->pContent); break; case DISPLAY: SendMessage (hWnd, DISPLAYSTR, data); SendMessage (hWnd, DISPLAYSTR, strCRLF); break; case DISPLAYSTR: StreamOut ( hWnd, (PSTR) data, strlen ((PSTR) data), DefNorm); break; case REGENCONT: if (hWnd->pContent != NULL) Fill (hWnd->pContent, ' ', height * width); break; default: break; } }
void SACEmpty(SAC sac, Addr p, Size size) { Index i; Size blockSize; mps_sac_t esac; AVERT(SAC, sac); AVER(p != NULL); AVER(PoolHasAddr(sac->pool, p)); AVER(size > 0); esac = ExternalSACOfSAC(sac); sacFind(&i, &blockSize, sac, size); /* Check it's full (in the future, there will be other cases). */ AVER(esac->_freelists[i]._count == esac->_freelists[i]._count_max); /* Adjust size for the overlarge class. */ if (blockSize == SizeMAX) /* see .align */ blockSize = SizeAlignUp(size, PoolAlignment(sac->pool)); if (esac->_freelists[i]._count_max > 0) { Count blockCount; /* Flush 2/3 of the cache for this class. */ /* Computed as count - count/3, so that the rounding works out right. */ blockCount = esac->_freelists[i]._count; blockCount -= esac->_freelists[i]._count / 3; sacClassFlush(sac, i, blockSize, (blockCount > 0) ? blockCount : 1); /* Leave the current one in the cache. */ esac->_freelists[i]._count += 1; /* @@@@ ignoring shields for now */ *ADDR_PTR(Addr, p) = esac->_freelists[i]._blocks; esac->_freelists[i]._blocks = p; } else { /* Free even the current one. */ PoolFree(sac->pool, p, blockSize); } }
static abyss_bool ServerDirectoryHandler(TSession * const r, char * const z, time_t const fileModTime, MIMEType * const mimeTypeP) { TList list; abyss_bool text; abyss_bool ascending; uint16_t sort; /* 1=by name, 2=by date */ TPool pool; TDate date; const char * error; uint16_t responseStatus; TDate dirdate; const char * imsHdr; determineSortType(r->request_info.query, &ascending, &sort, &text, &error); if (error) { ResponseStatus(r,400); xmlrpc_strfree(error); return TRUE; } fileDate(r, fileModTime, &dirdate); imsHdr = RequestHeaderValue(r, "If-Modified-Since"); if (imsHdr) { if (DateDecode(imsHdr, &date)) { if (DateCompare(&dirdate, &date) <= 0) { ResponseStatus(r, 304); ResponseWrite(r); return TRUE; } } } if (!PoolCreate(&pool, 1024)) { ResponseStatus(r, 500); return TRUE; } generateListing(&list, z, r->request_info.uri, &pool, &error, &responseStatus); if (error) { ResponseStatus(r, responseStatus); xmlrpc_strfree(error); PoolFree(&pool); return TRUE; } /* Send something to the user to show that we are still alive */ ResponseStatus(r, 200); ResponseContentType(r, (text ? "text/plain" : "text/html")); if (DateToString(&dirdate, z)) ResponseAddField(r, "Last-Modified", z); ResponseChunked(r); ResponseWrite(r); if (r->request_info.method!=m_head) sendDirectoryDocument(&list, ascending, sort, text, r->request_info.uri, mimeTypeP, r, z); HTTPWriteEndChunk(r); /* Free memory and exit */ ListFree(&list); PoolFree(&pool); return TRUE; }
NTSTATUS Hooked_NtQueryAttributesFile(__in POBJECT_ATTRIBUTES ObjectAttributes, __out PFILE_BASIC_INFORMATION FileInformation) { NTSTATUS statusCall, exceptionCode; ULONG currentProcessId; UNICODE_STRING kObjectName; PWCHAR parameter = NULL; PAGED_CODE(); currentProcessId = (ULONG)PsGetCurrentProcessId(); statusCall = Orig_NtQueryAttributesFile(ObjectAttributes, FileInformation); if(IsProcessInList(currentProcessId, pMonitoredProcessListHead) && (ExGetPreviousMode() != KernelMode)) { Dbg("Call NtQueryAttributesFile\n"); parameter = PoolAlloc(MAX_SIZE * sizeof(WCHAR)); kObjectName.Buffer = NULL; if(NT_SUCCESS(statusCall)) { __try { if(ObjectAttributes != NULL) { ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1); ProbeForRead(ObjectAttributes->ObjectName, sizeof(UNICODE_STRING), 1); ProbeForRead(ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length, 1); kObjectName.Length = ObjectAttributes->ObjectName->Length; kObjectName.MaximumLength = ObjectAttributes->ObjectName->MaximumLength; kObjectName.Buffer = PoolAlloc(kObjectName.MaximumLength); RtlCopyUnicodeString(&kObjectName, ObjectAttributes->ObjectName); } else RtlInitUnicodeString(&kObjectName, L""); } __except(EXCEPTION_EXECUTE_HANDLER) { exceptionCode = GetExceptionCode(); if(parameter && NT_SUCCESS(RtlStringCchPrintfW(parameter, MAX_SIZE, L"0,%d,sss,FileHandle->0,buffer->ERROR,offset->0", exceptionCode))) SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, parameter); else SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, L"0,-1,sss,FileHandle->0,buffer->ERROR,offset->0"); if(parameter != NULL) PoolFree(parameter); return statusCall; } if(wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxMouse.sys") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxGuest.sys") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxSF.sys") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\VBoxVideo.sys") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxControl.exe") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxDisp.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxHook.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxMRXNP.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGL.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLarrayspu.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLcrutil.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLerrorspu.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLfeedbackspu.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLpackspu.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxOGLpassthroughspu.dll") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxService.exe") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\VBoxTray.exe") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\vmmouse.sys") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Windows\\system32\\drivers\\vmhgfs.sys") || wcsistr(kObjectName.Buffer, L"\\??\\C:\\Program Files\\oracle\\virtualbox guest additions\\")) { if(parameter && NT_SUCCESS(RtlStringCchPrintfW(parameter, MAX_SIZE, L"0,-1,s,filepath->%wZ", &kObjectName))) SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, parameter); else SendLogs(currentProcessId, SIG_ntdll_NtQueryAttributesFile, L"0,-1,s,filepath->ERROR"); if(parameter != NULL) PoolFree(parameter); return INVALID_FILE_ATTRIBUTES; } } if(parameter != NULL) PoolFree(parameter); }
static void FreeRtconn( rtconn *ptr) { PoolFree(rtconn_pool, ptr); }
void FreeTcpPair( tcp_pair *ptr) { PoolFree(tcp_pair_pool, ptr); }
void FreeQuadrant( quadrant *ptr) { PoolFree(quadrant_pool, ptr); }
void FreeSegment( segment *ptr) { PoolFree(segment_pool, ptr); }
void FreePtpPtr( ptp_ptr *ptr) { PoolFree(ptp_ptr_pool, ptr); }
void FreePtpSnap( ptp_snap *ptr) { PoolFree(ptp_snap_pool, ptr); }
void FreeSeqspace( seqspace *ptr) { PoolFree(seqspace_pool, ptr); }
void FreeUdpPair( udp_pair *ptr) { PoolFree(udp_pair_pool, ptr); }
/* readProc - handle messages for the read-file window. This function is used * to handle both help windows and read-message windows. * * arguments: * hWnd handle of window receiving message * command command in message * data data peculiar to the command * * return value: * none * */ VOID PASCAL INTERNAL readProc ( HW hWnd, INT command, WDATA data ) { INT width = TWINWIDTH (hWnd); INT height = TWINHEIGHT (hWnd); INT winSize = width *height *sizeof ( CHAR ); INT oldTop; /* Do NOT initialize this here, hWnd->data may be invalid */ INT i; switch ( command ) { case KEY : oldTop = FT->top; switch ( data ) { case HELP : if ( !fHelp ) { fHelp = TRUE; SpecificHlp ( "reading messages" ); } break; case ESC : fAllowCM = FALSE; CloseWindow ( hWnd ); return; case CTRL_P: case UP : FT->top = max ( 0, FT->top - 1 ); break; case CTRL_N: case DOWN : if ( ( FT->llof == -1 ) || ( FT->top < FT->llof - 1 ) ) FT->top++; break; case CTRL_K: case PGUP : FT->top = max ( 0, FT->top - ( height - 1 ) ); break; case CTRL_L: case PGDN : if ( ( FT->llof == -1 ) || ( FT->top + height - 1 < FT->llof ) ) FT->top += height - 1; break; case CTRL_T: case HOME : FT->top = 0; break; case CTRL_B: case END : if ( FT->llof == -1 ) { FT->top = PAGETOLINE (FT->cPages - 1); while ( GrabNextPage ( hWnd ) ) FT->top += PAGELEN; while ( fSkipToLine ( hWnd, FT->top ) ) FT->top++; FT->top = max ( 0, FT->top - ( height - 2 ) ); } else FT->top = FT->llof - 1; break; default : if ( ( *hWnd->keyProc ) ( hWnd, data ) ) return; break; } /* topLine has moved, so decide how to redraw the read window, */ /* if the window was only moved 1 line, scroll it and draw the */ /* new line, otherwise redraw the whole window. */ if ( ( FT->top == oldTop - 1 ) || ( FT->top == oldTop + 1 ) ) { ScrollWindow ( hWnd, 1, FT->top - oldTop ); if ( FT->top - oldTop < 0 ) { SendMessage ( hWnd, REGENCONT, FT->top + 1 ); SendMessage ( hWnd, PAINT, 0 ); } else { SendMessage ( hWnd, REGENCONT, FT->top + height ); SendMessage ( hWnd, PAINT, height - 1 ); } CheckMore ( hWnd ); } else if ( FT->top != oldTop ) { SendMessage ( hWnd, REGENCONT, NULL ); DrawWindow ( hWnd, FALSE ); } #if DEBUG debout ( "Character %x struck", data ); #endif break; case REGENCONT : /* grab line from file and put it in window's content region */ /* data is a pointer to struct pos. if data == NULL, redo */ /* all lines from FT->top to the end of the window */ if ( data != 0 ) LineToCont ( hWnd, data - 1 ); else { Fill ( ( LPSTR ) hWnd->pContent, ' ', winSize ); for ( i = 0; i <= height - 1; i++) SendMessage ( hWnd, REGENCONT, FT->top + i + 1 ); CheckMore ( hWnd ); } break; case CREATE : hWnd->data = data; FT->pages = ( PLONG ) ZMalloc ( PAGEMAX * sizeof ( *FT->pages ) ); FT->pages [ 0 ] = 0L; FT->cPageMax = PAGEMAX; hWnd->pContent = PoolAlloc ( winSize ); hWnd->contSize = winSize; WindLevel++; SendMessage ( hWnd, REOPNFILE, 0 ); break; case REOPNFILE : FT->fhRead = fopen ( FT->fileRead, "r" ); fseek ( FT->fhRead, 0L, 0 ); FT->cur = FT->top = 0; FT->llof = -1; FT->cPages = 1; SendMessage ( hWnd, REGENCONT, NULL ); /* if data != 0 redraw the window too */ if ( data ) { DrawWindow ( hWnd, FALSE ); CheckMore ( hWnd ); } break; case CLOSEFILE : fclose ( FT->fhRead ); break; case CLOSE : fclose ( FT->fhRead ); if ( FT->fDeleteRead ) _unlink ( FT->fileRead ); ZMfree ( FT->fileRead ); ZMfree ( FT->pages ); ZMfree ( FT ); PoolFree ( hWnd->pContent ); fHelp = FALSE; WindLevel--; if ( hWnd == hReadMessage ) hReadMessage = NULL; break; default : defWndProc (hWnd, command, data); break; } }
/** \brief Init a Pool * * PoolInit() creates a ::Pool. The Alloc function must only do * allocation stuff. The Cleanup function must not try to free * the PoolBucket::data. This is done by the ::Pool management * system. * * \param size * \param prealloc_size * \param elt_size Memory size of an element * \param Alloc An allocation function or NULL to use a standard SCMalloc * \param Init An init function or NULL to use a standard memset to 0 * \param InitData Init data * \Param Cleanup a free function or NULL if no special treatment is needed * \retval the allocated Pool */ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(), int (*Init)(void *, void *), void *InitData, void (*Cleanup)(void *)) { Pool *p = NULL; if (size != 0 && prealloc_size > size) goto error; /* setup the filter */ p = SCMalloc(sizeof(Pool)); if (p == NULL) goto error; memset(p,0,sizeof(Pool)); p->max_buckets = size; p->preallocated = prealloc_size; p->elt_size = elt_size; p->data_buffer_size = prealloc_size * elt_size; p->Alloc = Alloc; p->Init = Init; p->InitData = InitData; p->Cleanup = Cleanup; if (p->Init == NULL) { p->Init = PoolMemset; p->InitData = p; } /* alloc the buckets and place them in the empty list */ uint32_t u32 = 0; if (size > 0) { PoolBucket *pb = SCCalloc(size, sizeof(PoolBucket)); p->pb_buffer = pb; if (pb == NULL) goto error; memset(pb, 0, size * sizeof(PoolBucket)); for (u32 = 0; u32 < size; u32++) { /* populate pool */ pb->next = p->empty_list; pb->flags |= POOL_BUCKET_PREALLOCATED; p->empty_list = pb; p->empty_list_size++; pb++; } } p->data_buffer = SCCalloc(prealloc_size, elt_size); /* FIXME better goto */ if (p->data_buffer == NULL) goto error; /* prealloc the buckets and requeue them to the alloc list */ for (u32 = 0; u32 < prealloc_size; u32++) { if (size == 0) { /* unlimited */ PoolBucket *pb = SCMalloc(sizeof(PoolBucket)); if (pb == NULL) goto error; memset(pb, 0, sizeof(PoolBucket)); if (p->Alloc) { pb->data = p->Alloc(); } else { pb->data = SCMalloc(p->elt_size); } if (pb->data == NULL) { SCFree(pb); goto error; } if (p->Init(pb->data, p->InitData) != 1) { if (p->Cleanup) p->Cleanup(pb->data); SCFree(pb->data); SCFree(pb); goto error; } p->allocated++; pb->next = p->alloc_list; p->alloc_list = pb; p->alloc_list_size++; } else { PoolBucket *pb = p->empty_list; if (pb == NULL) goto error; pb->data = (char *)p->data_buffer + u32 * elt_size; if (p->Init(pb->data, p->InitData) != 1) { if (p->Cleanup) p->Cleanup(pb->data); goto error; } p->empty_list = pb->next; p->empty_list_size--; p->allocated++; pb->next = p->alloc_list; p->alloc_list = pb; p->alloc_list_size++; } } return p; error: if (p != NULL) { PoolFree(p); } return NULL; }
/** \test pool with unlimited size */ static int PoolTestInit07 (void) { int retval = 0; void *data = NULL; void *data2 = NULL; Pool *p = PoolInit(0,1,10,PoolTestAlloc,NULL,NULL,PoolTestFree); if (p == NULL) goto end; if (p->max_buckets != 0) { printf("p->max_buckets 0 != %" PRIu32 ": ", p->max_buckets); retval = 0; goto end; } if (p->allocated != 1) { printf("p->allocated 1 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } data = PoolGet(p); if (data == NULL) { printf("PoolGet returned NULL: "); retval = 0; goto end; } if (p->allocated != 1) { printf("(2) p->allocated 1 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } data2 = PoolGet(p); if (data2 == NULL) { printf("PoolGet returned NULL: "); retval = 0; goto end; } if (p->allocated != 2) { printf("(3) p->allocated 2 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } PoolReturn(p,data); data = NULL; if (p->allocated != 2) { printf("(4) p->allocated 2 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } if (p->alloc_list_size != 1) { printf("p->alloc_list_size 1 != %" PRIu32 ": ", p->alloc_list_size); retval = 0; goto end; } PoolReturn(p,data2); data2 = NULL; if (p->allocated != 1) { printf("(5) p->allocated 1 != %" PRIu32 ": ", p->allocated); retval = 0; goto end; } retval = 1; end: if (p != NULL) PoolFree(p); return retval; }