Skip to content
Snippets Groups Projects
Commit 540f4a80 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Add test for rwlocks

Currently the "wrapper" is just the POSIX API.
We may not need the pthread_rwlock_timed??lock() functions, and even
if we do, we like want a different wrapper that takes a ms timeout
instead of an absolute time.
parent 508984b8
No related branches found
No related tags found
No related merge requests found
Pipeline #5283 passed
#ifndef RWLOCKWRAP_H
#define RWLOCKWRAP_H
#ifdef UNIX
#include <pthread.h>
#include <time.h>
#else
#error Not implemented
#endif
#endif
......@@ -29,4 +29,4 @@ dl-mtlib: $(MTOBJODIR) $(LIBODIR) $(XPDEV-MT_SHLIB_BUILD)
xptime: $(OBJODIR) $(LIBODIR) $(EXEODIR) $(XPTIME)
$(WRAPTEST): $(XPDEV-MT_LIB_BUILD)
$(WRAPTEST): $(XPDEV-MT_LIB_BUILD) | $(EXEODIR)
......@@ -26,7 +26,8 @@ static void sleep_test_thread(void* arg);
static void sopen_test_thread(void* arg);
static void sopen_child_thread(void* arg);
static void lock_test_thread(void* arg);
static void rwlock_rdlock_thread(void *arg);
static void rwlock_wrlock_thread(void *arg);
typedef struct {
sem_t parent_sem;
......@@ -60,6 +61,25 @@ int main()
printf("%-15s: %s\n","Compiler" ,compiler);
printf("%-15s: %ld\n","Random Number",xp_random(1000));
printf("Testing rwlocks...\n");
do {
pthread_rwlock_t lock;
if ((i=pthread_rwlock_init(&lock, NULL)) != 0) {
printf("pthread_rwlock_init() failed (%d)\n", i);
continue;
}
// Start two copies of the ddlock thread...
if (_beginthread(rwlock_rdlock_thread, 0, &lock) == -1UL) {
printf("Unable to start rwlock_rdlock_thread\n");
continue;
}
if (_beginthread(rwlock_rdlock_thread, 0, &lock) == -1UL) {
printf("Unable to start rwlock_rdlock_thread\n");
continue;
}
rwlock_wrlock_thread(&lock);
} while(0);
for(i=0;i<3;i++) {
if(_beginthread(
sopen_child_thread /* entry point */
......@@ -415,4 +435,105 @@ static void sopen_child_thread(void* arg)
printf("sopen_child_thread: %d end\n",(int)arg);
}
static void rwlock_rdlock_thread(void *arg)
{
pthread_rwlock_t *lock = arg;
int locks = 0;
int i;
struct timespec abstime = {0};
// Grab the lock three times...
for (locks = 0; locks < 3; locks++) {
if ((i = pthread_rwlock_rdlock(lock)) != 0) {
printf("Failed to obtain rdlock #%d\n", locks + 1);
break;
}
}
// Try to grab the lock (should succeed)
if ((i = pthread_rwlock_tryrdlock(lock)) == 0) {
locks++;
}
else {
printf("tryrdlock failed: %d\n", i);
}
// Try to grab the lock before Jan 1st, 1970 (should succeed)
if ((i = pthread_rwlock_timedrdlock(lock, &abstime)) == 0) {
locks++;
}
else {
printf("timedrdlock failed: %d\n", i);
}
printf("Obtained %d locks (should be 5)\n", locks);
for (; locks > 0; locks--) {
SLEEP(1000);
if ((i = pthread_rwlock_unlock(lock)) != 0) {
printf("Failed to unlock rdlock #%d\n", locks);
}
}
SLEEP(1000);
// Try to grab the lock (should fail)
if ((i = pthread_rwlock_tryrdlock(lock)) == 0) {
printf("tryrdlock incorrectly succeeded: %d\n", i);
pthread_rwlock_unlock(lock);
}
// Try to grab the lock before Jan 1st, 1970 (should fail)
if ((i = pthread_rwlock_timedrdlock(lock, &abstime)) == 0) {
printf("timedrdlock incorrectly succeeded: %d\n", i);
pthread_rwlock_unlock(lock);
}
// Wait up to five seconds for the lock (should succeed)
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += 5;
printf("Waiting for lock\n");
if ((i = pthread_rwlock_timedrdlock(lock, &abstime)) == 0) {
locks++;
}
else {
printf("timedrdlock failed: %d\n", i);
}
printf("Wait done\n");
SLEEP(1000);
for (; locks > 0; locks--) {
pthread_rwlock_unlock(lock);
}
}
static void rwlock_wrlock_thread(void *arg)
{
pthread_rwlock_t *lock = arg;
int i;
struct timespec abstime = {0};
// Sleep to allow readers to grab locks...
SLEEP(1000);
// Try to grab lock (should fail)
if ((i = pthread_rwlock_trywrlock(lock)) == 0) {
printf("trywrlock() incorrectly succeeded\n");
pthread_rwlock_unlock(lock);
}
// Try to grab lock (should succeed)
printf("Waiting for write lock\n");
if ((i = pthread_rwlock_wrlock(lock)) != 0) {
printf("wrlock() failed %d\n", i);
}
printf("wrlock Wait done\n");
// Enjoy the lock for a bit...
SLEEP(2000);
printf("wrlock unlocking\n");
pthread_rwlock_unlock(lock);
SLEEP(100);
// Wait up to five seconds for the lock (should succeed)
clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += 5;
printf("Waiting up to 5 seconds for wrlock\n");
if ((i = pthread_rwlock_timedwrlock(lock, &abstime)) != 0) {
printf("timedrdlock failed: %d\n", i);
}
else {
SLEEP(1000);
pthread_rwlock_unlock(lock);
}
printf("wrlock wait done\n");
}
/* End of wraptest.c */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment