added linked list and part of barrier

This commit is contained in:
Juan Antonio Hernández Cánovas 2018-08-24 00:36:49 +02:00
parent 3513c91c3c
commit a9d95be173
4 changed files with 234 additions and 0 deletions

View File

@ -0,0 +1,24 @@
/**
* @file barrier.h
* @brief Barrier synchronization primitive.
* @author Yordrar
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "condvar.h"
#include "mutex.h"
#include "../runtime/util/list.h"
typedef struct barrier {
List threads_registered;
List threads_waiting;
RwLock mutex;
bool isInited;
} Barrier;
void barrierInit(Barrier* b);
void barrierFree(Barrier* b);
void barrierRegister(Barrier* b, Thread* thread);
void barrierUnregister(Barrier* b, Thread* thread);
void barrierWait(Barrier* b, Thread* thread);

View File

@ -0,0 +1,35 @@
/**
* @file list.h
* @brief Singly Linked List data structure.
* @author Yordrar
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../kernel/condvar.h"
#include "../kernel/mutex.h"
typedef struct node {
void* item;
Node* next;
} Node;
typedef struct list {
Node* header;
Node* last;
u32 num_nodes;
RwLock mutex;
bool isInited;
} List;
void listInit(List* l);
void listFree(List* l);
void listInsert(List* l, void* item, u32 pos);
static inline void listInsertFirst(List* l, void* item) {
listInsert(l, item, 0);
}
void listInsertLast(List* l, void* item);
void listDelete(List* l, void* item);
bool listIsInserted(List* l, void* item);
u32 listGetNumNodes(List* l);
void* listGetItem(List* l, u32 pos);

View File

@ -0,0 +1,39 @@
#include "kernel/barrier.h"
void barrierInit(Barrier* b) {
rwlockWriteLock(b->mutex);
if(b->isInited) {
return;
}
listInit(b->threads_registered);
listInit(b->threads_waiting);
b->isInited = true;
rwlockWriteUnlock(b->mutex);
}
void barrierFree(Barrier* b);
void barrierRegister(Barrier* b, Thread* thread) {
if(listIsInserted(b->threads_registered, (void*)thread)) {
return;
}
listInsertLast(b->threads_registered, (void*)thread);
}
void barrierUnregister(Barrier* b, Thread* thread) {
listDelete(b->threads_registered, (void*)thread);
}
void barrierWait(Barrier* b, Thread* thread) {
if(!listIsInserted(b->threads_registered)) {
return;
}
threadPause((void*)thread);
listInsertLast(b->threads_waiting, thread);
if(listGetNumNodes(b->threads_registered) == listGetNumNodes(b->threads_waiting)) {
while(listGetNumNodes(b->threads_waiting) > 0) {
threadResume(listGetItem(b->threads_waiting, 0));
}
}
}

View File

@ -0,0 +1,136 @@
#include "runtime/util/list.h"
#include <stdlib.h>
void listInit(List* l) {
rwlockWriteLock(l->mutex);
if(l->isInited) {
return;
}
Node* header = (Node*)malloc(sizeof(Node));
header->item = NULL;
header->next = NULL;
l->header = header;
l->last = header;
l->num_nodes = 0;
l->isInited = true;
rwlockWriteUnlock(l->mutex);
}
void listFree(List* l) {
rwlockWriteLock(l->mutex);
if(!l->isInited) {
return;
}
Node* aux = l->header;
while(aux != NULL) {
free(aux);
aux = aux->next;
}
l->header = NULL;
l->last = NULL;
l->num_nodes = 0;
l->isInited = false;
rwlockWriteUnlock(l->mutex);
}
void listInsert(List* l, void* item, u32 pos) {
rwlockReadLock(l->mutex);
if(!l->isInited) {
return;
}
if(pos > l->num_nodes || pos < 0) {
return;
}
rwlockReadUnlock(l->mutex);
rwlockWriteLock(l->mutex);
Node* aux = l->header;
for(u32 i = pos; i > 0; i--) {
aux = aux->next;
}
Node* new = (Node*)malloc(sizeof(Node));
new->item = item;
new->next = aux->next;
aux->next = new;
l->num_nodes++;
rwlockWriteUnlock(l->mutex);
}
void listInsertLast(List* l, void* item) {
rwlockWriteLock(l->mutex);
if(!l->isInited) {
return;
}
Node* new = (Node*)malloc(sizeof(Node));
new->item = item;
new->next = NULL;
l->last->next = new;
l->last = new;
rwlockWriteUnlock(l->mutex);
}
void listDelete(List* l, void* item) {
rwlockWriteLock(l->mutex);
if(!l->isInited) {
return;
}
Node* aux = l->header;
while(aux->next != NULL && aux->next->item != item) {
aux = aux->next;
}
if(aux->next != NULL && aux->next->item == item) {
Node* delete = aux->next;
aux->next = delete->next;
free(delete);
l->num_nodes--;
}
rwlockWriteUnlock(l->mutex);
}
bool listIsInserted(List* l, void* item) {
rwlockReadLock(l->mutex);
if(!l->isInited) {
return;
}
Node* aux = l->header;
while(aux != NULL && aux->item != item) {
aux = aux->next;
}
bool result = aux == NULL ? false : true;
rwlockReadUnlock(l->mutex);
return result;
}
u32 listGetNumNodes(List* l) {
rwlockReadLock(l->mutex);
if(!l->isInited) {
return;
}
u32 result = l->num_nodes;
rwlockReadUnlock(l->mutex);
return result;
}
void* listGetItem(List* l, u32 pos) {
rwlockReadLock(l->mutex);
if(!l->isInited) {
return;
}
if(pos >= l->num_nodes || pos < 0) {
return;
}
Node* aux = l->header->next;
for(u32 i = pos; i > 0; i--) {
aux = aux->next;
}
void* result = aux->item;
rwlockReadUnlock(l->mutex);
return result;
}