#include "util-validate.h"
#include "action-globals.h"
+extern uint16_t max_pending_packets;
+
/* Number of freed packet to save for one pool before freeing them. */
#define MAX_PENDING_RETURN_PACKETS 32
static uint32_t max_pending_return_packets = MAX_PENDING_RETURN_PACKETS;
return 1;
}
+static void UpdateReturnThreshold(PktPool *pool)
+{
+ const float perc = (float)pool->cnt / (float)max_pending_packets;
+ uint32_t threshold = (uint32_t)(perc * (float)max_pending_return_packets);
+ if (threshold != SC_ATOMIC_GET(pool->return_stack.return_threshold)) {
+ SC_ATOMIC_SET(pool->return_stack.return_threshold, threshold);
+ }
+}
+
void PacketPoolWait(void)
{
PktPool *my_pool = GetThreadPacketPool();
if (PacketPoolIsEmpty(my_pool)) {
+ SC_ATOMIC_SET(my_pool->return_stack.return_threshold, 1);
+
SCMutexLock(&my_pool->return_stack.mutex);
- SC_ATOMIC_ADD(my_pool->return_stack.sync_now, 1);
SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex);
SCMutexUnlock(&my_pool->return_stack.mutex);
+
+ UpdateReturnThreshold(my_pool);
}
while(PacketPoolIsEmpty(my_pool))
/* Move all the packets from the locked return stack to the local stack. */
pool->head = pool->return_stack.head;
pool->return_stack.head = NULL;
+ pool->cnt += pool->return_stack.cnt;
+ pool->return_stack.cnt = 0;
SCMutexUnlock(&pool->return_stack.mutex);
}
/* Stack is not empty. */
Packet *p = pool->head;
pool->head = p->next;
+ pool->cnt--;
p->pool = pool;
PacketReinit(p);
+
+ UpdateReturnThreshold(pool);
+ SCLogDebug("pp: %0.2f cnt:%u max:%d threshold:%u",
+ ((float)pool->cnt / (float)max_pending_packets) * (float)100, pool->cnt,
+ max_pending_packets, SC_ATOMIC_GET(pool->return_stack.return_threshold));
return p;
}
/* Stack is not empty. */
Packet *p = pool->head;
pool->head = p->next;
+ pool->cnt--;
p->pool = pool;
PacketReinit(p);
+
+ UpdateReturnThreshold(pool);
+ SCLogDebug("pp: %0.2f cnt:%u max:%d threshold:%u",
+ ((float)pool->cnt / (float)max_pending_packets) * (float)100, pool->cnt,
+ max_pending_packets, SC_ATOMIC_GET(pool->return_stack.return_threshold));
return p;
}
/* Push back onto this thread's own stack, so no locking. */
p->next = my_pool->head;
my_pool->head = p;
+ my_pool->cnt++;
} else {
PktPool *pending_pool = my_pool->pending_pool;
if (pending_pool == NULL || pending_pool == pool) {
my_pool->pending_count++;
}
- if (SC_ATOMIC_GET(pool->return_stack.sync_now) || my_pool->pending_count > max_pending_return_packets) {
+ const uint32_t threshold = SC_ATOMIC_GET(pool->return_stack.return_threshold);
+ if (my_pool->pending_count >= threshold) {
/* Return the entire list of pending packets. */
SCMutexLock(&pool->return_stack.mutex);
my_pool->pending_tail->next = pool->return_stack.head;
pool->return_stack.head = my_pool->pending_head;
- SC_ATOMIC_RESET(pool->return_stack.sync_now);
+ pool->return_stack.cnt += my_pool->pending_count;
SCCondSignal(&pool->return_stack.cond);
SCMutexUnlock(&pool->return_stack.mutex);
/* Clear the list of pending packets to return. */
SCMutexLock(&pool->return_stack.mutex);
p->next = pool->return_stack.head;
pool->return_stack.head = p;
- SC_ATOMIC_RESET(pool->return_stack.sync_now);
+ pool->return_stack.cnt++;
SCMutexUnlock(&pool->return_stack.mutex);
SCCondSignal(&pool->return_stack.cond);
}
SCMutexInit(&my_pool->return_stack.mutex, NULL);
SCCondInit(&my_pool->return_stack.cond, NULL);
- SC_ATOMIC_INIT(my_pool->return_stack.sync_now);
+ SC_ATOMIC_INIT(my_pool->return_stack.return_threshold);
+ SC_ATOMIC_SET(my_pool->return_stack.return_threshold, 32);
}
void PacketPoolInit(void)
{
- extern uint16_t max_pending_packets;
-
PktPool *my_pool = GetThreadPacketPool();
#ifdef DEBUG_VALIDATION
SCMutexInit(&my_pool->return_stack.mutex, NULL);
SCCondInit(&my_pool->return_stack.cond, NULL);
- SC_ATOMIC_INIT(my_pool->return_stack.sync_now);
+ SC_ATOMIC_INIT(my_pool->return_stack.return_threshold);
+ SC_ATOMIC_SET(my_pool->return_stack.return_threshold, 32);
/* pre allocate packets */
SCLogDebug("preallocating packets... packet size %" PRIuMAX "",