Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pool block alloc #9

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/app-layer-parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,18 @@ FileContainer *AppLayerGetFilesFromFlow(Flow *f, uint8_t direction) {
}

/** \brief Alloc a AppLayerParserResultElmt func for the pool */
static void *AlpResultElmtPoolAlloc(void *null)
static void *AlpResultElmtPoolAlloc(void *null, void *data)
{
AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)SCMalloc
(sizeof(AppLayerParserResultElmt));
if (e == NULL)
return NULL;
AppLayerParserResultElmt *e = NULL;

if (data == NULL) {
e = (AppLayerParserResultElmt *)SCMalloc
(sizeof(AppLayerParserResultElmt));
if (e == NULL)
return NULL;
} else {
e = data;
}

memset(e, 0, sizeof(AppLayerParserResultElmt));

Expand Down Expand Up @@ -1314,7 +1320,9 @@ void RegisterAppLayerParsers(void)

/** setup result pool
* \todo Per thread pool */
al_result_pool = PoolInit(1000,250,AlpResultElmtPoolAlloc,NULL,AlpResultElmtPoolFree);
al_result_pool = PoolInit(1000,250,
sizeof(AppLayerParserResultElmt),
AlpResultElmtPoolAlloc,NULL,AlpResultElmtPoolFree);

RegisterHTPParsers();
RegisterSSLParsers();
Expand Down
28 changes: 19 additions & 9 deletions src/defrag.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,18 @@ DefragFragReset(Frag *frag)
* \brief Allocate a new frag for use in a pool.
*/
static void *
DefragFragNew(void *arg)
DefragFragNew(void *arg, void *data)
{
DefragContext *dc = arg;
Frag *frag;
Frag *frag = NULL;

frag = SCCalloc(1, sizeof(*frag));
if (frag == NULL)
return NULL;
if (data == NULL) {
frag = SCCalloc(1, sizeof(*frag));
if (frag == NULL)
return NULL;
} else {
frag = data;
}
frag->dc = dc;

return (void *)frag;
Expand Down Expand Up @@ -369,14 +373,18 @@ DefragTrackerReset(DefragTracker *tracker)
* \retval A new DefragTracker if successfull, NULL on failure.
*/
static void *
DefragTrackerNew(void *arg)
DefragTrackerNew(void *arg, void *data)
{
DefragContext *dc = arg;
DefragTracker *tracker;

tracker = SCCalloc(1, sizeof(*tracker));
if (tracker == NULL)
return NULL;
if (data == NULL) {
tracker = SCCalloc(1, sizeof(*tracker));
if (tracker == NULL)
return NULL;
} else {
tracker = data;
}
if (SCMutexInit(&tracker->lock, NULL) != 0) {
SCFree(tracker);
return NULL;
Expand Down Expand Up @@ -436,6 +444,7 @@ DefragContextNew(void)
tracker_pool_size = DEFAULT_DEFRAG_HASH_SIZE;
}
dc->tracker_pool = PoolInit(tracker_pool_size, tracker_pool_size,
sizeof(DefragTracker),
DefragTrackerNew, dc, DefragTrackerFree);
if (dc->tracker_pool == NULL) {
SCLogError(SC_ERR_MEM_ALLOC,
Expand All @@ -452,6 +461,7 @@ DefragContextNew(void)
int frag_pool_size = 0xffff;
int frag_pool_prealloc = frag_pool_size / 4;
dc->frag_pool = PoolInit(frag_pool_size, frag_pool_prealloc,
sizeof(Frag),
DefragFragNew, dc, DefragFragFree);
if (dc->frag_pool == NULL) {
SCLogError(SC_ERR_MEM_ALLOC,
Expand Down
15 changes: 11 additions & 4 deletions src/stream-tcp-reassemble.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,22 @@ int StreamTcpReassembleCheckMemcap(uint32_t size) {
}

/** \brief alloc a tcp segment pool entry */
void *TcpSegmentPoolAlloc(void *payload_len) {
void *TcpSegmentPoolAlloc(void *payload_len, void* data) {
if (StreamTcpReassembleCheckMemcap((uint32_t)sizeof(TcpSegment) +
*((uint16_t *) payload_len)) == 0)
{
return NULL;
}

TcpSegment *seg = SCMalloc(sizeof (TcpSegment));
if (seg == NULL)
return NULL;
TcpSegment *seg = NULL;

if (data == NULL) {
seg = SCMalloc(sizeof (TcpSegment));
if (seg == NULL)
return NULL;
} else {
seg = data;
}

memset(seg, 0, sizeof (TcpSegment));

Expand Down Expand Up @@ -276,6 +282,7 @@ int StreamTcpReassembleInit(char quiet)
SCMutexLock(&segment_pool_mutex[u16]);
segment_pool[u16] = PoolInit(segment_pool_poolsizes[u16],
segment_pool_poolsizes_prealloc[u16],
sizeof (TcpSegment),
TcpSegmentPoolAlloc, (void *) &
segment_pool_pktsizes[u16],
TcpSegmentPoolFree);
Expand Down
20 changes: 14 additions & 6 deletions src/stream-tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,16 +245,23 @@ void StreamTcpSessionPktFree (Packet *p)

/** \brief Stream alloc function for the Pool
* \param null NULL ptr (value of null is ignored)
* \param data Pointer to potentially pre-allocated data
* \retval ptr void ptr to TcpSession structure with all vars set to 0/NULL
*/
void *StreamTcpSessionPoolAlloc(void *null)
void *StreamTcpSessionPoolAlloc(void *null, void* data)
{
if (StreamTcpCheckMemcap((uint32_t)sizeof(TcpSession)) == 0)
return NULL;
void *ptr = NULL;

void *ptr = SCMalloc(sizeof(TcpSession));
if (ptr == NULL)
return NULL;
if (data == NULL) {
if (StreamTcpCheckMemcap((uint32_t)sizeof(TcpSession)) == 0)
return NULL;

ptr = SCMalloc(sizeof(TcpSession));
if (ptr == NULL)
return NULL;
} else {
ptr = data;
}

memset(ptr, 0, sizeof(TcpSession));

Expand Down Expand Up @@ -488,6 +495,7 @@ void StreamTcpInitConfig(char quiet)
SCMutexLock(&ssn_pool_mutex);
ssn_pool = PoolInit(stream_config.max_sessions,
stream_config.prealloc_sessions,
sizeof(TcpSession),
StreamTcpSessionPoolAlloc, NULL,
StreamTcpSessionPoolFree);
if (ssn_pool == NULL) {
Expand Down
16 changes: 11 additions & 5 deletions src/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,16 @@ static uint16_t toclient_min_chunk_len = 2560;
static Pool *stream_msg_pool = NULL;
static SCMutex stream_msg_pool_mutex = PTHREAD_MUTEX_INITIALIZER;

void *StreamMsgAlloc(void *null) {
StreamMsg *s = SCMalloc(sizeof(StreamMsg));
if (s == NULL)
return NULL;
void *StreamMsgAlloc(void *null, void *data) {
StreamMsg *s;

if (data == NULL) {
s = SCMalloc(sizeof(StreamMsg));
if (s == NULL)
return NULL;
} else {
s = data;
}

memset(s, 0, sizeof(StreamMsg));

Expand Down Expand Up @@ -159,7 +165,7 @@ void StreamMsgQueuesInit(void) {
SCMutexInit(&stream_pool_memuse_mutex, NULL);
#endif
SCMutexLock(&stream_msg_pool_mutex);
stream_msg_pool = PoolInit(0,250,StreamMsgAlloc,NULL,StreamMsgFree);
stream_msg_pool = PoolInit(0,250,sizeof(StreamMsg),StreamMsgAlloc,NULL,StreamMsgFree);
if (stream_msg_pool == NULL)
exit(EXIT_FAILURE); /* XXX */
SCMutexUnlock(&stream_msg_pool_mutex);
Expand Down
56 changes: 39 additions & 17 deletions src/util-pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include "util-unittest.h"
#include "util-debug.h"

Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), void *AllocData, void (*Free)(void *))
Pool *PoolInit(uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(void *, void*), void *AllocData, void (*Free)(void *))
{
Pool *p = NULL;

Expand All @@ -48,24 +48,34 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
memset(p,0,sizeof(Pool));

p->max_buckets = size;
p->preallocated = prealloc_size;
p->elt_size = elt_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 (size > 0) {
PoolBucket *pb = SCCalloc(size, sizeof(PoolBucket));
p->pb_buffer = pb;
if (pb == NULL)
goto error;

memset(pb, 0, sizeof(PoolBucket));
pb->next = p->empty_list;
p->empty_list = pb;
p->empty_list_size++;
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 */
Expand All @@ -75,7 +85,7 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo

memset(pb, 0, sizeof(PoolBucket));

pb->data = p->Alloc(p->AllocData);
pb->data = p->Alloc(p->AllocData, NULL);
p->allocated++;

pb->next = p->alloc_list;
Expand All @@ -89,7 +99,9 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
p->empty_list = pb->next;
p->empty_list_size--;

pb->data = p->Alloc(p->AllocData);
pb->data = (char *)p->data_buffer + u32 * elt_size;
pb->flags |= POOL_BUCKET_PREALLOCATED_DATA;
p->Alloc(p->AllocData, pb->data);
p->allocated++;

pb->next = p->alloc_list;
Expand All @@ -107,28 +119,38 @@ Pool *PoolInit(uint32_t size, uint32_t prealloc_size, void *(*Alloc)(void *), vo
return NULL;
}


void PoolFree(Pool *p) {
if (p == NULL)
return;

while (p->alloc_list != NULL) {
PoolBucket *pb = p->alloc_list;
p->alloc_list = pb->next;
p->Free(pb->data);
if (! pb->flags & POOL_BUCKET_PREALLOCATED_DATA) {
p->Free(pb->data);
}
pb->data = NULL;
SCFree(pb);
if (! pb->flags & POOL_BUCKET_PREALLOCATED) {
SCFree(pb);
}
}

while (p->empty_list != NULL) {
PoolBucket *pb = p->empty_list;
p->empty_list = pb->next;
if (pb->data!= NULL) {
p->Free(pb->data);
if (pb->data!= NULL) {
if (! pb->flags & POOL_BUCKET_PREALLOCATED_DATA) {
p->Free(pb->data);
}
pb->data = NULL;
}
SCFree(pb);
if (! pb->flags & POOL_BUCKET_PREALLOCATED) {
SCFree(pb);
}
}

SCFree(p->pb_buffer);
SCFree(p);
}

Expand Down Expand Up @@ -160,7 +182,7 @@ void *PoolGet(Pool *p) {
if (p->outstanding > p->max_outstanding)
p->max_outstanding = p->outstanding;

SCReturnPtr(p->Alloc(p->AllocData), "void");
SCReturnPtr(p->Alloc(p->AllocData, NULL), "void");
} else {
SCReturnPtr(NULL, "void");
}
Expand Down
13 changes: 11 additions & 2 deletions src/util-pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,20 @@
#ifndef __UTIL_POOL_H__
#define __UTIL_POOL_H__

#define POOL_BUCKET_PREALLOCATED 1 << 0
#define POOL_BUCKET_PREALLOCATED_DATA 1 << 1

/* pool bucket structure */
typedef struct PoolBucket_ {
void *data;
uint8_t flags;
struct PoolBucket_ *next;
} PoolBucket;

/* pool structure */
typedef struct Pool_ {
uint32_t max_buckets;
uint32_t preallocated;
uint32_t allocated;

PoolBucket *alloc_list;
Expand All @@ -41,16 +46,20 @@ typedef struct Pool_ {
PoolBucket *empty_list;
uint32_t empty_list_size;

void *(*Alloc)(void *);
PoolBucket *pb_buffer;
void *data_buffer;

void *(*Alloc)(void *, void *);
void *AllocData;
void (*Free)(void *);

uint32_t elt_size;
uint32_t outstanding;
uint32_t max_outstanding;
} Pool;

/* prototypes */
Pool* PoolInit(uint32_t, uint32_t, void *(*Alloc)(void *), void *, void (*Free)(void *));
Pool* PoolInit(uint32_t, uint32_t, uint32_t, void *(*Alloc)(void *, void *), void *, void (*Free)(void *));
void PoolFree(Pool *);
void PoolPrint(Pool *);
void PoolPrintSaturation(Pool *p);
Expand Down