static void * test(void *c) { struct context *context = c; struct entry *entry; ck_fifo_spsc_entry_t *fifo_entry; int i, j; if (aff_iterate(&a)) { perror("ERROR: Could not affine thread"); exit(EXIT_FAILURE); } #ifdef DEBUG fprintf(stderr, "%p %u: %u -> %u\n", fifo+context->tid, context->tid, context->previous, context->tid); #endif if (context->tid == 0) { struct entry *entries; entries = malloc(sizeof(struct entry) * size); assert(entries != NULL); for (i = 0; i < size; i++) { entries[i].value = i; entries[i].tid = 0; fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entries + i); } } ck_pr_inc_uint(&barrier); while (ck_pr_load_uint(&barrier) < (unsigned int)nthr); for (i = 0; i < ITERATIONS; i++) { for (j = 0; j < size; j++) { while (ck_fifo_spsc_dequeue(fifo + context->previous, &entry) == false); if (context->previous != (unsigned int)entry->tid) { ck_error("T [%u:%p] %u != %u\n", context->tid, (void *)entry, entry->tid, context->previous); } if (entry->value != j) { ck_error("V [%u:%p] %u != %u\n", context->tid, (void *)entry, entry->value, j); } entry->tid = context->tid; fifo_entry = ck_fifo_spsc_recycle(fifo + context->tid); if (fifo_entry == NULL) fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entry); } } return (NULL); }
static void fqd_queue_message_process(remote_data_client *me, fq_msg *msg) { ck_fifo_spsc_t *work_queue = NULL; ck_fifo_spsc_entry_t *entry = NULL; int i = 0, tindex = 0; uint32_t blmin = UINT_MAX; struct incoming_message *m = malloc(sizeof(struct incoming_message)); m->client = me; m->msg = msg; /* while we live in this queue, we ref the client so it can't be destroyed until the queue is cleared of it */ fqd_remote_client_ref((remote_client *) m->client); /* find the least loaded queue */ for ( ; i < worker_thread_count; i++) { uint32_t x = work_queue_backlogs[i]; if (x < blmin) { blmin = x; tindex = i; } } ck_pr_inc_32(&work_queue_backlogs[tindex]); work_queue = &work_queues[tindex]; entry = ck_fifo_spsc_recycle(work_queue); if (entry == NULL) { entry = malloc(sizeof(ck_fifo_spsc_entry_t)); } ck_fifo_spsc_enqueue(work_queue, entry, m); }
static void fq_client_signal(fq_client conn, cmd_instr *e) { fq_conn_s *conn_s = conn; ck_fifo_spsc_enqueue_lock(&conn_s->cmdq); ck_fifo_spsc_entry_t *fifo_entry = ck_fifo_spsc_recycle(&conn_s->cmdq); if (fifo_entry == NULL) { fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); } ck_fifo_spsc_enqueue(&conn_s->cmdq, fifo_entry, e); ck_fifo_spsc_enqueue_unlock(&conn_s->cmdq); }
static void enqueue_cmd_hook_req(fq_conn_s *conn_s, cmd_instr *e) { ck_fifo_spsc_enqueue_lock(&conn_s->backq); ck_fifo_spsc_entry_t *fifo_entry = ck_fifo_spsc_recycle(&conn_s->backq); if (unlikely(fifo_entry == NULL)) { fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); } hook_req_t *hreq = calloc(1,sizeof(*hreq)); hreq->type = CMD_HOOK_TYPE; hreq->entry = e; ck_fifo_spsc_enqueue(&conn_s->backq, fifo_entry, MARKED_HOOK_REQ_PTR(hreq)); ck_fifo_spsc_enqueue_unlock(&conn_s->backq); }
static void enqueue_auth_hook_req(fq_conn_s *conn_s, int rv) { ck_fifo_spsc_enqueue_lock(&conn_s->backq); ck_fifo_spsc_entry_t *fifo_entry = ck_fifo_spsc_recycle(&conn_s->backq); if (unlikely(fifo_entry == NULL)) { fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); } hook_req_t *hreq = calloc(1,sizeof(*hreq)); hreq->type = AUTH_HOOK_TYPE; hreq->entry = calloc(1, sizeof(*hreq->entry)); hreq->entry->data.return_value = 0; ck_fifo_spsc_enqueue(&conn_s->backq, fifo_entry, MARKED_HOOK_REQ_PTR(hreq)); ck_fifo_spsc_enqueue_unlock(&conn_s->backq); }
static void fq_client_read_complete(void *closure, fq_msg *msg) { fq_conn_s *conn_s = (fq_conn_s *)closure; if(conn_s->message_hook && conn_s->message_hook(conn_s, msg)) { fq_msg_deref(msg); } else { ck_fifo_spsc_enqueue_lock(&conn_s->backq); ck_fifo_spsc_entry_t *fifo_entry = ck_fifo_spsc_recycle(&conn_s->backq); if (unlikely(fifo_entry == NULL)) { fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); } ck_fifo_spsc_enqueue(&conn_s->backq, fifo_entry, msg); ck_fifo_spsc_enqueue_unlock(&conn_s->backq); } }
static void distribute_message_with_interests(caql_cnt_t *interests, noit_metric_message_t *message) { mtev_atomic_inc64(&number_of_messages_received); int i; for(i = 0; i < nthreads; i++) { if(interests[i] > 0) { ck_fifo_spsc_t *fifo = (ck_fifo_spsc_t *) thread_queues[i]; ck_fifo_spsc_entry_t *fifo_entry; ck_fifo_spsc_enqueue_lock(fifo); fifo_entry = ck_fifo_spsc_recycle(fifo); if(!fifo_entry) fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); noit_metric_director_message_ref(message); ck_fifo_spsc_enqueue(fifo, fifo_entry, message); ck_fifo_spsc_enqueue_unlock(fifo); mtev_atomic_inc64(&number_of_messages_distributed); } } }
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; }