static inline void fq_push_free_message_stack(struct free_message_stack *stack, fq_msg *m) { if (stack == NULL) { return; } while(ck_pr_load_32(&stack->size) > stack->max_size) { ck_stack_entry_t *ce = ck_stack_pop_mpmc(&stack->stack); if (ce != NULL) { fq_msg *m = container_of(ce, fq_msg, cleanup_stack_entry); free(m); ck_pr_dec_32(&stack->size); } else break; } uint32_t c = ck_pr_load_32(&stack->size); if (c >= stack->max_size) { free(m); return; } ck_pr_inc_32(&stack->size); ck_stack_push_mpmc(&stack->stack, &m->cleanup_stack_entry); }
static inline fq_msg * fq_pop_free_message_stack(struct free_message_stack *stack) { fq_msg *rv = NULL; if (stack == NULL) { return rv; } ck_stack_entry_t *ce = ck_stack_pop_mpmc(&stack->stack); if (ce != NULL) { ck_pr_dec_32(&stack->size); rv = container_of(ce, fq_msg, cleanup_stack_entry); } return rv; }
int main(void) { ck_stack_entry_t entry[ENTRIES]; ck_spinlock_fas_t mutex = CK_SPINLOCK_FAS_INITIALIZER; volatile ck_stack_entry_t * volatile r; uint64_t s, e, a; unsigned int i; unsigned int j; a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); s = rdtsc(); for (j = 0; j < ENTRIES; j++) { ck_spinlock_fas_lock(&mutex); ck_stack_push_spnc(&stack, entry + j); ck_spinlock_fas_unlock(&mutex); } e = rdtsc(); a += e - s; } printf(" spinlock_push: %16" PRIu64 "\n", a / STEPS / ENTRIES); a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); for (j = 0; j < ENTRIES; j++) ck_stack_push_spnc(&stack, entry + j); s = rdtsc(); for (j = 0; j < ENTRIES; j++) { ck_spinlock_fas_lock(&mutex); r = ck_stack_pop_npsc(&stack); ck_spinlock_fas_unlock(&mutex); } e = rdtsc(); a += e - s; } printf(" spinlock_pop: %16" PRIu64 "\n", a / STEPS / ENTRIES); r++; #ifdef CK_F_STACK_PUSH_UPMC a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_stack_push_upmc(&stack, entry + j); e = rdtsc(); a += e - s; } printf("ck_stack_push_upmc: %16" PRIu64 "\n", a / STEPS / ENTRIES); #endif /* CK_F_STACK_PUSH_UPMC */ #ifdef CK_F_STACK_PUSH_MPMC a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_stack_push_mpmc(&stack, entry + j); e = rdtsc(); a += e - s; } printf("ck_stack_push_mpmc: %16" PRIu64 "\n", a / STEPS / ENTRIES); #endif /* CK_F_STACK_PUSH_MPMC */ #ifdef CK_F_STACK_PUSH_MPNC a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_stack_push_mpnc(&stack, entry + j); e = rdtsc(); a += e - s; } printf("ck_stack_push_mpnc: %16" PRIu64 "\n", a / STEPS / ENTRIES); #endif /* CK_F_STACK_PUSH_MPNC */ #if defined(CK_F_STACK_PUSH_UPMC) && defined(CK_F_STACK_POP_UPMC) a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); for (j = 0; j < ENTRIES; j++) ck_stack_push_upmc(&stack, entry + j); s = rdtsc(); for (j = 0; j < ENTRIES; j++) r = ck_stack_pop_upmc(&stack); e = rdtsc(); a += e - s; } printf(" ck_stack_pop_upmc: %16" PRIu64 "\n", a / STEPS / (sizeof(entry) / sizeof(*entry))); #endif /* CK_F_STACK_PUSH_UPMC && CK_F_STACK_POP_UPMC */ #if defined(CK_F_STACK_POP_MPMC) && defined(CK_F_STACK_PUSH_MPMC) a = 0; for (i = 0; i < STEPS; i++) { ck_stack_init(&stack); for (j = 0; j < ENTRIES; j++) ck_stack_push_mpmc(&stack, entry + j); s = rdtsc(); for (j = 0; j < ENTRIES; j++) r = ck_stack_pop_mpmc(&stack); e = rdtsc(); a += e - s; } printf(" ck_stack_pop_mpmc: %16" PRIu64 "\n", a / STEPS / (sizeof(entry) / sizeof(*entry))); r++; #endif return 0; }