toys

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

queue.c (2920B)


      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 	size_t *ptr;
     19 	for (size_t i = 0; i < limit; i++) {
     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 (void *) (sizeof *ptr * limit); // return bytes written
     30 }
     31 
     32 static void *
     33 reader(void *data)
     34 {
     35 	struct spsc_queue *queue = data;
     36 
     37 	size_t *ptr;
     38 	for (size_t i = 0; i < limit; i++) {
     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 (void *) (sizeof *ptr * limit); // return bytes read
     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 	const uint64_t nsecs = 1000000000, usecs = 1000000, msecs = 1000;
     59 	struct timespec start, end;
     60 
     61 	pthread_t writer_thread, reader_thread;
     62 	pthread_create(&reader_thread, NULL, reader, &queue);
     63 	pthread_create(&writer_thread, NULL, writer, &queue);
     64 
     65 	clock_gettime(CLOCK_MONOTONIC_RAW, &start);
     66 
     67 	void *nbytes_written;
     68 	pthread_join(writer_thread, &nbytes_written);
     69 
     70 	void *nbytes_read;
     71 	pthread_join(reader_thread, &nbytes_read);
     72 
     73 	clock_gettime(CLOCK_MONOTONIC_RAW, &end);
     74 
     75 	uint64_t ns = ((end.tv_sec - start.tv_sec) * nsecs) + (end.tv_nsec - start.tv_nsec);
     76 	uint64_t bytes = (uint64_t) nbytes_written + (uint64_t) nbytes_read;
     77 	double gigs = bytes / (double) GiB(1);
     78 
     79 	printf("Iters: %zu\n", limit);
     80 	printf("Elapsed time: ms: %lu, ns: %lu, avg. ns per iter: %lu\n",
     81 			ns / usecs, ns, ns / limit);
     82 
     83 	printf("Ops/sec: %lu, bytes written: %lu, bytes read: %lu, total GiBps: %.03f\n",
     84 			(limit * nsecs) / ns, (uint64_t) nbytes_written, (uint64_t) nbytes_read,
     85 			(float) ((gigs * nsecs) / ns));
     86 }
     87 
     88 int
     89 main(void)
     90 {
     91 	benchmark();
     92 
     93 	return 0;
     94 
     95 	int *foo = mirrormap(NULL, PAGESZ_4K, PAGESZ_4K, 2, PROT_READ | PROT_WRITE);
     96 	int *bar = (void *) ((uintptr_t) foo + PAGESZ_4K);
     97 
     98 	*foo = 42;
     99 	assert(*bar == 42);
    100 
    101 	munmap(foo, 0);
    102 
    103 	struct queue queue;
    104 	int res = queue_init(&queue, PAGESZ_4K, PAGESZ_4K);
    105 	assert(res == 0);
    106 
    107 	assert(queue_length(&queue) == 0);
    108 	assert(queue_capacity(&queue) == PAGESZ_4K);
    109 
    110 	char buf[] = "Hello, World!";
    111 
    112 	char *mydst = queue_write(&queue, sizeof buf);
    113 	assert(mydst);
    114 	queue_write_commit(&queue, sizeof buf);
    115 
    116 	strcpy(mydst, buf);
    117 
    118 	assert(queue_length(&queue) == sizeof buf);
    119 	assert(queue_capacity(&queue) == (PAGESZ_4K - sizeof buf));
    120 
    121 	char *mysrc = queue_read(&queue, sizeof buf);
    122 	assert(mysrc);
    123 	queue_read_commit(&queue, sizeof buf);
    124 
    125 	printf("%s\n", mysrc);
    126 
    127 	assert(queue_length(&queue) == 0);
    128 	assert(queue_capacity(&queue) == PAGESZ_4K);
    129 
    130 	queue_free(&queue);
    131 
    132 	return 0;
    133 }