int main(int argc, char **argv) { (void)argc; (void)argv; int num_producers = NUM_THREADS-1; pthread_t producers[num_producers]; pthread_t consumer; struct timespec start, end; for(int i=0; i<NUM_THREADS; i++) { for(int j=0; j<NUM_ITEMS; j++) { items[i][j].sent = 0; items[i][j].recv = 0; } } int cap = atoi(argv[1]); queue = mpscq_create(NULL, cap); pthread_create(&consumer, NULL, consumer_main, NULL); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); for(long i=0; i<num_producers; i++) { pthread_create(&producers[i], NULL, producer_main, (void *)i); } for(int i=0; i<num_producers; i++) { pthread_join(producers[i], NULL); } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); done = true; pthread_join(consumer, NULL); atomic_thread_fence(memory_order_seq_cst); for(int i=0; i<num_producers; i++) { for(int j=0; j<NUM_ITEMS; j++) { if(items[i][j].sent != 2) { printf(":(%d %d): %d %d, %d %d\n", i, j, items[i][j].sent, items[i][j].recv, amount_produced, amount_consumed); } assert(items[i][j].sent == 2); assert(items[i][j].recv == 1); } } long ms = (end.tv_sec - start.tv_sec) * 1000; ms += (end.tv_nsec - start.tv_nsec) / 1000000; fprintf(stdout, "\t%d\t%ld\t%ld\n", retries, ms, (long)(total / amount_produced)); assert(amount_produced == amount_consumed); exit(amount_produced != amount_consumed); }
int blockdev_register(struct inode *node, struct blockctl *ctl) { struct blockdev *bd = kmalloc(sizeof(struct blockdev)); mutex_create(&ctl->cachelock, 0); hash_create(&ctl->cache, 0, 0x4000); mpscq_create(&ctl->queue, 1000); bd->ctl = ctl; int num = atomic_fetch_add(&next_minor, 1); node->devdata = bd; node->phys_dev = GETDEV(block_major, num); node->kdev = dm_device_get(block_major); kthread_create(&ctl->elevator, "[kelevator]", 0, block_elevator_main, node); char name[64]; snprintf(name, 64, "/dev/bcache-%d", num); kerfs_register_parameter(name, ctl, 0, 0, kerfs_block_cache_report); return num; }