summaryrefslogtreecommitdiffstats
path: root/04_exercise/arena/arena_list.c
diff options
context:
space:
mode:
Diffstat (limited to '04_exercise/arena/arena_list.c')
-rw-r--r--04_exercise/arena/arena_list.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/04_exercise/arena/arena_list.c b/04_exercise/arena/arena_list.c
index 4becef6..73b126c 100644
--- a/04_exercise/arena/arena_list.c
+++ b/04_exercise/arena/arena_list.c
@@ -3,12 +3,20 @@
//
#include "arena_list.h"
#include <pthread.h>
-#include <sched.h>
#include <stdio.h>
#include <unistd.h>
#include <rwlock.h>
+static const bool DEBUG = false;
+bool listContains(List const * const list ,Node const * const needle) {
+ for(Node * current = list ->first; current != NULL; current = current->next) {
+ if(current == needle) {
+ return true;
+ }
+ }
+ return false;
+}
Node *listPopFront(List *list) {
Node *front = list->first;
if (front == NULL) {
@@ -77,7 +85,8 @@ AtomicArenaList alInit(Node *arena, size_t size) {
}
int alPush(AtomicArenaList *al, void *value) {
- fprintf(stderr, "Thread %lu: Pushing \n", pthread_self() % 1000);
+ if(DEBUG)
+ fprintf(stderr, "Thread %lu: Pushing \n", pthread_self() % 1000);
rwLockWrite(&al->lock);
Node *current = listPopFront(&al->freeList);
// List is empty
@@ -92,43 +101,49 @@ int alPush(AtomicArenaList *al, void *value) {
}
int alRemoveElem(AtomicArenaList *al, void *value) {
- fprintf(stderr, "Thread %lu: Removing element \n", pthread_self() % 1000);
+ if(DEBUG)
+ fprintf(stderr, "Thread %lu: Removing element \n", pthread_self() % 1000);
rwLockWrite(&al->lock);
- for (size_t i = 0; i < al->size; ++i) {
+ size_t i = 0;
+ for (; i < al->size; ++i) {
if (al->arena[i].value != value) {
continue;
}
- Node *node = &al->arena[i];
- if (node == al->activeList.first) {
- listPopFront(&al->activeList);
- listPushFront(&al->freeList, node);
- atomic_char *a = &al->lock;
- rwUnlockWrite(a);
- return 0;
- }
- if (node == al->activeList.last) {
- listPopBack(&al->activeList);
- listPushFront(&al->freeList, node);
- rwUnlockWrite(&al->lock);
- return 0;
- }
- // The node is somewhere in the middle
- Node *prev = node->prev;
- Node *next = node->next;
-
- next->prev = prev;
- prev->next = next;
+ }
+ Node *node = &al->arena[i];
+ if(listContains(&al->activeList,node) || i == al->size) {
+ rwUnlockWrite(&al->lock);
+ return -1;
+ }
+ if (node == al->activeList.first) {
+ listPopFront(&al->activeList);
+ listPushFront(&al->freeList, node);
+ atomic_char *a = &al->lock;
+ rwUnlockWrite(a);
+ return 0;
+ }
+ if (node == al->activeList.last) {
+ listPopBack(&al->activeList);
listPushFront(&al->freeList, node);
rwUnlockWrite(&al->lock);
return 0;
}
+ // The node is somewhere in the middle
+ Node *prev = node->prev;
+ Node *next = node->next;
+
+ next->prev = prev;
+ prev->next = next;
+
+ listPushFront(&al->freeList, node);
rwUnlockWrite(&al->lock);
- return -1;
+ return 0;
}
void *alFindLastElem(AtomicArenaList *al, SearchFunction f) {
- fprintf(stderr, "Thread %lu: Finding last element \n", pthread_self() % 1000);
+ if(DEBUG)
+ fprintf(stderr, "Thread %lu: Finding last element \n", pthread_self() % 1000);
rwLockRead(&al->lock);