diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-07-23 11:24:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-07-23 11:24:09 +0000 |
commit | e36b37583bebd229102f46c4ed7d2f6fad8697d4 (patch) | |
tree | 73937b6f051fcaaa1ccbdfbaa9f3a1f36bbedb9e /regressions/ck_fifo | |
parent | Initial commit. (diff) | |
download | ck-e36b37583bebd229102f46c4ed7d2f6fad8697d4.tar.xz ck-e36b37583bebd229102f46c4ed7d2f6fad8697d4.zip |
Adding upstream version 0.6.0.upstream/0.6.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'regressions/ck_fifo')
-rw-r--r-- | regressions/ck_fifo/benchmark/Makefile | 14 | ||||
-rw-r--r-- | regressions/ck_fifo/benchmark/latency.c | 157 | ||||
-rw-r--r-- | regressions/ck_fifo/validate/Makefile | 29 | ||||
-rw-r--r-- | regressions/ck_fifo/validate/ck_fifo_mpmc.c | 168 | ||||
-rw-r--r-- | regressions/ck_fifo/validate/ck_fifo_mpmc_iterator.c | 90 | ||||
-rw-r--r-- | regressions/ck_fifo/validate/ck_fifo_spsc.c | 177 | ||||
-rw-r--r-- | regressions/ck_fifo/validate/ck_fifo_spsc_iterator.c | 83 |
7 files changed, 718 insertions, 0 deletions
diff --git a/regressions/ck_fifo/benchmark/Makefile b/regressions/ck_fifo/benchmark/Makefile new file mode 100644 index 0000000..6e2df2a --- /dev/null +++ b/regressions/ck_fifo/benchmark/Makefile @@ -0,0 +1,14 @@ +.PHONY: clean distribution + +OBJECTS=latency + +all: $(OBJECTS) + +latency: latency.c + $(CC) $(CFLAGS) -o latency latency.c + +clean: + rm -rf *~ *.o *.dSYM *.exe $(OBJECTS) + +include ../../../build/regressions.build +CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_fifo/benchmark/latency.c b/regressions/ck_fifo/benchmark/latency.c new file mode 100644 index 0000000..267452f --- /dev/null +++ b/regressions/ck_fifo/benchmark/latency.c @@ -0,0 +1,157 @@ +/* + * Copyright 2011-2015 Samy Al Bahra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <ck_fifo.h> +#include <ck_spinlock.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> + +#include "../../common.h" + +#ifndef ENTRIES +#define ENTRIES 4096 +#endif + +#ifndef STEPS +#define STEPS 40000 +#endif + +int +main(void) +{ + ck_spinlock_fas_t mutex = CK_SPINLOCK_FAS_INITIALIZER; + void *r; + uint64_t s, e, a; + unsigned int i; + unsigned int j; + +#if defined(CK_F_FIFO_SPSC) + ck_fifo_spsc_t spsc_fifo; + ck_fifo_spsc_entry_t spsc_entry[ENTRIES]; + ck_fifo_spsc_entry_t spsc_stub; +#endif + +#if defined(CK_F_FIFO_MPMC) + ck_fifo_mpmc_t mpmc_fifo; + ck_fifo_mpmc_entry_t mpmc_entry[ENTRIES]; + ck_fifo_mpmc_entry_t mpmc_stub; + ck_fifo_mpmc_entry_t *garbage; +#endif + +#ifdef CK_F_FIFO_SPSC + a = 0; + for (i = 0; i < STEPS; i++) { + ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); + + s = rdtsc(); + for (j = 0; j < ENTRIES; j++) { + ck_spinlock_fas_lock(&mutex); + ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); + ck_spinlock_fas_unlock(&mutex); + } + e = rdtsc(); + + a += e - s; + } + printf(" spinlock_enqueue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); + + a = 0; + for (i = 0; i < STEPS; i++) { + ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); + for (j = 0; j < ENTRIES; j++) + ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); + + s = rdtsc(); + for (j = 0; j < ENTRIES; j++) { + ck_spinlock_fas_lock(&mutex); + ck_fifo_spsc_dequeue(&spsc_fifo, &r); + ck_spinlock_fas_unlock(&mutex); + } + e = rdtsc(); + a += e - s; + } + printf(" spinlock_dequeue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); + + a = 0; + for (i = 0; i < STEPS; i++) { + ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); + + s = rdtsc(); + for (j = 0; j < ENTRIES; j++) + ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); + e = rdtsc(); + + a += e - s; + } + printf("ck_fifo_spsc_enqueue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); + + a = 0; + for (i = 0; i < STEPS; i++) { + ck_fifo_spsc_init(&spsc_fifo, &spsc_stub); + for (j = 0; j < ENTRIES; j++) + ck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL); + + s = rdtsc(); + for (j = 0; j < ENTRIES; j++) + ck_fifo_spsc_dequeue(&spsc_fifo, &r); + e = rdtsc(); + a += e - s; + } + printf("ck_fifo_spsc_dequeue: %16" PRIu64 "\n", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry))); +#endif + +#ifdef CK_F_FIFO_MPMC + a = 0; + for (i = 0; i < STEPS; i++) { + ck_fifo_mpmc_init(&mpmc_fifo, &mpmc_stub); + + s = rdtsc(); + for (j = 0; j < ENTRIES; j++) + ck_fifo_mpmc_enqueue(&mpmc_fifo, mpmc_entry + j, NULL); + e = rdtsc(); + + a += e - s; + } + printf("ck_fifo_mpmc_enqueue: %16" PRIu64 "\n", a / STEPS / (sizeof(mpmc_entry) / sizeof(*mpmc_entry))); + + a = 0; + for (i = 0; i < STEPS; i++) { + ck_fifo_mpmc_init(&mpmc_fifo, &mpmc_stub); + for (j = 0; j < ENTRIES; j++) + ck_fifo_mpmc_enqueue(&mpmc_fifo, mpmc_entry + j, NULL); + + s = rdtsc(); + for (j = 0; j < ENTRIES; j++) + ck_fifo_mpmc_dequeue(&mpmc_fifo, &r, &garbage); + e = rdtsc(); + a += e - s; + } + printf("ck_fifo_mpmc_dequeue: %16" PRIu64 "\n", a / STEPS / (sizeof(mpmc_entry) / sizeof(*mpmc_entry))); +#endif + + return 0; +} diff --git a/regressions/ck_fifo/validate/Makefile b/regressions/ck_fifo/validate/Makefile new file mode 100644 index 0000000..6bfc696 --- /dev/null +++ b/regressions/ck_fifo/validate/Makefile @@ -0,0 +1,29 @@ +.PHONY: check clean distribution + +OBJECTS=ck_fifo_spsc ck_fifo_mpmc ck_fifo_spsc_iterator ck_fifo_mpmc_iterator + +all: $(OBJECTS) + +check: all + ./ck_fifo_spsc $(CORES) 1 64000 + ./ck_fifo_mpmc $(CORES) 1 16000 + ./ck_fifo_spsc_iterator + ./ck_fifo_mpmc_iterator + +ck_fifo_spsc: ck_fifo_spsc.c ../../../include/ck_fifo.h + $(CC) $(CFLAGS) -o ck_fifo_spsc ck_fifo_spsc.c + +ck_fifo_mpmc: ck_fifo_mpmc.c ../../../include/ck_fifo.h + $(CC) $(CFLAGS) -o ck_fifo_mpmc ck_fifo_mpmc.c + +ck_fifo_spsc_iterator: ck_fifo_spsc_iterator.c ../../../include/ck_fifo.h + $(CC) $(CFLAGS) -o ck_fifo_spsc_iterator ck_fifo_spsc_iterator.c + +ck_fifo_mpmc_iterator: ck_fifo_mpmc_iterator.c ../../../include/ck_fifo.h + $(CC) $(CFLAGS) -o ck_fifo_mpmc_iterator ck_fifo_mpmc_iterator.c + +clean: + rm -rf *.dSYM *.exe *~ *.o $(OBJECTS) + +include ../../../build/regressions.build +CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE diff --git a/regressions/ck_fifo/validate/ck_fifo_mpmc.c b/regressions/ck_fifo/validate/ck_fifo_mpmc.c new file mode 100644 index 0000000..89eb2f4 --- /dev/null +++ b/regressions/ck_fifo/validate/ck_fifo_mpmc.c @@ -0,0 +1,168 @@ +/* + * Copyright 2011-2015 Samy Al Bahra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> +#include <ck_fifo.h> + +#include "../../common.h" + +#ifdef CK_F_FIFO_MPMC +#ifndef ITERATIONS +#define ITERATIONS 128 +#endif + +struct context { + unsigned int tid; + unsigned int previous; + unsigned int next; +}; + +struct entry { + int tid; + int value; +}; + +static int nthr; + +#ifdef CK_F_FIFO_MPMC +static ck_fifo_mpmc_t fifo CK_CC_CACHELINE; +#endif + +static struct affinity a; +static int size; +static unsigned int barrier; + +static void * +test(void *c) +{ +#ifdef CK_F_FIFO_MPMC + struct context *context = c; + struct entry *entry; + ck_fifo_mpmc_entry_t *fifo_entry, *garbage; + int i, j; + + if (aff_iterate(&a)) { + perror("ERROR: Could not affine thread"); + exit(EXIT_FAILURE); + } + + ck_pr_inc_uint(&barrier); + while (ck_pr_load_uint(&barrier) < (unsigned int)nthr); + + for (i = 0; i < ITERATIONS; i++) { + for (j = 0; j < size; j++) { + fifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t)); + entry = malloc(sizeof(struct entry)); + entry->tid = context->tid; + ck_fifo_mpmc_enqueue(&fifo, fifo_entry, entry); + if (ck_fifo_mpmc_dequeue(&fifo, &entry, &garbage) == false) { + ck_error("ERROR [%u] Queue should never be empty.\n", context->tid); + } + + if (entry->tid < 0 || entry->tid >= nthr) { + ck_error("ERROR [%u] Incorrect value in entry.\n", entry->tid); + } + } + } + + for (i = 0; i < ITERATIONS; i++) { + for (j = 0; j < size; j++) { + fifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t)); + entry = malloc(sizeof(struct entry)); + entry->tid = context->tid; + while (ck_fifo_mpmc_tryenqueue(&fifo, fifo_entry, entry) == false) + ck_pr_stall(); + + while (ck_fifo_mpmc_trydequeue(&fifo, &entry, &garbage) == false) + ck_pr_stall(); + + if (entry->tid < 0 || entry->tid >= nthr) { + ck_error("ERROR [%u] Incorrect value in entry when using try interface.\n", entry->tid); + } + } + } +#endif + + return (NULL); +} + +int +main(int argc, char *argv[]) +{ + int i, r; + struct context *context; + ck_fifo_mpmc_entry_t *garbage; + pthread_t *thread; + + if (argc != 4) { + ck_error("Usage: validate <threads> <affinity delta> <size>\n"); + } + + a.request = 0; + a.delta = atoi(argv[2]); + + nthr = atoi(argv[1]); + assert(nthr >= 1); + + size = atoi(argv[3]); + assert(size > 0); + + context = malloc(sizeof(*context) * nthr); + assert(context); + + thread = malloc(sizeof(pthread_t) * nthr); + assert(thread); + + ck_fifo_mpmc_init(&fifo, malloc(sizeof(ck_fifo_mpmc_entry_t))); + ck_fifo_mpmc_deinit(&fifo, &garbage); + if (garbage == NULL) + ck_error("ERROR: Expected non-NULL stub node on deinit.\n"); + free(garbage); + ck_fifo_mpmc_init(&fifo, malloc(sizeof(ck_fifo_mpmc_entry_t))); + + for (i = 0; i < nthr; i++) { + context[i].tid = i; + r = pthread_create(thread + i, NULL, test, context + i); + assert(r == 0); + } + + for (i = 0; i < nthr; i++) + pthread_join(thread[i], NULL); + + return (0); +} +#else +int +main(void) +{ + fprintf(stderr, "Unsupported.\n"); + return 0; +} +#endif + diff --git a/regressions/ck_fifo/validate/ck_fifo_mpmc_iterator.c b/regressions/ck_fifo/validate/ck_fifo_mpmc_iterator.c new file mode 100644 index 0000000..5ac8175 --- /dev/null +++ b/regressions/ck_fifo/validate/ck_fifo_mpmc_iterator.c @@ -0,0 +1,90 @@ +/* + * Copyright 2011 David Joseph. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <ck_fifo.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +#ifdef CK_F_FIFO_MPMC +struct example { + int x; +}; + +static ck_fifo_mpmc_t mpmc_fifo; + +int +main(void) +{ + int i, length = 3; + struct example *examples; + ck_fifo_mpmc_entry_t *stub, *entries, *entry, *next; + + stub = malloc(sizeof(ck_fifo_mpmc_entry_t)); + if (stub == NULL) + exit(EXIT_FAILURE); + + ck_fifo_mpmc_init(&mpmc_fifo, stub); + + entries = malloc(sizeof(ck_fifo_mpmc_entry_t) * length); + if (entries == NULL) + exit(EXIT_FAILURE); + + examples = malloc(sizeof(struct example) * length); + /* Need these for this unit test. */ + if (examples == NULL) + exit(EXIT_FAILURE); + + for (i = 0; i < length; ++i) { + examples[i].x = i; + ck_fifo_mpmc_enqueue(&mpmc_fifo, entries + i, examples + i); + } + + puts("Testing CK_FIFO_MPMC_FOREACH."); + CK_FIFO_MPMC_FOREACH(&mpmc_fifo, entry) { + printf("Next value in fifo: %d\n", ((struct example *)entry->value)->x); + } + + puts("Testing CK_FIFO_MPMC_FOREACH_SAFE."); + CK_FIFO_MPMC_FOREACH_SAFE(&mpmc_fifo, entry, next) { + if (entry->next.pointer != next) + exit(EXIT_FAILURE); + printf("Next value in fifo: %d\n", ((struct example *)entry->value)->x); + } + + free(examples); + free(entries); + free(stub); + + return (0); +} +#else +int +main(void) +{ + return (0); +} +#endif diff --git a/regressions/ck_fifo/validate/ck_fifo_spsc.c b/regressions/ck_fifo/validate/ck_fifo_spsc.c new file mode 100644 index 0000000..3d6c38c --- /dev/null +++ b/regressions/ck_fifo/validate/ck_fifo_spsc.c @@ -0,0 +1,177 @@ +/* + * Copyright 2011-2015 Samy Al Bahra. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> + +#include <ck_fifo.h> + +#include "../../common.h" + +#ifndef ITERATIONS +#define ITERATIONS 128 +#endif + +struct context { + unsigned int tid; + unsigned int previous; + unsigned int next; +}; + +struct entry { + int tid; + int value; +}; + +static int nthr; +static ck_fifo_spsc_t *fifo; +static struct affinity a; +static int size; +static unsigned int barrier; + +static void * +test(void *c) +{ + struct context *context = c; + struct entry *entry; + ck_fifo_spsc_entry_t *fifo_entry; + int i, j; + + if (aff_iterate(&a)) { + perror("ERROR: Could not affine thread"); + exit(EXIT_FAILURE); + } + +#ifdef DEBUG + fprintf(stderr, "%p %u: %u -> %u\n", fifo+context->tid, context->tid, context->previous, context->tid); +#endif + + if (context->tid == 0) { + struct entry *entries; + + entries = malloc(sizeof(struct entry) * size); + assert(entries != NULL); + + for (i = 0; i < size; i++) { + entries[i].value = i; + entries[i].tid = 0; + + fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); + ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entries + i); + } + } + + ck_pr_inc_uint(&barrier); + while (ck_pr_load_uint(&barrier) < (unsigned int)nthr); + + for (i = 0; i < ITERATIONS; i++) { + for (j = 0; j < size; j++) { + while (ck_fifo_spsc_dequeue(fifo + context->previous, &entry) == false); + if (context->previous != (unsigned int)entry->tid) { + ck_error("T [%u:%p] %u != %u\n", + context->tid, (void *)entry, entry->tid, context->previous); + } + + if (entry->value != j) { + ck_error("V [%u:%p] %u != %u\n", + context->tid, (void *)entry, entry->value, j); + } + + entry->tid = context->tid; + fifo_entry = ck_fifo_spsc_recycle(fifo + context->tid); + if (fifo_entry == NULL) + fifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t)); + + ck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entry); + } + } + + return (NULL); +} + +int +main(int argc, char *argv[]) +{ + int i, r; + struct context *context; + pthread_t *thread; + + if (argc != 4) { + ck_error("Usage: validate <threads> <affinity delta> <size>\n"); + } + + a.request = 0; + a.delta = atoi(argv[2]); + + nthr = atoi(argv[1]); + assert(nthr >= 1); + + size = atoi(argv[3]); + assert(size > 0); + + fifo = malloc(sizeof(ck_fifo_spsc_t) * nthr); + assert(fifo); + + context = malloc(sizeof(*context) * nthr); + assert(context); + + thread = malloc(sizeof(pthread_t) * nthr); + assert(thread); + + for (i = 0; i < nthr; i++) { + ck_fifo_spsc_entry_t *garbage; + + context[i].tid = i; + if (i == 0) { + context[i].previous = nthr - 1; + context[i].next = i + 1; + } else if (i == nthr - 1) { + context[i].next = 0; + context[i].previous = i - 1; + } else { + context[i].next = i + 1; + context[i].previous = i - 1; + } + + ck_fifo_spsc_init(fifo + i, malloc(sizeof(ck_fifo_spsc_entry_t))); + ck_fifo_spsc_deinit(fifo + i, &garbage); + if (garbage == NULL) + ck_error("ERROR: Expected non-NULL stub node on deinit.\n"); + + free(garbage); + ck_fifo_spsc_init(fifo + i, malloc(sizeof(ck_fifo_spsc_entry_t))); + r = pthread_create(thread + i, NULL, test, context + i); + assert(r == 0); + } + + for (i = 0; i < nthr; i++) + pthread_join(thread[i], NULL); + + return (0); +} + diff --git a/regressions/ck_fifo/validate/ck_fifo_spsc_iterator.c b/regressions/ck_fifo/validate/ck_fifo_spsc_iterator.c new file mode 100644 index 0000000..97804de --- /dev/null +++ b/regressions/ck_fifo/validate/ck_fifo_spsc_iterator.c @@ -0,0 +1,83 @@ +/* + * Copyright 2011 David Joseph. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <ck_fifo.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +struct example { + int x; +}; + +static ck_fifo_spsc_t spsc_fifo; + +int +main(void) +{ + int i, length = 3; + struct example *examples; + ck_fifo_spsc_entry_t *stub, *entries, *entry, *next; + + stub = malloc(sizeof(ck_fifo_spsc_entry_t)); + if (stub == NULL) + exit(EXIT_FAILURE); + + ck_fifo_spsc_init(&spsc_fifo, stub); + + entries = malloc(sizeof(ck_fifo_spsc_entry_t) * length); + if (entries == NULL) + exit(EXIT_FAILURE); + + examples = malloc(sizeof(struct example) * length); + /* Need these for this unit test. */ + if (examples == NULL) + exit(EXIT_FAILURE); + + for (i = 0; i < length; ++i) { + examples[i].x = i; + ck_fifo_spsc_enqueue(&spsc_fifo, entries + i, examples + i); + } + + puts("Testing CK_FIFO_SPSC_FOREACH."); + CK_FIFO_SPSC_FOREACH(&spsc_fifo, entry) { + printf("Next value in fifo: %d\n", ((struct example *)entry->value)->x); + } + + puts("Testing CK_FIFO_SPSC_FOREACH_SAFE."); + CK_FIFO_SPSC_FOREACH_SAFE(&spsc_fifo, entry, next) { + if (entry->next != next) + exit(EXIT_FAILURE); + printf("Next value in fifo: %d\n", ((struct example *)entry->value)->x); + } + + free(examples); + free(entries); + free(stub); + + return (0); +} + |