// // Created by stefan on 11.06.20. // #include "rwlock.h" #include #include #include #include static const bool DEBUG = false; void rwLockWrite(atomic_char *lock) { char status; bool succeeded; do { status = RW_UNLOCKED; succeeded = atomic_compare_exchange_weak(lock, &status, RW_WRITE_LOCKED); } while (!succeeded); if(DEBUG) { fprintf(stderr, "Thread %lu: Aquired Write Lock \n", pthread_self() % 1000); } } void rwUnlockWrite(atomic_char *lock) { char expected = RW_WRITE_LOCKED; if (!atomic_compare_exchange_strong(lock, &expected, RW_UNLOCKED)) { fprintf(stderr, "Couldn't unlock from writelock. Lock was at %d", expected); perror("Lock got into undefined state"); exit(-1); } if(DEBUG) { fprintf(stderr, "Thread %lu: Released Write Lock \n", pthread_self() % 1000); } // Avoid starvation of readers/all other threads if (sched_yield() < 0) { perror("Couldn't sleep. This shouldn't happen."); exit(-1); } } void rwLockRead(atomic_char *lock) { while (atomic_load(lock) == RW_WRITE_LOCKED) { } atomic_fetch_add(lock, 1); if(DEBUG) { fprintf(stderr, "Thread %lu: Aquired Read Lock \n", pthread_self() % 1000); } } void rwUnlockRead(atomic_char *lock) { char value = atomic_load(lock); if (value < 1) { fprintf(stderr, "Couldn't unlock from readlock. Lock was at %d", value); perror("Lock got into undefined state"); exit(-1); } atomic_fetch_sub(lock, 1); if(DEBUG) { fprintf(stderr, "Thread %lu: Released Read Lock \n", pthread_self() % 1000); } // Avoid starvation of writer/all other threads if (sched_yield() < 0) { perror("Couldn't sleep. This shouldn't happen."); exit(-1); } }