#define _GNU_SOURCE #include #include #include #include #include #define ARRAY_SIZE 64 #define MAX_VALUE 0x10000 struct spa_ringbuffer rb; uint8_t *data; static int fill_int_array (int *array, int start, int count) { int i, j = start; for (i = 0; i < count; i++) { array[i] = j; j = (j + 1) % MAX_VALUE; } return j; } static int cmp_array (int *array1, int *array2, int count) { int i; for (i = 0; i < count; i++) if (array1[i] != array2[i]) { printf("%d != %d at offset %d\n", array1[i], array2[i], i); return 0; } return 1; } static void * reader_start (void * arg) { int i = 0, a[ARRAY_SIZE], b[ARRAY_SIZE]; unsigned long j = 0, nfailures = 0; printf("reader started on cpu: %d\n", sched_getcpu()); i = fill_int_array (a, i, ARRAY_SIZE); while (1) { uint32_t index; if (spa_ringbuffer_get_read_index (&rb, &index) >= ARRAY_SIZE * sizeof (int)) { spa_ringbuffer_read_data (&rb, data, index & rb.mask, b, ARRAY_SIZE * sizeof (int)); if (!cmp_array (a, b, ARRAY_SIZE)) { nfailures++; printf("failure in chunk %lu - probability: %lu/%lu = %.3f per million\n", j, nfailures, j, (float) nfailures / (j + 1) * 1000000); i = (b[0] + ARRAY_SIZE) % MAX_VALUE; } i = fill_int_array (a, i, ARRAY_SIZE); j++; spa_ringbuffer_read_update (&rb, index + ARRAY_SIZE * sizeof (int)); } } return NULL; } static void * writer_start (void * arg) { int i = 0, a[ARRAY_SIZE]; printf("writer started on cpu: %d\n", sched_getcpu()); i = fill_int_array (a, i, ARRAY_SIZE); while (1) { uint32_t index; if (spa_ringbuffer_get_write_index (&rb, &index) >= ARRAY_SIZE * sizeof (int)) { spa_ringbuffer_write_data (&rb, data, index & rb.mask, a, ARRAY_SIZE * sizeof (int)); spa_ringbuffer_write_update (&rb, index + ARRAY_SIZE * sizeof (int)); i = fill_int_array (a, i, ARRAY_SIZE); } } return NULL; } int main(int argc, char *argv[]) { int size; printf("starting ringbuffer stress test\n"); sscanf(argv[1], "%d", &size); printf("buffer size (bytes): %d\n", size); printf("array size (bytes): %ld\n", sizeof(int) * ARRAY_SIZE); spa_ringbuffer_init (&rb, size); data = malloc (size); pthread_t reader_thread, writer_thread; pthread_create (&reader_thread, NULL, reader_start, NULL); pthread_create (&writer_thread, NULL, writer_start, NULL); while (1) sleep(1); return 0; }