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 ph_thread_t *ph_thread_init_myself(bool booting) { ph_thread_t *me; ck_epoch_record_t *er; er = ck_epoch_recycle(&misc_epoch); if (er) { me = ph_container_of(er, ph_thread_t, epoch_record); } else { me = calloc(1, sizeof(*me)); if (!me) { ph_panic("fatal OOM in ph_thread_init_myself()"); } ck_epoch_register(&misc_epoch, &me->epoch_record); ck_stack_push_mpmc(&ph_thread_all_threads, &me->thread_linkage); ph_counter_init_thread(me); } #ifdef HAVE___THREAD __ph_thread_self = me; #endif pthread_setspecific(__ph_thread_key, me); PH_STAILQ_INIT(&me->pending_nbio); PH_STAILQ_INIT(&me->pending_pool); me->tid = ck_pr_faa_32(&next_tid, 1); me->thr = pthread_self(); #ifdef __sun__ me->lwpid = _lwp_self(); #endif #if defined(__linux__) || defined(__MACH__) // see if we can discover our thread name from the system pthread_getname_np(me->thr, me->name, sizeof(me->name)); #endif // If we were recycled from a non-phenom thread, and are initializing // a non-phenom thread, it is possible that there are still deferred // items to reap in this record, so get them now. if (er && !booting) { ck_epoch_barrier(&misc_epoch, &me->epoch_record); } return me; }
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; }