#include #include #include #include #include #include #include #include "cachetable-rwlock.h" int verbose = 0; // test create and destroy void test_create_destroy() { struct ctpair_rwlock the_rwlock, *rwlock = &the_rwlock; ctpair_rwlock_init(rwlock); ctpair_rwlock_destroy(rwlock); } // test read lock and unlock with no writers void test_simple_read_lock(int n) { struct ctpair_rwlock the_rwlock, *rwlock = &the_rwlock; ctpair_rwlock_init(rwlock); assert(ctpair_pinned(rwlock) == 0); int i; for (i=1; i<=n; i++) { ctpair_read_lock(rwlock, 0); assert(ctpair_pinned(rwlock) == i); assert(ctpair_users(rwlock) == i); } for (i=n-1; i>=0; i--) { ctpair_read_unlock(rwlock); assert(ctpair_pinned(rwlock) == i); assert(ctpair_users(rwlock) == i); } ctpair_rwlock_destroy(rwlock); } // test write lock and unlock with no readers void test_simple_write_lock() { struct ctpair_rwlock the_rwlock, *rwlock = &the_rwlock; ctpair_rwlock_init(rwlock); assert(ctpair_users(rwlock) == 0); ctpair_write_lock(rwlock, 0); assert(ctpair_writers(rwlock) == 1); assert(ctpair_users(rwlock) == 1); ctpair_write_unlock(rwlock); assert(ctpair_users(rwlock) == 0); ctpair_rwlock_destroy(rwlock); } struct rw_event { int e; struct ctpair_rwlock the_rwlock; pthread_mutex_t mutex; }; void rw_event_init(struct rw_event *rwe) { rwe->e = 0; ctpair_rwlock_init(&rwe->the_rwlock); int r = pthread_mutex_init(&rwe->mutex, 0); assert(r == 0); } void rw_event_destroy(struct rw_event *rwe) { ctpair_rwlock_destroy(&rwe->the_rwlock); int r = pthread_mutex_destroy(&rwe->mutex); assert(r == 0); } void *test_writer_priority_thread(void *arg) { struct rw_event *rwe = arg; int r; r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex); rwe->e++; assert(rwe->e == 3); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); sleep(1); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); rwe->e++; assert(rwe->e == 4); ctpair_write_unlock(&rwe->the_rwlock); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); return arg; } // test writer priority over new readers void test_writer_priority() { struct rw_event rw_event, *rwe = &rw_event; int r; rw_event_init(rwe); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_read_lock(&rwe->the_rwlock, &rwe->mutex); sleep(1); rwe->e++; assert(rwe->e == 1); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); pthread_t tid; r = pthread_create(&tid, 0, test_writer_priority_thread, rwe); sleep(1); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); rwe->e++; assert(rwe->e == 2); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); sleep(1); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_read_unlock(&rwe->the_rwlock); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); sleep(1); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_read_lock(&rwe->the_rwlock, &rwe->mutex); rwe->e++; assert(rwe->e == 5); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); sleep(1); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_read_unlock(&rwe->the_rwlock); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); void *ret; r = pthread_join(tid, &ret); assert(r == 0); rw_event_destroy(rwe); } // test single writer void *test_single_writer_thread(void *arg) { struct rw_event *rwe = arg; int r; r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex); rwe->e++; assert(rwe->e == 3); assert(ctpair_writers(&rwe->the_rwlock) == 1); ctpair_write_unlock(&rwe->the_rwlock); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); return arg; } void test_single_writer() { struct rw_event rw_event, *rwe = &rw_event; int r; rw_event_init(rwe); assert(ctpair_writers(&rwe->the_rwlock) == 0); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); ctpair_write_lock(&rwe->the_rwlock, &rwe->mutex); assert(ctpair_writers(&rwe->the_rwlock) == 1); sleep(1); rwe->e++; assert(rwe->e == 1); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); pthread_t tid; r = pthread_create(&tid, 0, test_single_writer_thread, rwe); sleep(1); r = pthread_mutex_lock(&rwe->mutex); assert(r == 0); rwe->e++; assert(rwe->e == 2); assert(ctpair_writers(&rwe->the_rwlock) == 1); assert(ctpair_users(&rwe->the_rwlock) == 2); ctpair_write_unlock(&rwe->the_rwlock); r = pthread_mutex_unlock(&rwe->mutex); assert(r == 0); void *ret; r = pthread_join(tid, &ret); assert(r == 0); assert(ctpair_writers(&rwe->the_rwlock) == 0); rw_event_destroy(rwe); } int main(int argc, char *argv[]) { int i; for (i=1; i