toys

toys.git
git clone git://git.lenczewski.org/toys.git
Log | Files | Refs | README | LICENSE

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 }