ck_rwlock: Add adaptive elision and unit tests.

ck_pring
Samy Al Bahra 12 years ago
parent fe8deba87d
commit 768b5b3597

@ -127,6 +127,10 @@ CK_ELIDE_PROTOTYPE(ck_rwlock_write, ck_rwlock_t,
ck_rwlock_locked, ck_rwlock_write_lock,
ck_rwlock_locked_writer, ck_rwlock_write_unlock)
CK_ELIDE_ADAPTIVE_PROTOTYPE(ck_rwlock_write, ck_rwlock_t,
ck_rwlock_locked, ck_rwlock_write_lock,
ck_rwlock_locked_writer, ck_rwlock_write_unlock)
CK_CC_INLINE static bool
ck_rwlock_read_trylock(ck_rwlock_t *rw)
{
@ -202,6 +206,10 @@ CK_ELIDE_PROTOTYPE(ck_rwlock_read, ck_rwlock_t,
ck_rwlock_locked_writer, ck_rwlock_read_lock,
ck_rwlock_locked_reader, ck_rwlock_read_unlock)
CK_ELIDE_ADAPTIVE_PROTOTYPE(ck_rwlock_read, ck_rwlock_t,
ck_rwlock_locked_writer, ck_rwlock_read_lock,
ck_rwlock_locked_reader, ck_rwlock_read_unlock)
/*
* Recursive writer reader-writer lock implementation.
*/

@ -4,10 +4,10 @@ OBJECTS=latency throughput
all: $(OBJECTS)
latency: latency.c ../../../include/ck_rwlock.h
latency: latency.c ../../../include/ck_rwlock.h ../../../include/ck_elide.h
$(CC) $(CFLAGS) -o latency latency.c
throughput: throughput.c ../../../include/ck_rwlock.h
throughput: throughput.c ../../../include/ck_rwlock.h ../../../include/ck_elide.h
$(CC) $(CFLAGS) -o throughput throughput.c
clean:

@ -30,8 +30,10 @@
#include "../../common.h"
#define CK_F_PR_RTM
#ifndef STEPS
#define STEPS 1000000
#define STEPS 2000000
#endif
int
@ -51,9 +53,12 @@ main(void)
ck_rwlock_write_unlock(&rwlock);
}
e_b = rdtsc();
printf(" WRITE: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
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);
@ -65,7 +70,20 @@ main(void)
CK_ELIDE_UNLOCK(ck_rwlock_write, &rwlock);
}
e_b = rdtsc();
printf(" (rtm) WRITE: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
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++) {
@ -79,9 +97,11 @@ main(void)
ck_rwlock_read_unlock(&rwlock);
}
e_b = rdtsc();
printf(" READ: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
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);
@ -93,7 +113,20 @@ main(void)
CK_ELIDE_UNLOCK(ck_rwlock_read, &rwlock);
}
e_b = rdtsc();
printf(" (rtm) READ: rwlock %15" PRIu64 "\n", (e_b - s_b) / STEPS);
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;

@ -4,7 +4,7 @@ OBJECTS=validate
all: $(OBJECTS)
validate: validate.c ../../../include/ck_rwlock.h
validate: validate.c ../../../include/ck_rwlock.h ../../../include/ck_elide.h
$(CC) $(CFLAGS) -o validate validate.c
check: all

@ -124,6 +124,70 @@ thread_recursive(void *null CK_CC_UNUSED)
}
#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)
{
@ -375,6 +439,7 @@ main(int argc, char *argv[])
#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;

Loading…
Cancel
Save