blob: 941d176d431961847c454885cdfb271f4d096188 (
plain) (
tree)
|
|
//
// Created by stefan on 11.06.20.
//
#include "rwlock.h"
#include <stdbool.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
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);
}
}
|