summaryrefslogtreecommitdiffstats
path: root/04_exercise/rwlock/rwlock.c
blob: 3de5083e15088f65a838f42b385219084426fa53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//
// 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);
    }
    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);
    }
    if (sched_yield() < 0) {
        perror("Couldn't sleep. This shouldn't happen.");
        exit(-1);
    }
}