You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by so...@apache.org on 2014/08/01 22:44:17 UTC
[04/20] TS-2950: Initial commit of libck.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_ring/validate/ck_ring_spsc.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_ring/validate/ck_ring_spsc.c b/lib/ck/regressions/ck_ring/validate/ck_ring_spsc.c
new file mode 100644
index 0000000..b107c3c
--- /dev/null
+++ b/lib/ck/regressions/ck_ring/validate/ck_ring_spsc.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2011-2014 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_barrier.h>
+#include <ck_ring.h>
+#include "../../common.h"
+
+#ifndef ITERATIONS
+#define ITERATIONS 128
+#endif
+
+struct context {
+ unsigned int tid;
+ unsigned int previous;
+ unsigned int next;
+ void *buffer;
+};
+
+struct entry {
+ int tid;
+ int value;
+};
+
+static int nthr;
+static ck_ring_t *ring;
+static struct affinity a;
+static int size;
+static ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;
+static struct context *_context;
+
+static void *
+test(void *c)
+{
+ struct context *context = c;
+ struct entry *entry;
+ unsigned int s;
+ int i, j;
+ bool r;
+ ck_barrier_centralized_state_t sense =
+ CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;
+ ck_ring_buffer_t *buffer;
+
+ if (aff_iterate(&a)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ buffer = context->buffer;
+ if (context->tid == 0) {
+ struct entry *entries;
+
+ entries = malloc(sizeof(struct entry) * size);
+ assert(entries != NULL);
+
+ if (ck_ring_size(ring) != 0) {
+ ck_error("More entries than expected: %u > 0\n",
+ ck_ring_size(ring));
+ }
+
+ for (i = 0; i < size; i++) {
+ entries[i].value = i;
+ entries[i].tid = 0;
+
+ if (i & 1) {
+ r = ck_ring_enqueue_spsc(ring, buffer,
+ entries + i);
+ } else {
+ r = ck_ring_enqueue_spsc_size(ring,
+ buffer, entries + i, &s);
+
+ if ((int)s != i) {
+ ck_error("Size is %u, expected %d\n",
+ s, i + 1);
+ }
+ }
+
+ assert(r != false);
+ }
+
+ if (ck_ring_size(ring) != (unsigned int)size) {
+ ck_error("Less entries than expected: %u < %d\n",
+ ck_ring_size(ring), size);
+ }
+
+ if (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) {
+ ck_error("Capacity less than expected: %u < %u\n",
+ ck_ring_size(ring), ck_ring_capacity(ring));
+ }
+ }
+
+ ck_barrier_centralized(&barrier, &sense, nthr);
+
+ for (i = 0; i < ITERATIONS; i++) {
+ for (j = 0; j < size; j++) {
+ buffer = _context[context->previous].buffer;
+ while (ck_ring_dequeue_spsc(ring + context->previous,
+ buffer, &entry) == false);
+
+ if (context->previous != (unsigned int)entry->tid) {
+ ck_error("[%u:%p] %u != %u\n",
+ context->tid, (void *)entry, entry->tid, context->previous);
+ }
+
+ if (entry->value != j) {
+ ck_error("[%u:%p] %u != %u\n",
+ context->tid, (void *)entry, entry->tid, context->previous);
+ }
+
+ entry->tid = context->tid;
+ buffer = context->buffer;
+ if (i & 1) {
+ r = ck_ring_enqueue_spsc(ring + context->tid,
+ buffer, entry);
+ } else {
+ r = ck_ring_enqueue_spsc_size(ring +
+ context->tid, buffer, entry, &s);
+
+ if ((int)s >= size) {
+ ck_error("Size %u is out of range %d\n",
+ s, size);
+ }
+ }
+ assert(r == true);
+ }
+ }
+
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i, r;
+ ck_ring_buffer_t *buffer;
+ 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 >= 4 && (size & size - 1) == 0);
+ size -= 1;
+
+ ring = malloc(sizeof(ck_ring_t) * nthr);
+ assert(ring);
+
+ _context = malloc(sizeof(*_context) * nthr);
+ assert(_context);
+
+ thread = malloc(sizeof(pthread_t) * nthr);
+ assert(thread);
+
+ for (i = 0; i < nthr; i++) {
+ _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;
+ }
+
+ buffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));
+ assert(buffer);
+ _context[i].buffer = buffer;
+ ck_ring_init(ring + i, size + 1);
+ 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);
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/benchmark/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/benchmark/Makefile b/lib/ck/regressions/ck_rwcohort/benchmark/Makefile
new file mode 100644
index 0000000..054c85c
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/benchmark/Makefile
@@ -0,0 +1,32 @@
+.PHONY: clean distribution
+
+OBJECTS=latency throughput
+OBJECTS=ck_neutral.THROUGHPUT ck_neutral.LATENCY \
+ ck_rp.THROUGHPUT ck_rp.LATENCY \
+ ck_wp.THROUGHPUT ck_wp.LATENCY
+
+all: $(OBJECTS)
+
+ck_neutral.THROUGHPUT: ck_neutral.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_neutral.THROUGHPUT ck_neutral.c
+
+ck_neutral.LATENCY: ck_neutral.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_neutral.LATENCY ck_neutral.c
+
+ck_rp.THROUGHPUT: ck_rp.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_rp.THROUGHPUT ck_rp.c
+
+ck_rp.LATENCY: ck_rp.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_rp.LATENCY ck_rp.c
+
+ck_wp.THROUGHPUT: ck_wp.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_wp.THROUGHPUT ck_wp.c
+
+ck_wp.LATENCY: ck_wp.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_wp.LATENCY ck_wp.c
+
+clean:
+ rm -rf *.dSYM *~ *.o $(OBJECTS)
+
+include ../../../build/regressions.build
+CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/benchmark/ck_neutral.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/benchmark/ck_neutral.c b/lib/ck/regressions/ck_rwcohort/benchmark/ck_neutral.c
new file mode 100644
index 0000000..9fb85db
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/benchmark/ck_neutral.c
@@ -0,0 +1,7 @@
+#include "../ck_neutral.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/benchmark/ck_rp.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/benchmark/ck_rp.c b/lib/ck/regressions/ck_rwcohort/benchmark/ck_rp.c
new file mode 100644
index 0000000..798e578
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/benchmark/ck_rp.c
@@ -0,0 +1,7 @@
+#include "../ck_rp.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/benchmark/ck_wp.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/benchmark/ck_wp.c b/lib/ck/regressions/ck_rwcohort/benchmark/ck_wp.c
new file mode 100644
index 0000000..07b0cce
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/benchmark/ck_wp.c
@@ -0,0 +1,7 @@
+#include "../ck_wp.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/benchmark/latency.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/benchmark/latency.h b/lib/ck/regressions/ck_rwcohort/benchmark/latency.h
new file mode 100644
index 0000000..42c323a
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/benchmark/latency.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2013-2014 Samy Al Bahra.
+ * Copyright 2013 Brendon Scheinman.
+ * 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_rwcohort.h>
+#include <ck_spinlock.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#include "../../common.h"
+
+#ifndef STEPS
+#define STEPS 1000000
+#endif
+
+static void
+ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+ (void)context;
+ ck_spinlock_fas_lock(lock);
+}
+
+static void
+ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+ (void)context;
+ ck_spinlock_fas_unlock(lock);
+}
+
+static bool
+ck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+ (void)context;
+ return ck_spinlock_fas_locked(lock);
+}
+
+CK_COHORT_PROTOTYPE(fas_fas,
+ ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,
+ ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)
+LOCK_PROTOTYPE(fas_fas)
+
+int
+main(void)
+{
+ uint64_t s_b, e_b, i;
+ ck_spinlock_fas_t global_lock = CK_SPINLOCK_FAS_INITIALIZER;
+ ck_spinlock_fas_t local_lock = CK_SPINLOCK_FAS_INITIALIZER;
+ CK_COHORT_INSTANCE(fas_fas) cohort = CK_COHORT_INITIALIZER;
+ LOCK_INSTANCE(fas_fas) rw_cohort = LOCK_INITIALIZER;
+
+ CK_COHORT_INIT(fas_fas, &cohort, &global_lock, &local_lock,
+ CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);
+ LOCK_INIT(fas_fas, &rw_cohort, CK_RWCOHORT_WP_DEFAULT_WAIT_LIMIT);
+
+ for (i = 0; i < STEPS; i++) {
+ WRITE_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ WRITE_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ WRITE_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ WRITE_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ }
+ e_b = rdtsc();
+ printf("WRITE: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+
+ for (i = 0; i < STEPS; i++) {
+ READ_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ READ_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);
+ }
+ e_b = rdtsc();
+ printf("READ: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+
+ return (0);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/benchmark/throughput.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/benchmark/throughput.h b/lib/ck/regressions/ck_rwcohort/benchmark/throughput.h
new file mode 100644
index 0000000..55b91a0
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/benchmark/throughput.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2013-2014 Samy Al Bahra.
+ * Copyright 2013 Brendon Scheinman.
+ * 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_cohort.h>
+#include <ck_rwcohort.h>
+#include <ck_spinlock.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../../common.h"
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+#ifndef STEPS
+#define STEPS 1000000
+#endif
+
+static unsigned int barrier;
+static unsigned int flag CK_CC_CACHELINE;
+static struct affinity affinity;
+static unsigned int nthr;
+
+static void
+ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+
+ (void)context;
+ ck_spinlock_fas_lock(lock);
+ return;
+}
+
+static void
+ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+
+ (void)context;
+ ck_spinlock_fas_unlock(lock);
+ return;
+}
+
+static bool
+ck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+
+ (void)context;
+ return ck_spinlock_fas_locked(lock);
+}
+
+CK_COHORT_PROTOTYPE(fas_fas,
+ ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,
+ ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)
+LOCK_PROTOTYPE(fas_fas)
+
+struct cohort_record {
+ CK_COHORT_INSTANCE(fas_fas) cohort;
+} CK_CC_CACHELINE;
+static struct cohort_record *cohorts;
+
+static ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;
+static LOCK_INSTANCE(fas_fas) rw_cohort = LOCK_INITIALIZER;
+static unsigned int n_cohorts;
+
+struct block {
+ unsigned int tid;
+};
+
+static void *
+thread_rwlock(void *pun)
+{
+ uint64_t s_b, e_b, a, i;
+ uint64_t *value = pun;
+ CK_COHORT_INSTANCE(fas_fas) *cohort;
+ unsigned int core;
+
+ if (aff_iterate_core(&affinity, &core) != 0) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ cohort = &((cohorts + (core / (int)(affinity.delta)) % n_cohorts)->cohort);
+
+ ck_pr_inc_uint(&barrier);
+ while (ck_pr_load_uint(&barrier) != nthr)
+ ck_pr_stall();
+
+ for (i = 1, a = 0;; i++) {
+ s_b = rdtsc();
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ e_b = rdtsc();
+
+ a += (e_b - s_b) >> 4;
+
+ if (ck_pr_load_uint(&flag) == 1)
+ break;
+ }
+
+ ck_pr_inc_uint(&barrier);
+ while (ck_pr_load_uint(&barrier) != nthr * 2)
+ ck_pr_stall();
+
+ *value = (a / i);
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ unsigned int i;
+ pthread_t *threads;
+ uint64_t *latency;
+ struct block *context;
+ ck_spinlock_fas_t *local_lock;
+
+ if (argc != 4) {
+ ck_error("Usage: throughput <number of cohorts> <threads per cohort> <affinity delta>\n");
+ }
+
+ n_cohorts = atoi(argv[1]);
+ if (n_cohorts <= 0) {
+ ck_error("ERROR: Number of cohorts must be greater than 0\n");
+ }
+
+ nthr = n_cohorts * atoi(argv[2]);
+ if (nthr <= 0) {
+ ck_error("ERROR: Number of threads must be greater than 0\n");
+ }
+
+ threads = malloc(sizeof(pthread_t) * nthr);
+ if (threads == NULL) {
+ ck_error("ERROR: Could not allocate thread structures\n");
+ }
+
+ cohorts = malloc(sizeof(struct cohort_record) * n_cohorts);
+ if (cohorts == NULL) {
+ ck_error("ERROR: Could not allocate cohort structures\n");
+ }
+
+ context = malloc(sizeof(struct block) * nthr);
+ if (context == NULL) {
+ ck_error("ERROR: Could not allocate thread contexts\n");
+ }
+
+ affinity.delta = atoi(argv[3]);
+ affinity.request = 0;
+
+ latency = malloc(sizeof(*latency) * nthr);
+ if (latency == NULL) {
+ ck_error("ERROR: Could not create latency buffer\n");
+ }
+ memset(latency, 0, sizeof(*latency) * nthr);
+
+ fprintf(stderr, "Creating cohorts...");
+ for (i = 0 ; i < n_cohorts ; i++) {
+ local_lock = malloc(max(CK_MD_CACHELINE, sizeof(ck_spinlock_fas_t)));
+ if (local_lock == NULL) {
+ ck_error("ERROR: Could not allocate local lock\n");
+ }
+ CK_COHORT_INIT(fas_fas, &((cohorts + i)->cohort), &global_lock, local_lock,
+ CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);
+ local_lock = NULL;
+ }
+ fprintf(stderr, "done\n");
+
+ fprintf(stderr, "Creating threads (rwlock)...");
+ for (i = 0; i < nthr; i++) {
+ if (pthread_create(&threads[i], NULL, thread_rwlock, latency + i) != 0) {
+ ck_error("ERROR: Could not create thread %d\n", i);
+ }
+ }
+ fprintf(stderr, "done\n");
+
+ common_sleep(10);
+ ck_pr_store_uint(&flag, 1);
+
+ fprintf(stderr, "Waiting for threads to finish acquisition regression...");
+ for (i = 0; i < nthr; i++)
+ pthread_join(threads[i], NULL);
+ fprintf(stderr, "done\n\n");
+
+ for (i = 1; i <= nthr; i++)
+ printf("%10u %20" PRIu64 "\n", i, latency[i - 1]);
+
+ return (0);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/ck_neutral.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/ck_neutral.h b/lib/ck/regressions/ck_rwcohort/ck_neutral.h
new file mode 100644
index 0000000..dbbda9d
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/ck_neutral.h
@@ -0,0 +1,8 @@
+#define LOCK_PROTOTYPE CK_RWCOHORT_NEUTRAL_PROTOTYPE
+#define LOCK_INSTANCE CK_RWCOHORT_NEUTRAL_INSTANCE
+#define LOCK_INITIALIZER CK_RWCOHORT_NEUTRAL_INITIALIZER
+#define LOCK_INIT(N, C, W) CK_RWCOHORT_NEUTRAL_INIT(N, C)
+#define READ_LOCK CK_RWCOHORT_NEUTRAL_READ_LOCK
+#define WRITE_LOCK CK_RWCOHORT_NEUTRAL_WRITE_LOCK
+#define READ_UNLOCK CK_RWCOHORT_NEUTRAL_READ_UNLOCK
+#define WRITE_UNLOCK CK_RWCOHORT_NEUTRAL_WRITE_UNLOCK
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/ck_rp.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/ck_rp.h b/lib/ck/regressions/ck_rwcohort/ck_rp.h
new file mode 100644
index 0000000..e20f3d2
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/ck_rp.h
@@ -0,0 +1,8 @@
+#define LOCK_PROTOTYPE CK_RWCOHORT_RP_PROTOTYPE
+#define LOCK_INSTANCE CK_RWCOHORT_RP_INSTANCE
+#define LOCK_INITIALIZER CK_RWCOHORT_RP_INITIALIZER
+#define LOCK_INIT CK_RWCOHORT_RP_INIT
+#define READ_LOCK CK_RWCOHORT_RP_READ_LOCK
+#define READ_UNLOCK CK_RWCOHORT_RP_READ_UNLOCK
+#define WRITE_LOCK CK_RWCOHORT_RP_WRITE_LOCK
+#define WRITE_UNLOCK CK_RWCOHORT_RP_WRITE_UNLOCK
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/ck_wp.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/ck_wp.h b/lib/ck/regressions/ck_rwcohort/ck_wp.h
new file mode 100644
index 0000000..556c7df
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/ck_wp.h
@@ -0,0 +1,8 @@
+#define LOCK_PROTOTYPE CK_RWCOHORT_WP_PROTOTYPE
+#define LOCK_INSTANCE CK_RWCOHORT_WP_INSTANCE
+#define LOCK_INITIALIZER CK_RWCOHORT_WP_INITIALIZER
+#define LOCK_INIT CK_RWCOHORT_WP_INIT
+#define READ_LOCK CK_RWCOHORT_WP_READ_LOCK
+#define WRITE_LOCK CK_RWCOHORT_WP_WRITE_LOCK
+#define READ_UNLOCK CK_RWCOHORT_WP_READ_UNLOCK
+#define WRITE_UNLOCK CK_RWCOHORT_WP_WRITE_UNLOCK
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/validate/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/validate/Makefile b/lib/ck/regressions/ck_rwcohort/validate/Makefile
new file mode 100644
index 0000000..33e3a29
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/validate/Makefile
@@ -0,0 +1,25 @@
+.PHONY: check clean distribution
+
+OBJECTS=ck_neutral ck_rp ck_wp
+
+all: $(OBJECTS)
+
+ck_neutral: ck_neutral.c ../../../include/ck_rwcohort.h
+ $(CC) $(CFLAGS) -o ck_neutral ck_neutral.c
+
+ck_rp: ck_rp.c ../../../include/ck_rwcohort.h
+ $(CC) $(CFLAGS) -o ck_rp ck_rp.c
+
+ck_wp: ck_wp.c ../../../include/ck_rwcohort.h
+ $(CC) $(CFLAGS) -o ck_wp ck_wp.c
+
+check: all
+ ./ck_neutral `expr $(CORES) / 2` 2 1
+ ./ck_rp `expr $(CORES) / 2` 2 1
+ ./ck_wp `expr $(CORES) / 2` 2 1
+
+clean:
+ rm -rf *.dSYM *~ *.o $(OBJECTS)
+
+include ../../../build/regressions.build
+CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/validate/ck_neutral.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/validate/ck_neutral.c b/lib/ck/regressions/ck_rwcohort/validate/ck_neutral.c
new file mode 100644
index 0000000..7884dc5
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/validate/ck_neutral.c
@@ -0,0 +1,2 @@
+#include "../ck_neutral.h"
+#include "validate.h"
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/validate/ck_rp.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/validate/ck_rp.c b/lib/ck/regressions/ck_rwcohort/validate/ck_rp.c
new file mode 100644
index 0000000..d63e9d5
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/validate/ck_rp.c
@@ -0,0 +1,2 @@
+#include "../ck_rp.h"
+#include "validate.h"
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/validate/ck_wp.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/validate/ck_wp.c b/lib/ck/regressions/ck_rwcohort/validate/ck_wp.c
new file mode 100644
index 0000000..f89be35
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/validate/ck_wp.c
@@ -0,0 +1,2 @@
+#include "../ck_wp.h"
+#include "validate.h"
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwcohort/validate/validate.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwcohort/validate/validate.h b/lib/ck/regressions/ck_rwcohort/validate/validate.h
new file mode 100644
index 0000000..5aefa8a
--- /dev/null
+++ b/lib/ck/regressions/ck_rwcohort/validate/validate.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2013-2014 Samy Al Bahra.
+ * Copything 2013 Brendon Scheinman.
+ * 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 <errno.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <ck_pr.h>
+#include <ck_rwcohort.h>
+#include <ck_spinlock.h>
+
+#include "../../common.h"
+
+#ifndef ITERATE
+#define ITERATE 1000000
+#endif
+
+
+static struct affinity a;
+static unsigned int locked;
+static int nthr;
+static ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;
+
+static void
+ck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+ (void)context;
+ ck_spinlock_fas_lock(lock);
+}
+
+static void
+ck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+ (void)context;
+ ck_spinlock_fas_unlock(lock);
+}
+
+static bool
+ck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)
+{
+ (void)context;
+ return ck_spinlock_fas_locked(lock);
+}
+
+CK_COHORT_PROTOTYPE(fas_fas,
+ ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,
+ ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)
+LOCK_PROTOTYPE(fas_fas)
+
+static CK_COHORT_INSTANCE(fas_fas) *cohorts;
+static LOCK_INSTANCE(fas_fas) rw_cohort = LOCK_INITIALIZER;
+static int n_cohorts;
+
+static void *
+thread(void *null CK_CC_UNUSED)
+{
+ int i = ITERATE;
+ unsigned int l;
+ unsigned int core;
+ CK_COHORT_INSTANCE(fas_fas) *cohort;
+
+ if (aff_iterate_core(&a, &core)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ cohort = cohorts + (core / (int)(a.delta)) % n_cohorts;
+
+ while (i--) {
+ WRITE_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 8) {
+ ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
+ }
+
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ WRITE_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+
+ READ_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ READ_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);
+ }
+
+ return (NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *threads;
+ int threads_per_cohort;
+ ck_spinlock_fas_t *local_lock;
+ int i;
+
+ if (argc != 4) {
+ ck_error("Usage: validate <number of cohorts> <threads per cohort> <affinity delta>\n");
+ }
+
+ n_cohorts = atoi(argv[1]);
+ if (n_cohorts <= 0) {
+ ck_error("ERROR: Number of cohorts must be greater than 0\n");
+ }
+
+ threads_per_cohort = atoi(argv[2]);
+ if (threads_per_cohort <= 0) {
+ ck_error("ERROR: Threads per cohort must be greater than 0\n");
+ }
+
+ nthr = n_cohorts * threads_per_cohort;
+
+ threads = malloc(sizeof(pthread_t) * nthr);
+ if (threads == NULL) {
+ ck_error("ERROR: Could not allocate thread structures\n");
+ }
+
+ a.delta = atoi(argv[3]);
+
+ fprintf(stderr, "Creating cohorts...");
+ cohorts = malloc(sizeof(CK_COHORT_INSTANCE(fas_fas)) * n_cohorts);
+ if (cohorts == NULL) {
+ ck_error("ERROR: Could not allocate base cohort structures\n");
+ }
+ for (i = 0 ; i < n_cohorts ; i++) {
+ local_lock = malloc(sizeof(ck_spinlock_fas_t));
+ CK_COHORT_INIT(fas_fas, cohorts + i, &global_fas_lock, local_lock,
+ CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);
+ }
+ fprintf(stderr, "done\n");
+
+ fprintf(stderr, "Creating threads...");
+ for (i = 0; i < nthr; i++) {
+ if (pthread_create(&threads[i], NULL, thread, NULL)) {
+ ck_error("ERROR: Could not create thread %d\n", i);
+ }
+ }
+ fprintf(stderr, "done\n");
+
+ fprintf(stderr, "Waiting for threads to finish correctness regression...");
+ for (i = 0; i < nthr; i++)
+ pthread_join(threads[i], NULL);
+ fprintf(stderr, "done (passed)\n");
+
+ return (0);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwlock/benchmark/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwlock/benchmark/Makefile b/lib/ck/regressions/ck_rwlock/benchmark/Makefile
new file mode 100644
index 0000000..ed63504
--- /dev/null
+++ b/lib/ck/regressions/ck_rwlock/benchmark/Makefile
@@ -0,0 +1,17 @@
+.PHONY: clean distribution
+
+OBJECTS=latency throughput
+
+all: $(OBJECTS)
+
+latency: latency.c ../../../include/ck_rwlock.h ../../../include/ck_elide.h
+ $(CC) $(CFLAGS) -o latency latency.c
+
+throughput: throughput.c ../../../include/ck_rwlock.h ../../../include/ck_elide.h
+ $(CC) $(CFLAGS) -o throughput throughput.c
+
+clean:
+ rm -rf *.dSYM *.exe *~ *.o $(OBJECTS)
+
+include ../../../build/regressions.build
+CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwlock/benchmark/latency.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwlock/benchmark/latency.c b/lib/ck/regressions/ck_rwlock/benchmark/latency.c
new file mode 100644
index 0000000..34dc406
--- /dev/null
+++ b/lib/ck/regressions/ck_rwlock/benchmark/latency.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2011-2014 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_rwlock.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#include "../../common.h"
+
+#define CK_F_PR_RTM
+
+#ifndef STEPS
+#define STEPS 2000000
+#endif
+
+int
+main(void)
+{
+ uint64_t s_b, e_b, i;
+ ck_rwlock_t rwlock = CK_RWLOCK_INITIALIZER;
+
+ for (i = 0; i < STEPS; i++) {
+ ck_rwlock_write_lock(&rwlock);
+ ck_rwlock_write_unlock(&rwlock);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ ck_rwlock_write_lock(&rwlock);
+ ck_rwlock_write_unlock(&rwlock);
+ }
+ e_b = rdtsc();
+ printf(" WRITE: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+
+#ifdef CK_F_PR_RTM
+ struct ck_elide_config config = CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;
+ struct ck_elide_stat st = CK_ELIDE_STAT_INITIALIZER;
+
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK(ck_rwlock_write, &rwlock);
+ CK_ELIDE_UNLOCK(ck_rwlock_write, &rwlock);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK(ck_rwlock_write, &rwlock);
+ CK_ELIDE_UNLOCK(ck_rwlock_write, &rwlock);
+ }
+ e_b = rdtsc();
+ printf(" (rtm) WRITE: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &st, &config, &rwlock);
+ CK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &st, &rwlock);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &st, &config, &rwlock);
+ CK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &st, &rwlock);
+ }
+ e_b = rdtsc();
+ printf(" (rtm-adaptive) WRITE: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+#endif /* CK_F_PR_RTM */
+
+ for (i = 0; i < STEPS; i++) {
+ ck_rwlock_read_lock(&rwlock);
+ ck_rwlock_read_unlock(&rwlock);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ ck_rwlock_read_lock(&rwlock);
+ ck_rwlock_read_unlock(&rwlock);
+ }
+ e_b = rdtsc();
+ printf(" READ: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+
+#ifdef CK_F_PR_RTM
+ ck_elide_stat_init(&st);
+
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK(ck_rwlock_read, &rwlock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rwlock);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK(ck_rwlock_read, &rwlock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rwlock);
+ }
+ e_b = rdtsc();
+ printf(" (rtm) READ: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_read, &st, &config, &rwlock);
+ CK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_read, &st, &rwlock);
+ }
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; i++) {
+ CK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_read, &st, &config, &rwlock);
+ CK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_read, &st, &rwlock);
+ }
+ e_b = rdtsc();
+ printf(" (rtm-adaptive) READ: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
+#endif /* CK_F_PR_RTM */
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwlock/benchmark/throughput.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwlock/benchmark/throughput.c b/lib/ck/regressions/ck_rwlock/benchmark/throughput.c
new file mode 100644
index 0000000..908348d
--- /dev/null
+++ b/lib/ck/regressions/ck_rwlock/benchmark/throughput.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2011-2014 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_rwlock.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../common.h"
+
+#ifndef STEPS
+#define STEPS 1000000
+#endif
+
+static int barrier;
+static int threads;
+static unsigned int flag CK_CC_CACHELINE;
+static struct {
+ ck_rwlock_t lock;
+} rw CK_CC_CACHELINE = {
+ .lock = CK_RWLOCK_INITIALIZER
+};
+
+static struct affinity affinity;
+
+#ifdef CK_F_PR_RTM
+static void *
+thread_lock_rtm(void *pun)
+{
+ uint64_t s_b, e_b, a, i;
+ uint64_t *value = pun;
+
+ if (aff_iterate(&affinity) != 0) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ ck_pr_inc_int(&barrier);
+ while (ck_pr_load_int(&barrier) != threads)
+ ck_pr_stall();
+
+ for (i = 1, a = 0;; i++) {
+ s_b = rdtsc();
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);
+ e_b = rdtsc();
+
+ a += (e_b - s_b) >> 4;
+
+ if (ck_pr_load_uint(&flag) == 1)
+ break;
+ }
+
+ ck_pr_inc_int(&barrier);
+ while (ck_pr_load_int(&barrier) != threads * 2)
+ ck_pr_stall();
+
+ *value = (a / i);
+ return NULL;
+}
+#endif /* CK_F_PR_RTM */
+
+static void *
+thread_lock(void *pun)
+{
+ uint64_t s_b, e_b, a, i;
+ uint64_t *value = pun;
+
+ if (aff_iterate(&affinity) != 0) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ ck_pr_inc_int(&barrier);
+ while (ck_pr_load_int(&barrier) != threads)
+ ck_pr_stall();
+
+ for (i = 1, a = 0;; i++) {
+ s_b = rdtsc();
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ ck_rwlock_read_lock(&rw.lock);
+ ck_rwlock_read_unlock(&rw.lock);
+ e_b = rdtsc();
+
+ a += (e_b - s_b) >> 4;
+
+ if (ck_pr_load_uint(&flag) == 1)
+ break;
+ }
+
+ ck_pr_inc_int(&barrier);
+ while (ck_pr_load_int(&barrier) != threads * 2)
+ ck_pr_stall();
+
+ *value = (a / i);
+ return NULL;
+}
+
+static void
+rwlock_test(pthread_t *p, int d, uint64_t *latency, void *(*f)(void *), const char *label)
+{
+ int t;
+
+ ck_pr_store_int(&barrier, 0);
+ ck_pr_store_uint(&flag, 0);
+
+ affinity.delta = d;
+ affinity.request = 0;
+
+ fprintf(stderr, "Creating threads (%s)...", label);
+ for (t = 0; t < threads; t++) {
+ if (pthread_create(&p[t], NULL, f, latency + t) != 0) {
+ ck_error("ERROR: Could not create thread %d\n", t);
+ }
+ }
+ fprintf(stderr, "done\n");
+
+ common_sleep(10);
+ ck_pr_store_uint(&flag, 1);
+
+ fprintf(stderr, "Waiting for threads to finish acquisition regression...");
+ for (t = 0; t < threads; t++)
+ pthread_join(p[t], NULL);
+ fprintf(stderr, "done\n\n");
+
+ for (t = 1; t <= threads; t++)
+ printf("%10u %20" PRIu64 "\n", t, latency[t - 1]);
+
+ fprintf(stderr, "\n");
+ return;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int d;
+ pthread_t *p;
+ uint64_t *latency;
+
+ if (argc != 3) {
+ ck_error("Usage: throughput <delta> <threads>\n");
+ }
+
+ threads = atoi(argv[2]);
+ if (threads <= 0) {
+ ck_error("ERROR: Threads must be a value > 0.\n");
+ }
+
+ p = malloc(sizeof(pthread_t) * threads);
+ if (p == NULL) {
+ ck_error("ERROR: Failed to initialize thread.\n");
+ }
+
+ latency = malloc(sizeof(uint64_t) * threads);
+ if (latency == NULL) {
+ ck_error("ERROR: Failed to create latency buffer.\n");
+ }
+
+ d = atoi(argv[1]);
+ rwlock_test(p, d, latency, thread_lock, "rwlock");
+
+#ifdef CK_F_PR_RTM
+ rwlock_test(p, d, latency, thread_lock_rtm, "rwlock, rtm");
+#endif /* CK_F_PR_RTM */
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwlock/validate/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwlock/validate/Makefile b/lib/ck/regressions/ck_rwlock/validate/Makefile
new file mode 100644
index 0000000..2c2116b
--- /dev/null
+++ b/lib/ck/regressions/ck_rwlock/validate/Makefile
@@ -0,0 +1,17 @@
+.PHONY: check clean distribution
+
+OBJECTS=validate
+
+all: $(OBJECTS)
+
+validate: validate.c ../../../include/ck_rwlock.h ../../../include/ck_elide.h
+ $(CC) $(CFLAGS) -o validate validate.c
+
+check: all
+ ./validate $(CORES) 1
+
+clean:
+ rm -rf *.dSYM *.exe *~ *.o $(OBJECTS)
+
+include ../../../build/regressions.build
+CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_rwlock/validate/validate.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_rwlock/validate/validate.c b/lib/ck/regressions/ck_rwlock/validate/validate.c
new file mode 100644
index 0000000..de77d26
--- /dev/null
+++ b/lib/ck/regressions/ck_rwlock/validate/validate.c
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2011-2014 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 <errno.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <ck_pr.h>
+#include <ck_rwlock.h>
+
+#include "../../common.h"
+
+#ifndef ITERATE
+#define ITERATE 1000000
+#endif
+
+static struct affinity a;
+static unsigned int locked;
+static unsigned int tid = 2;
+static int nthr;
+static ck_rwlock_t lock = CK_RWLOCK_INITIALIZER;
+static ck_rwlock_recursive_t r_lock = CK_RWLOCK_RECURSIVE_INITIALIZER;
+
+static void *
+thread_recursive(void *null CK_CC_UNUSED)
+{
+ int i = ITERATE;
+ unsigned int l;
+ unsigned int t = ck_pr_faa_uint(&tid, 1);
+
+ if (aff_iterate(&a)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (i--) {
+ while (ck_rwlock_recursive_write_trylock(&r_lock, t) == false)
+ ck_pr_stall();
+
+ ck_rwlock_recursive_write_lock(&r_lock, t);
+ ck_rwlock_recursive_write_lock(&r_lock, t);
+ ck_rwlock_recursive_write_lock(&r_lock, t);
+
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 8) {
+ ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
+ }
+
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ ck_rwlock_recursive_write_unlock(&r_lock);
+ ck_rwlock_recursive_write_unlock(&r_lock);
+ ck_rwlock_recursive_write_unlock(&r_lock);
+ ck_rwlock_recursive_write_unlock(&r_lock);
+
+ ck_rwlock_recursive_read_lock(&r_lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ ck_rwlock_recursive_read_unlock(&r_lock);
+ }
+
+ return (NULL);
+}
+
+#ifdef CK_F_PR_RTM
+static void *
+thread_rtm_adaptive(void *null CK_CC_UNUSED)
+{
+ unsigned int i = ITERATE;
+ unsigned int l;
+ struct ck_elide_config config = CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;
+ struct ck_elide_stat st = CK_ELIDE_STAT_INITIALIZER;
+
+ if (aff_iterate(&a)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (i--) {
+ CK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &st, &config, &lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 8) {
+ ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
+ }
+
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ CK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &st, &lock);
+
+ CK_ELIDE_LOCK(ck_rwlock_read, &lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &lock);
+ }
+
+ return NULL;
+}
+
+static void *
+thread_rtm_mix(void *null CK_CC_UNUSED)
+{
+ unsigned int i = ITERATE;
+ unsigned int l;
+
+ if (aff_iterate(&a)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (i--) {
+ if (i & 1) {
+ CK_ELIDE_LOCK(ck_rwlock_write, &lock);
+ } else {
+ ck_rwlock_write_lock(&lock);
+ }
+
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 8) {
+ ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
+ }
+
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+
+ if (i & 1) {
+ CK_ELIDE_UNLOCK(ck_rwlock_write, &lock);
+ } else {
+ ck_rwlock_write_unlock(&lock);
+ }
+
+ if (i & 1) {
+ CK_ELIDE_LOCK(ck_rwlock_read, &lock);
+ } else {
+ ck_rwlock_read_lock(&lock);
+ }
+
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+
+ if (i & 1) {
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &lock);
+ } else {
+ ck_rwlock_read_unlock(&lock);
+ }
+ }
+
+ return (NULL);
+}
+
+static void *
+thread_rtm(void *null CK_CC_UNUSED)
+{
+ unsigned int i = ITERATE;
+ unsigned int l;
+
+ if (aff_iterate(&a)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (i--) {
+ CK_ELIDE_LOCK(ck_rwlock_write, &lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 8) {
+ ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
+ }
+
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ CK_ELIDE_UNLOCK(ck_rwlock_write, &lock);
+
+ CK_ELIDE_LOCK(ck_rwlock_read, &lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ CK_ELIDE_UNLOCK(ck_rwlock_read, &lock);
+ }
+
+ return (NULL);
+}
+#endif /* CK_F_PR_RTM */
+
+static void *
+thread(void *null CK_CC_UNUSED)
+{
+ unsigned int i = ITERATE;
+ unsigned int l;
+
+ if (aff_iterate(&a)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (i--) {
+ ck_rwlock_write_lock(&lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+ ck_pr_inc_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 8) {
+ ck_error("ERROR [WR:%d]: %u != 2\n", __LINE__, l);
+ }
+
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+ ck_pr_dec_uint(&locked);
+
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [WR:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ ck_rwlock_write_unlock(&lock);
+
+ ck_rwlock_read_lock(&lock);
+ {
+ l = ck_pr_load_uint(&locked);
+ if (l != 0) {
+ ck_error("ERROR [RD:%d]: %u != 0\n", __LINE__, l);
+ }
+ }
+ ck_rwlock_read_unlock(&lock);
+ }
+
+ return (NULL);
+}
+
+static void
+rwlock_test(pthread_t *threads, void *(*f)(void *), const char *test)
+{
+ int i;
+
+ fprintf(stderr, "Creating threads (%s)...", test);
+ for (i = 0; i < nthr; i++) {
+ if (pthread_create(&threads[i], NULL, f, NULL)) {
+ ck_error("ERROR: Could not create thread %d\n", i);
+ }
+ }
+ fprintf(stderr, ".");
+
+ for (i = 0; i < nthr; i++)
+ pthread_join(threads[i], NULL);
+ fprintf(stderr, "done (passed)\n");
+ return;
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *threads;
+
+ if (argc != 3) {
+ ck_error("Usage: validate <number of threads> <affinity delta>\n");
+ }
+
+ nthr = atoi(argv[1]);
+ if (nthr <= 0) {
+ ck_error("ERROR: Number of threads must be greater than 0\n");
+ }
+
+ threads = malloc(sizeof(pthread_t) * nthr);
+ if (threads == NULL) {
+ ck_error("ERROR: Could not allocate thread structures\n");
+ }
+
+ a.delta = atoi(argv[2]);
+
+ rwlock_test(threads, thread, "regular");
+#ifdef CK_F_PR_RTM
+ rwlock_test(threads, thread_rtm, "rtm");
+ rwlock_test(threads, thread_rtm_mix, "rtm-mix");
+ rwlock_test(threads, thread_rtm_adaptive, "rtm-adaptive");
+#endif
+ rwlock_test(threads, thread_recursive, "recursive");
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_sequence/benchmark/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_sequence/benchmark/Makefile b/lib/ck/regressions/ck_sequence/benchmark/Makefile
new file mode 100644
index 0000000..5803a4d
--- /dev/null
+++ b/lib/ck/regressions/ck_sequence/benchmark/Makefile
@@ -0,0 +1,18 @@
+.PHONY: clean distribution
+
+OBJECTS=ck_sequence
+
+all: $(OBJECTS)
+
+ck_sequence: ck_sequence.c ../../../include/ck_sequence.h
+ $(CC) $(CFLAGS) -o ck_sequence ck_sequence.c
+
+check: all
+ ./ck_sequence $(CORES) 1
+
+clean:
+ rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe
+
+include ../../../build/regressions.build
+CFLAGS+=-D_GNU_SOURCE
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_sequence/benchmark/ck_sequence.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_sequence/benchmark/ck_sequence.c b/lib/ck/regressions/ck_sequence/benchmark/ck_sequence.c
new file mode 100644
index 0000000..de7af6d
--- /dev/null
+++ b/lib/ck/regressions/ck_sequence/benchmark/ck_sequence.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2013-2014 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_cc.h>
+#include <ck_sequence.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "../../common.h"
+
+#ifndef STEPS
+#define STEPS (65536 * 64)
+#endif
+
+static ck_sequence_t seqlock CK_CC_CACHELINE = CK_SEQUENCE_INITIALIZER;
+
+int
+main(void)
+{
+ unsigned int i = 0;
+ unsigned int version;
+ uint64_t a, s;
+
+ /* Read-side latency. */
+ a = 0;
+ for (i = 0; i < STEPS / 4; i++) {
+ s = rdtsc();
+ ck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));
+ ck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));
+ ck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));
+ ck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));
+ a += rdtsc() - s;
+ }
+ printf("read: %" PRIu64 "\n", a / STEPS);
+
+ a = 0;
+ for (i = 0; i < STEPS / 4; i++) {
+ s = rdtsc();
+ CK_SEQUENCE_READ(&seqlock, &version);
+ CK_SEQUENCE_READ(&seqlock, &version);
+ CK_SEQUENCE_READ(&seqlock, &version);
+ CK_SEQUENCE_READ(&seqlock, &version);
+ a += rdtsc() - s;
+ }
+ printf("READ %" PRIu64 "\n", a / STEPS);
+
+ /* Write-side latency. */
+ a = 0;
+ for (i = 0; i < STEPS / 4; i++) {
+ s = rdtsc();
+ ck_sequence_write_begin(&seqlock);
+ ck_sequence_write_end(&seqlock);
+ ck_sequence_write_begin(&seqlock);
+ ck_sequence_write_end(&seqlock);
+ ck_sequence_write_begin(&seqlock);
+ ck_sequence_write_end(&seqlock);
+ ck_sequence_write_begin(&seqlock);
+ ck_sequence_write_end(&seqlock);
+ a += rdtsc() - s;
+ }
+ printf("write: %" PRIu64 "\n", a / STEPS);
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_sequence/validate/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_sequence/validate/Makefile b/lib/ck/regressions/ck_sequence/validate/Makefile
new file mode 100644
index 0000000..bc2e5be
--- /dev/null
+++ b/lib/ck/regressions/ck_sequence/validate/Makefile
@@ -0,0 +1,17 @@
+.PHONY: check clean distribution
+
+OBJECTS=ck_sequence
+
+all: $(OBJECTS)
+
+ck_sequence: ck_sequence.c ../../../include/ck_sequence.h
+ $(CC) $(CFLAGS) -o ck_sequence ck_sequence.c
+
+check: all
+ ./ck_sequence $(CORES) 1
+
+clean:
+ rm -rf *~ *.o $(OBJECTS) *.dSYM *.exe
+
+include ../../../build/regressions.build
+CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_sequence/validate/ck_sequence.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_sequence/validate/ck_sequence.c b/lib/ck/regressions/ck_sequence/validate/ck_sequence.c
new file mode 100644
index 0000000..1f01931
--- /dev/null
+++ b/lib/ck/regressions/ck_sequence/validate/ck_sequence.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2011-2014 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_cc.h>
+#include <ck_sequence.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../../common.h"
+
+#ifndef STEPS
+#define STEPS 1000000
+#endif
+
+struct example {
+ unsigned int a;
+ unsigned int b;
+ unsigned int c;
+};
+
+static struct example global CK_CC_CACHELINE;
+static ck_sequence_t seqlock CK_CC_CACHELINE = CK_SEQUENCE_INITIALIZER;
+static unsigned int barrier;
+static struct affinity affinerator;
+
+static void
+validate(struct example *copy)
+{
+
+ if (copy->b != copy->a + 1000) {
+ ck_error("ERROR: Failed regression: copy->b (%u != %u + %u / %u)\n",
+ copy->b, copy->a, 1000, copy->a + 1000);
+ }
+
+ if (copy->c != copy->a + copy->b) {
+ ck_error("ERROR: Failed regression: copy->c (%u != %u + %u / %u)\n",
+ copy->c, copy->a, copy->b, copy->a + copy->b);
+ }
+
+ return;
+}
+
+static void *
+consumer(void *unused CK_CC_UNUSED)
+{
+ struct example copy;
+ uint32_t version;
+ unsigned int retries = 0;
+ unsigned int i;
+
+ unused = NULL;
+ if (aff_iterate(&affinerator)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (ck_pr_load_uint(&barrier) == 0);
+ for (i = 0; i < STEPS; i++) {
+ /*
+ * Attempt a read of the data structure. If the structure
+ * has been modified between ck_sequence_read_begin and
+ * ck_sequence_read_retry then attempt another read since
+ * the data may be in an inconsistent state.
+ */
+ do {
+ version = ck_sequence_read_begin(&seqlock);
+ copy.a = ck_pr_load_uint(&global.a);
+ copy.b = ck_pr_load_uint(&global.b);
+ copy.c = ck_pr_load_uint(&global.c);
+ retries++;
+ } while (ck_sequence_read_retry(&seqlock, version) == true);
+ validate(©);
+
+ CK_SEQUENCE_READ(&seqlock, &version) {
+ copy.a = ck_pr_load_uint(&global.a);
+ copy.b = ck_pr_load_uint(&global.b);
+ copy.c = ck_pr_load_uint(&global.c);
+ retries++;
+ }
+ validate(©);
+ }
+
+ fprintf(stderr, "%u retries.\n", retries - STEPS);
+ ck_pr_dec_uint(&barrier);
+ return (NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *threads;
+ unsigned int counter = 0;
+ int n_threads, i;
+
+ if (argc != 3) {
+ ck_error("Usage: ck_sequence <number of threads> <affinity delta>\n");
+ }
+
+ n_threads = atoi(argv[1]);
+ if (n_threads <= 0) {
+ ck_error("ERROR: Number of threads must be greater than 0\n");
+ }
+
+ threads = malloc(sizeof(pthread_t) * n_threads);
+ if (threads == NULL) {
+ ck_error("ERROR: Could not allocate memory for threads\n");
+ }
+
+ affinerator.delta = atoi(argv[2]);
+ affinerator.request = 0;
+
+ for (i = 0; i < n_threads; i++) {
+ if (pthread_create(&threads[i], NULL, consumer, NULL)) {
+ ck_error("ERROR: Failed to create thread %d\n", i);
+ }
+ }
+
+ for (;;) {
+ /*
+ * Update the shared data in a non-blocking fashion.
+ * If the data is modified by multiple writers then
+ * ck_sequence_write_begin must be called after acquiring
+ * the associated lock and ck_sequence_write_end must be
+ * called before relinquishing the lock.
+ */
+ ck_sequence_write_begin(&seqlock);
+ global.a = counter++;
+ global.b = global.a + 1000;
+ global.c = global.b + global.a;
+ ck_sequence_write_end(&seqlock);
+
+ if (counter == 1)
+ ck_pr_store_uint(&barrier, n_threads);
+
+ counter++;
+ if (ck_pr_load_uint(&barrier) == 0)
+ break;
+ }
+
+ printf("%u updates made.\n", counter);
+ return (0);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/Makefile
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/Makefile b/lib/ck/regressions/ck_spinlock/benchmark/Makefile
new file mode 100644
index 0000000..ca3e1cf
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/Makefile
@@ -0,0 +1,87 @@
+.PHONY: all clean
+
+OBJECTS=ck_ticket.THROUGHPUT ck_ticket.LATENCY \
+ ck_mcs.THROUGHPUT ck_mcs.LATENCY \
+ ck_dec.THROUGHPUT ck_dec.LATENCY \
+ ck_cas.THROUGHPUT ck_cas.LATENCY \
+ ck_fas.THROUGHPUT ck_fas.LATENCY \
+ ck_clh.THROUGHPUT ck_clh.LATENCY \
+ linux_spinlock.THROUGHPUT linux_spinlock.LATENCY \
+ ck_ticket_pb.THROUGHPUT ck_ticket_pb.LATENCY \
+ ck_anderson.THROUGHPUT ck_anderson.LATENCY \
+ ck_spinlock.THROUGHPUT ck_spinlock.LATENCY \
+ ck_hclh.THROUGHPUT ck_hclh.LATENCY
+
+all: $(OBJECTS)
+
+ck_spinlock.THROUGHPUT: ck_spinlock.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_spinlock.THROUGHPUT ck_spinlock.c -lm
+
+ck_spinlock.LATENCY: ck_spinlock.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_spinlock.LATENCY ck_spinlock.c -lm
+
+ck_ticket.THROUGHPUT: ck_ticket.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_ticket.THROUGHPUT ck_ticket.c -lm
+
+ck_ticket.LATENCY: ck_ticket.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_ticket.LATENCY ck_ticket.c -lm
+
+ck_mcs.THROUGHPUT: ck_mcs.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_mcs.THROUGHPUT ck_mcs.c -lm
+
+ck_mcs.LATENCY: ck_mcs.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_mcs.LATENCY ck_mcs.c -lm
+
+ck_dec.THROUGHPUT: ck_dec.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_dec.THROUGHPUT ck_dec.c -lm
+
+ck_dec.LATENCY: ck_dec.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_dec.LATENCY ck_dec.c -lm
+
+ck_cas.THROUGHPUT: ck_cas.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_cas.THROUGHPUT ck_cas.c -lm
+
+ck_cas.LATENCY: ck_cas.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_cas.LATENCY ck_cas.c -lm
+
+ck_fas.THROUGHPUT: ck_fas.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_fas.THROUGHPUT ck_fas.c -lm
+
+ck_fas.LATENCY: ck_fas.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_fas.LATENCY ck_fas.c -lm
+
+ck_clh.THROUGHPUT: ck_clh.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_clh.THROUGHPUT ck_clh.c -lm
+
+ck_clh.LATENCY: ck_clh.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_clh.LATENCY ck_clh.c -lm
+
+ck_hclh.THROUGHPUT: ck_hclh.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_hclh.THROUGHPUT ck_hclh.c -lm
+
+ck_hclh.LATENCY: ck_hclh.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_hclh.LATENCY ck_hclh.c -lm
+
+linux_spinlock.THROUGHPUT: linux_spinlock.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o linux_spinlock.THROUGHPUT linux_spinlock.c -lm
+
+linux_spinlock.LATENCY: linux_spinlock.c
+ $(CC) -DLATENCY $(CFLAGS) -o linux_spinlock.LATENCY linux_spinlock.c -lm
+
+ck_ticket_pb.THROUGHPUT: ck_ticket_pb.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_ticket_pb.THROUGHPUT ck_ticket_pb.c -lm
+
+ck_ticket_pb.LATENCY: ck_ticket_pb.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_ticket_pb.LATENCY ck_ticket_pb.c -lm
+
+ck_anderson.THROUGHPUT: ck_anderson.c
+ $(CC) -DTHROUGHPUT $(CFLAGS) -o ck_anderson.THROUGHPUT ck_anderson.c -lm
+
+ck_anderson.LATENCY: ck_anderson.c
+ $(CC) -DLATENCY $(CFLAGS) -o ck_anderson.LATENCY ck_anderson.c -lm
+
+clean:
+ rm -rf *.dSYM *.exe $(OBJECTS)
+
+include ../../../build/regressions.build
+CFLAGS+=$(PTHREAD_CFLAGS) -D_GNU_SOURCE
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_anderson.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_anderson.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_anderson.c
new file mode 100644
index 0000000..2f1aecd
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_anderson.c
@@ -0,0 +1,8 @@
+#include "../ck_anderson.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_cas.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_cas.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_cas.c
new file mode 100644
index 0000000..96bd9d8
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_cas.c
@@ -0,0 +1,8 @@
+#include "../ck_cas.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_clh.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_clh.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_clh.c
new file mode 100644
index 0000000..da71d5e
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_clh.c
@@ -0,0 +1,7 @@
+#include "../ck_clh.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_dec.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_dec.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_dec.c
new file mode 100644
index 0000000..115c116
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_dec.c
@@ -0,0 +1,7 @@
+#include "../ck_dec.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_fas.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_fas.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_fas.c
new file mode 100644
index 0000000..c76c964
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_fas.c
@@ -0,0 +1,7 @@
+#include "../ck_fas.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_hclh.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_hclh.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_hclh.c
new file mode 100644
index 0000000..9ae443e
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_hclh.c
@@ -0,0 +1,7 @@
+#include "../ck_hclh.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_mcs.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_mcs.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_mcs.c
new file mode 100644
index 0000000..c2e95de
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_mcs.c
@@ -0,0 +1,7 @@
+#include "../ck_mcs.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_spinlock.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_spinlock.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_spinlock.c
new file mode 100644
index 0000000..138541e
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_spinlock.c
@@ -0,0 +1,7 @@
+#include "../ck_spinlock.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket.c
new file mode 100644
index 0000000..09c9193
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket.c
@@ -0,0 +1,8 @@
+#include "../ck_ticket.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket_pb.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket_pb.c b/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket_pb.c
new file mode 100644
index 0000000..6122d6a
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/ck_ticket_pb.c
@@ -0,0 +1,7 @@
+#include "../ck_ticket_pb.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/latency.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/latency.h b/lib/ck/regressions/ck_spinlock/benchmark/latency.h
new file mode 100644
index 0000000..51cc6cc
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/latency.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011-2014 Samy Al Bahra.
+ * 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_bytelock.h>
+#include <ck_spinlock.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../../common.h"
+
+#ifndef STEPS
+#define STEPS 30000000
+#endif
+
+LOCK_DEFINE;
+
+int
+main(void)
+{
+ CK_CC_UNUSED unsigned int nthr = 1;
+
+ #ifdef LOCK_INIT
+ LOCK_INIT;
+ #endif
+
+ #ifdef LOCK_STATE
+ LOCK_STATE;
+ #endif
+
+ uint64_t s_b, e_b, i;
+ CK_CC_UNUSED int core = 0;
+
+ s_b = rdtsc();
+ for (i = 0; i < STEPS; ++i) {
+ #ifdef LOCK
+ LOCK;
+ UNLOCK;
+ LOCK;
+ UNLOCK;
+ LOCK;
+ UNLOCK;
+ LOCK;
+ UNLOCK;
+ #endif
+ }
+ e_b = rdtsc();
+ printf("%15" PRIu64 "\n", (e_b - s_b) / 4 / STEPS);
+
+ return (0);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/linux_spinlock.c
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/linux_spinlock.c b/lib/ck/regressions/ck_spinlock/benchmark/linux_spinlock.c
new file mode 100644
index 0000000..954019b
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/linux_spinlock.c
@@ -0,0 +1,7 @@
+#include "../linux_spinlock.h"
+
+#ifdef THROUGHPUT
+#include "throughput.h"
+#elif defined(LATENCY)
+#include "latency.h"
+#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/benchmark/throughput.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/benchmark/throughput.h b/lib/ck/regressions/ck_spinlock/benchmark/throughput.h
new file mode 100644
index 0000000..7851c50
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/benchmark/throughput.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2008-2012 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 <errno.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include <ck_pr.h>
+#include <ck_spinlock.h>
+
+#include "../../common.h"
+
+/* 8! = 40320, evenly divide 1 .. 8 processor workload. */
+#define WORKLOAD (40320 * 2056)
+
+#ifndef ITERATE
+#define ITERATE 65536
+#endif
+
+struct block {
+ unsigned int tid;
+};
+
+static struct affinity a;
+static unsigned int ready;
+
+struct counters {
+ uint64_t value;
+} CK_CC_CACHELINE;
+
+static struct counters *count;
+static uint64_t nthr;
+static unsigned int barrier;
+
+int critical __attribute__((aligned(64)));
+
+LOCK_DEFINE;
+
+CK_CC_USED static void
+gen_lock(void)
+{
+ CK_CC_UNUSED int core = 0;
+#ifdef LOCK_STATE
+ LOCK_STATE;
+#endif
+
+#ifdef LOCK
+ LOCK;
+#endif
+}
+
+CK_CC_USED static void
+gen_unlock(void)
+{
+#ifdef LOCK_STATE
+ LOCK_STATE;
+#endif
+
+#ifdef UNLOCK
+ UNLOCK;
+#endif
+}
+
+static void *
+fairness(void *null)
+{
+#ifdef LOCK_STATE
+ LOCK_STATE;
+#endif
+ struct block *context = null;
+ unsigned int i = context->tid;
+ volatile int j;
+ long int base;
+ unsigned int core;
+
+ if (aff_iterate_core(&a, &core)) {
+ perror("ERROR: Could not affine thread");
+ exit(EXIT_FAILURE);
+ }
+
+ while (ck_pr_load_uint(&ready) == 0);
+
+ ck_pr_inc_uint(&barrier);
+ while (ck_pr_load_uint(&barrier) != nthr);
+
+ while (ready) {
+ LOCK;
+
+ count[i].value++;
+ if (critical) {
+ base = common_lrand48() % critical;
+ for (j = 0; j < base; j++);
+ }
+
+ UNLOCK;
+ }
+
+ return (NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ uint64_t v, d;
+ unsigned int i;
+ pthread_t *threads;
+ struct block *context;
+
+ if (argc != 4) {
+ ck_error("Usage: " LOCK_NAME " <number of threads> <affinity delta> <critical section>\n");
+ exit(EXIT_FAILURE);
+ }
+
+ nthr = atoi(argv[1]);
+ if (nthr <= 0) {
+ ck_error("ERROR: Number of threads must be greater than 0\n");
+ exit(EXIT_FAILURE);
+ }
+
+#ifdef LOCK_INIT
+ LOCK_INIT;
+#endif
+
+ critical = atoi(argv[3]);
+ if (critical < 0) {
+ ck_error("ERROR: critical section cannot be negative\n");
+ exit(EXIT_FAILURE);
+ }
+
+ threads = malloc(sizeof(pthread_t) * nthr);
+ if (threads == NULL) {
+ ck_error("ERROR: Could not allocate thread structures\n");
+ exit(EXIT_FAILURE);
+ }
+
+ context = malloc(sizeof(struct block) * nthr);
+ if (context == NULL) {
+ ck_error("ERROR: Could not allocate thread contexts\n");
+ exit(EXIT_FAILURE);
+ }
+
+ a.delta = atoi(argv[2]);
+ a.request = 0;
+
+ count = malloc(sizeof(*count) * nthr);
+ if (count == NULL) {
+ ck_error("ERROR: Could not create acquisition buffer\n");
+ exit(EXIT_FAILURE);
+ }
+ memset(count, 0, sizeof(*count) * nthr);
+
+ fprintf(stderr, "Creating threads (fairness)...");
+ for (i = 0; i < nthr; i++) {
+ context[i].tid = i;
+ if (pthread_create(&threads[i], NULL, fairness, context + i)) {
+ ck_error("ERROR: Could not create thread %d\n", i);
+ exit(EXIT_FAILURE);
+ }
+ }
+ fprintf(stderr, "done\n");
+
+ ck_pr_store_uint(&ready, 1);
+ common_sleep(10);
+ ck_pr_store_uint(&ready, 0);
+
+ fprintf(stderr, "Waiting for threads to finish acquisition regression...");
+ for (i = 0; i < nthr; i++)
+ pthread_join(threads[i], NULL);
+ fprintf(stderr, "done\n\n");
+
+ for (i = 0, v = 0; i < nthr; i++) {
+ printf("%d %15" PRIu64 "\n", i, count[i].value);
+ v += count[i].value;
+ }
+
+ printf("\n# total : %15" PRIu64 "\n", v);
+ printf("# throughput : %15" PRIu64 " a/s\n", (v /= nthr) / 10);
+
+ for (i = 0, d = 0; i < nthr; i++)
+ d += (count[i].value - v) * (count[i].value - v);
+
+ printf("# average : %15" PRIu64 "\n", v);
+ printf("# deviation : %.2f (%.2f%%)\n\n", sqrt(d / nthr), (sqrt(d / nthr) / v) * 100.00);
+
+ return (0);
+}
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/ck_anderson.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/ck_anderson.h b/lib/ck/regressions/ck_spinlock/ck_anderson.h
new file mode 100644
index 0000000..7dc8e6e
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/ck_anderson.h
@@ -0,0 +1,11 @@
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LOCK_NAME "ck_anderson"
+#define LOCK_DEFINE static ck_spinlock_anderson_t lock CK_CC_CACHELINE
+#define LOCK_STATE ck_spinlock_anderson_thread_t *nad = NULL
+#define LOCK ck_spinlock_anderson_lock(&lock, &nad)
+#define UNLOCK ck_spinlock_anderson_unlock(&lock, nad)
+#define LOCK_INIT ck_spinlock_anderson_init(&lock, malloc(MAX(64,sizeof(ck_spinlock_anderson_thread_t)) * nthr), nthr)
+#define LOCKED ck_spinlock_anderson_locked(&lock)
+
+#define NO_LOCAL
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/ck_cas.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/ck_cas.h b/lib/ck/regressions/ck_spinlock/ck_cas.h
new file mode 100644
index 0000000..bd4ae13
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/ck_cas.h
@@ -0,0 +1,6 @@
+#define LOCK_NAME "ck_cas"
+#define LOCK_DEFINE static ck_spinlock_cas_t CK_CC_CACHELINE lock = CK_SPINLOCK_CAS_INITIALIZER
+#define LOCK ck_spinlock_cas_lock_eb(&lock)
+#define UNLOCK ck_spinlock_cas_unlock(&lock)
+#define LOCKED ck_spinlock_cas_locked(&lock)
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/ck_clh.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/ck_clh.h b/lib/ck/regressions/ck_spinlock/ck_clh.h
new file mode 100644
index 0000000..df7e49f
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/ck_clh.h
@@ -0,0 +1,9 @@
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define LOCK_NAME "ck_clh"
+#define LOCK_DEFINE static ck_spinlock_clh_t CK_CC_CACHELINE *lock = NULL
+#define LOCK_STATE ck_spinlock_clh_t *na = malloc(MAX(sizeof(ck_spinlock_clh_t), 64))
+#define LOCK ck_spinlock_clh_lock(&lock, na)
+#define UNLOCK ck_spinlock_clh_unlock(&na)
+#define LOCK_INIT ck_spinlock_clh_init(&lock, malloc(MAX(sizeof(ck_spinlock_clh_t), 64)))
+#define LOCKED ck_spinlock_clh_locked(&lock)
+
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/f098175e/lib/ck/regressions/ck_spinlock/ck_dec.h
----------------------------------------------------------------------
diff --git a/lib/ck/regressions/ck_spinlock/ck_dec.h b/lib/ck/regressions/ck_spinlock/ck_dec.h
new file mode 100644
index 0000000..c21a390
--- /dev/null
+++ b/lib/ck/regressions/ck_spinlock/ck_dec.h
@@ -0,0 +1,6 @@
+#define LOCK_NAME "ck_dec"
+#define LOCK_DEFINE static ck_spinlock_dec_t CK_CC_CACHELINE lock = CK_SPINLOCK_DEC_INITIALIZER
+#define LOCK ck_spinlock_dec_lock_eb(&lock)
+#define UNLOCK ck_spinlock_dec_unlock(&lock)
+#define LOCKED ck_spinlock_dec_locked(&lock)
+