static void ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context) { (void)context; ck_spinlock_fas_lock(lock); return; }
static CK_CC_INLINE void rwlock_write_lock(rwlock_t *rw) { ck_spinlock_fas_lock(&rw->writer); while (ck_pr_load_uint(&rw->readers) != 0) ck_pr_stall(); return; }
void ck_barrier_combining_group_init(struct ck_barrier_combining *root, struct ck_barrier_combining_group *tnode, unsigned int nthr) { struct ck_barrier_combining_group *node; struct ck_barrier_combining_queue queue; queue.head = queue.tail = NULL; tnode->k = nthr; tnode->count = 0; tnode->sense = 0; tnode->left = tnode->right = NULL; /* * Finds the first available node for linkage into the combining * tree. The use of a spinlock is excusable as this is a one-time * initialization cost. */ ck_spinlock_fas_lock(&root->mutex); ck_barrier_combining_queue_enqueue(&queue, root->root); while (queue.head != NULL) { node = ck_barrier_combining_queue_dequeue(&queue); /* If the left child is free, link the group there. */ if (node->left == NULL) { ck_barrier_combining_insert(node, tnode, &node->left); goto leave; } /* If the right child is free, link the group there. */ if (node->right == NULL) { ck_barrier_combining_insert(node, tnode, &node->right); goto leave; } /* * If unsuccessful, try inserting as a child of the children of the * current node. */ ck_barrier_combining_queue_enqueue(&queue, node->left); ck_barrier_combining_queue_enqueue(&queue, node->right); } leave: ck_spinlock_fas_unlock(&root->mutex); return; }
int main(void) { ck_spinlock_fas_t mutex = CK_SPINLOCK_FAS_INITIALIZER; void *r; uint64_t s, e, a; unsigned int i; unsigned int j; #if defined(CK_F_FIFO_SPSC) ck_fifo_spsc_t spsc_fifo; ck_fifo_spsc_entry_t spsc_entry[ENTRIES]; ck_fifo_spsc_entry_t spsc_stub; #endif #if defined(CK_F_FIFO_MPMC) ck_fifo_mpmc_t mpmc_fifo; ck_fifo_mpmc_entry_t mpmc_entry[ENTRIES]; ck_fifo_mpmc_entry_t mpmc_stub; ck_fifo_mpmc_entry_t *garbage; #endif #ifdef CK_F_FIFO_SPSC a = 0; for (i = 0; i < STEPS; i++) { ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); s = rdtsc(); for (j = 0; j < ENTRIES; j++) { ck_spinlock_fas_lock(&mutex); ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); ck_spinlock_fas_unlock(&mutex); } e = rdtsc(); a += e - s; } printf(" spinlock_enqueue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); a = 0; for (i = 0; i < STEPS; i++) { ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); for (j = 0; j < ENTRIES; j++) ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); s = rdtsc(); for (j = 0; j < ENTRIES; j++) { ck_spinlock_fas_lock(&mutex); ck_fifo_spsc_dequeue(&spsc_fifo, &r); ck_spinlock_fas_unlock(&mutex); } e = rdtsc(); a += e - s; } printf(" spinlock_dequeue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); a = 0; for (i = 0; i < STEPS; i++) { ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); e = rdtsc(); a += e - s; } printf("ck_fifo_spsc_enqueue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); a = 0; for (i = 0; i < STEPS; i++) { ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); for (j = 0; j < ENTRIES; j++) ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_fifo_spsc_dequeue(&spsc_fifo, &r); e = rdtsc(); a += e - s; } printf("ck_fifo_spsc_dequeue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); #endif #ifdef CK_F_FIFO_MPMC a = 0; for (i = 0; i < STEPS; i++) { ck_fifo_mpmc_init(&mpmc_fifo, &mpmc_stub); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_fifo_mpmc_enqueue(&mpmc_fifo, mpmc_entry + j, NULL); e = rdtsc(); a += e - s; } printf("ck_fifo_mpmc_enqueue: %16" PRIu64 "\n", a / STEPS / (sizeof(mpmc_entry) / sizeof(*mpmc_entry))); a = 0; for (i = 0; i < STEPS; i++) { ck_fifo_mpmc_init(&mpmc_fifo, &mpmc_stub); for (j = 0; j < ENTRIES; j++) ck_fifo_mpmc_enqueue(&mpmc_fifo, mpmc_entry + j, NULL); s = rdtsc(); for (j = 0; j < ENTRIES; j++) ck_fifo_mpmc_dequeue(&mpmc_fifo, &r, &garbage); e = rdtsc(); a += e - s; } printf("ck_fifo_mpmc_dequeue: %16" PRIu64 "\n", a / STEPS / (sizeof(mpmc_entry) / sizeof(*mpmc_entry))); #endif return 0; }
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; }