String::String( Pool& p ) { buf = (char*)p.Alloc(); bufLen = p.ItemBufLen(); dataLen = 0; disposer = &p; buf[ 0 ] = '\0'; }
String::String( Pool& p, char const* _buf, int _dataLen ) { assert( p.ItemBufLen() - ( int )sizeof( Pool* ) >= _dataLen + 1 ); buf = (char*)p.Alloc(); bufLen = p.ItemBufLen(); dataLen = _dataLen; disposer = &p; memcpy( buf, _buf, _dataLen ); buf[ _dataLen ] = '\0'; }
/** \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; }
Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), void *AllocData, void (*Free)(void *)) { Pool *p = NULL; if (Alloc == NULL) { //printf("ERROR: PoolInit no Hash function\n"); goto error; } 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->Alloc = Alloc; p->AllocData = AllocData; p->Free = Free; /* alloc the buckets and place them in the empty list */ uint32_t u32 = 0; for (u32 = 0; u32 < size; u32++) { /* populate pool */ PoolBucket *pb = SCMalloc(sizeof(PoolBucket)); if (pb == NULL) goto error; memset(pb, 0, sizeof(PoolBucket)); pb->next = p->empty_list; p->empty_list = pb; p->empty_list_size++; } /* 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)); pb->data = p->Alloc(p->AllocData); 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; p->empty_list = pb->next; p->empty_list_size--; pb->data = p->Alloc(p->AllocData); p->allocated++; pb->next = p->alloc_list; p->alloc_list = pb; p->alloc_list_size++; } } return p; error: /* XXX */ return NULL; }