queue.c (2413B)
1 #define HEADER_IMPL 2 #include "queue.h" 3 4 #include <assert.h> 5 #include <pthread.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <time.h> 9 10 static const size_t limit = 1000000000; 11 static const size_t qsize = PAGESZ_2M; 12 13 static void * 14 writer(void *data) 15 { 16 struct spsc_queue *queue = data; 17 18 for (size_t i = 0; i < limit; i++) { 19 size_t *ptr; 20 do { 21 ptr = spsc_queue_write(queue, sizeof *ptr); 22 } while (!ptr); 23 24 *ptr = i; 25 26 spsc_queue_write_commit(queue, sizeof *ptr); 27 } 28 29 return NULL; 30 } 31 32 static void * 33 reader(void *data) 34 { 35 struct spsc_queue *queue = data; 36 37 for (size_t i = 0; i < limit; i++) { 38 size_t *ptr; 39 do { 40 ptr = spsc_queue_read(queue, sizeof *ptr); 41 } while (!ptr); 42 43 ASSERT(*ptr == i); 44 45 spsc_queue_read_commit(queue, sizeof *ptr); 46 } 47 48 return NULL; 49 } 50 51 static void 52 benchmark(void) 53 { 54 struct spsc_queue queue; 55 int res = spsc_queue_init(&queue, qsize, qsize); 56 assert(res == 0); 57 58 struct timespec start, end; 59 60 pthread_t writer_thread, reader_thread; 61 pthread_create(&reader_thread, NULL, reader, &queue); 62 pthread_create(&writer_thread, NULL, writer, &queue); 63 64 clock_gettime(CLOCK_MONOTONIC_RAW, &start); 65 66 pthread_join(writer_thread, NULL); 67 pthread_join(reader_thread, NULL); 68 69 clock_gettime(CLOCK_MONOTONIC_RAW, &end); 70 71 uint64_t ns = ((end.tv_sec - start.tv_sec) * 1000000000) + (end.tv_nsec - start.tv_nsec); 72 73 printf("Iters: %zu\n", limit); 74 printf("Elapsed time: ms: %lu, ns: %lu\n", ns / 1000000, ns); 75 printf("Ops/sec: %lu\n", (limit * 1000000000) / ns); 76 } 77 78 int 79 main(void) 80 { 81 benchmark(); 82 83 return 0; 84 85 int *foo = mirrormap(NULL, PAGESZ_4K, PAGESZ_4K, 2, PROT_READ | PROT_WRITE); 86 int *bar = (void *) ((uintptr_t) foo + PAGESZ_4K); 87 88 *foo = 42; 89 assert(*bar == 42); 90 91 munmap(foo, 0); 92 93 struct queue queue; 94 int res = queue_init(&queue, PAGESZ_4K, PAGESZ_4K); 95 assert(res == 0); 96 97 assert(queue_length(&queue) == 0); 98 assert(queue_capacity(&queue) == PAGESZ_4K); 99 100 char buf[] = "Hello, World!"; 101 102 char *mydst = queue_write(&queue, sizeof buf); 103 assert(mydst); 104 queue_write_commit(&queue, sizeof buf); 105 106 strcpy(mydst, buf); 107 108 assert(queue_length(&queue) == sizeof buf); 109 assert(queue_capacity(&queue) == (PAGESZ_4K - sizeof buf)); 110 111 char *mysrc = queue_read(&queue, sizeof buf); 112 assert(mysrc); 113 queue_read_commit(&queue, sizeof buf); 114 115 printf("%s\n", mysrc); 116 117 assert(queue_length(&queue) == 0); 118 assert(queue_capacity(&queue) == PAGESZ_4K); 119 120 queue_free(&queue); 121 122 return 0; 123 }