mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-05 19:02:14 +02:00
tested code and documented it
This commit is contained in:
parent
e3a4e26875
commit
b11e3b2e14
@ -14,11 +14,36 @@ typedef struct barrier {
|
|||||||
List threads_registered;
|
List threads_registered;
|
||||||
List threads_waiting;
|
List threads_waiting;
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
bool isInited;
|
|
||||||
} Barrier;
|
} Barrier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory for a barrier
|
||||||
|
* @param b Barrier object
|
||||||
|
*/
|
||||||
void barrierInit(Barrier* b);
|
void barrierInit(Barrier* b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees the memory allocated for a barrier
|
||||||
|
* @param b Barrier object
|
||||||
|
*/
|
||||||
void barrierFree(Barrier* b);
|
void barrierFree(Barrier* b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Registers a thread that is going to use the specified barrier
|
||||||
|
* @param b Barrier object
|
||||||
|
* @param thread The thread to register
|
||||||
|
*/
|
||||||
void barrierRegister(Barrier* b, Thread* thread);
|
void barrierRegister(Barrier* b, Thread* thread);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unegisters a thread that is not going to use anymore the specified barrier
|
||||||
|
* @param b Barrier object
|
||||||
|
* @param thread The thread to unregister
|
||||||
|
*/
|
||||||
void barrierUnregister(Barrier* b, Thread* thread);
|
void barrierUnregister(Barrier* b, Thread* thread);
|
||||||
void barrierWait(Barrier* b, Thread* thread);
|
|
||||||
|
/**
|
||||||
|
* @brief Waits until all processes registered in the barrier call this function
|
||||||
|
* @param b Barrier object
|
||||||
|
*/
|
||||||
|
void barrierWait(Barrier* b);
|
||||||
|
@ -20,17 +20,70 @@ typedef struct list {
|
|||||||
Node* last;
|
Node* last;
|
||||||
u32 num_nodes;
|
u32 num_nodes;
|
||||||
RwLock mutex;
|
RwLock mutex;
|
||||||
bool isInited;
|
|
||||||
} List;
|
} List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates memory for a list
|
||||||
|
* @param l List object
|
||||||
|
*/
|
||||||
void listInit(List* l);
|
void listInit(List* l);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Frees memory allocated for a list
|
||||||
|
* @param l List object
|
||||||
|
*/
|
||||||
void listFree(List* l);
|
void listFree(List* l);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts something in a position
|
||||||
|
* @param l List object.
|
||||||
|
* @param item A pointer to the thing you want to insert
|
||||||
|
* @param pos The position to insert (0 is the first position)
|
||||||
|
*/
|
||||||
void listInsert(List* l, void* item, u32 pos);
|
void listInsert(List* l, void* item, u32 pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts something in the first position
|
||||||
|
* @param l List object.
|
||||||
|
* @param item A pointer to the thing you want to insert
|
||||||
|
*/
|
||||||
static inline void listInsertFirst(List* l, void* item) {
|
static inline void listInsertFirst(List* l, void* item) {
|
||||||
listInsert(l, item, 0);
|
listInsert(l, item, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inserts something at the end of the list
|
||||||
|
* @param l List object.
|
||||||
|
* @param item A pointer to the thing you want to insert
|
||||||
|
*/
|
||||||
void listInsertLast(List* l, void* item);
|
void listInsertLast(List* l, void* item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deletes the node of the list which has the item specified (makes a pointer comparison to ckeck that)
|
||||||
|
* @param l List object.
|
||||||
|
* @param item A pointer to the thing you want to delete
|
||||||
|
*/
|
||||||
void listDelete(List* l, void* item);
|
void listDelete(List* l, void* item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if the item is inserted in the list (makes a pointer comparison to ckeck that)
|
||||||
|
* @param l List object.
|
||||||
|
* @param item A pointer to the thing you want to check
|
||||||
|
* @return true if the item is in the list, false otherwise
|
||||||
|
*/
|
||||||
bool listIsInserted(List* l, void* item);
|
bool listIsInserted(List* l, void* item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of items inserted in the list
|
||||||
|
* @param l List object.
|
||||||
|
* @return The number of nodes (the number of inserted things) in the list
|
||||||
|
*/
|
||||||
u32 listGetNumNodes(List* l);
|
u32 listGetNumNodes(List* l);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the item inserted in an specified position
|
||||||
|
* @param l List object.
|
||||||
|
* @param pos The position of the item
|
||||||
|
* @return A pointer to that item, NULL if it isn't found
|
||||||
|
*/
|
||||||
void* listGetItem(List* l, u32 pos);
|
void* listGetItem(List* l, u32 pos);
|
@ -3,23 +3,15 @@
|
|||||||
void barrierInit(Barrier* b) {
|
void barrierInit(Barrier* b) {
|
||||||
mutexInit(&b->mutex);
|
mutexInit(&b->mutex);
|
||||||
mutexLock(&b->mutex);
|
mutexLock(&b->mutex);
|
||||||
if(b->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
listInit(&b->threads_registered);
|
listInit(&b->threads_registered);
|
||||||
listInit(&b->threads_waiting);
|
listInit(&b->threads_waiting);
|
||||||
b->isInited = true;
|
|
||||||
mutexUnlock(&b->mutex);
|
mutexUnlock(&b->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void barrierFree(Barrier* b) {
|
void barrierFree(Barrier* b) {
|
||||||
mutexLock(&b->mutex);
|
mutexLock(&b->mutex);
|
||||||
if(!b->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
listFree(&b->threads_registered);
|
listFree(&b->threads_registered);
|
||||||
listFree(&b->threads_waiting);
|
listFree(&b->threads_waiting);
|
||||||
b->isInited = false;
|
|
||||||
mutexUnlock(&b->mutex);
|
mutexUnlock(&b->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +27,8 @@ void barrierUnregister(Barrier* b, Thread* thread) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void barrierWait(Barrier* b, Thread* thread) {
|
void barrierWait(Barrier* b, Thread* thread) {
|
||||||
if(!listIsInserted(&b->threads_registered, thread)) {
|
Thread* thread = getThreadVars()->thread_ptr;
|
||||||
|
if(!listIsInserted(&b->threads_registered, (void*)thread)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,14 +36,14 @@ void barrierWait(Barrier* b, Thread* thread) {
|
|||||||
if(listGetNumNodes(&b->threads_registered) == listGetNumNodes(&b->threads_waiting)+1) {
|
if(listGetNumNodes(&b->threads_registered) == listGetNumNodes(&b->threads_waiting)+1) {
|
||||||
while(listGetNumNodes(&b->threads_waiting) > 0) {
|
while(listGetNumNodes(&b->threads_waiting) > 0) {
|
||||||
Thread* current_thread = listGetItem(&b->threads_waiting, 0);
|
Thread* current_thread = listGetItem(&b->threads_waiting, 0);
|
||||||
threadResume(current_thread);
|
svcSetThreadActivity(current_thread->handle, 0);
|
||||||
listDelete(&b->threads_waiting, current_thread);
|
listDelete(&b->threads_waiting, (void*)current_thread);
|
||||||
}
|
}
|
||||||
mutexUnlock(&b->mutex);
|
mutexUnlock(&b->mutex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
listInsertLast(&b->threads_waiting, thread);
|
listInsertLast(&b->threads_waiting, (void*)thread);
|
||||||
mutexUnlock(&b->mutex);
|
mutexUnlock(&b->mutex);
|
||||||
threadPause((void*)thread);
|
svcSleepThread(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,10 +2,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void listInit(List* l) {
|
void listInit(List* l) {
|
||||||
|
rwlockInit(&l->mutex);
|
||||||
rwlockWriteLock(&l->mutex);
|
rwlockWriteLock(&l->mutex);
|
||||||
if(l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Node* header = (Node*)malloc(sizeof(Node));
|
Node* header = (Node*)malloc(sizeof(Node));
|
||||||
header->item = NULL;
|
header->item = NULL;
|
||||||
header->next = NULL;
|
header->next = NULL;
|
||||||
@ -13,32 +11,25 @@ void listInit(List* l) {
|
|||||||
l->header = header;
|
l->header = header;
|
||||||
l->last = header;
|
l->last = header;
|
||||||
l->num_nodes = 0;
|
l->num_nodes = 0;
|
||||||
l->isInited = true;
|
|
||||||
rwlockWriteUnlock(&l->mutex);
|
rwlockWriteUnlock(&l->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void listFree(List* l) {
|
void listFree(List* l) {
|
||||||
rwlockWriteLock(&l->mutex);
|
rwlockWriteLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Node* aux = l->header;
|
Node* aux = l->header;
|
||||||
while(aux != NULL) {
|
while(aux != NULL) {
|
||||||
free(aux);
|
Node* erase = aux;
|
||||||
aux = aux->next;
|
aux = aux->next;
|
||||||
|
free(erase);
|
||||||
}
|
}
|
||||||
l->header = NULL;
|
l->header = NULL;
|
||||||
l->last = NULL;
|
l->last = NULL;
|
||||||
l->num_nodes = 0;
|
l->num_nodes = 0;
|
||||||
l->isInited = false;
|
|
||||||
rwlockWriteUnlock(&l->mutex);
|
rwlockWriteUnlock(&l->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void listInsert(List* l, void* item, u32 pos) {
|
void listInsert(List* l, void* item, u32 pos) {
|
||||||
rwlockReadLock(&l->mutex);
|
rwlockReadLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(pos > l->num_nodes || pos < 0) {
|
if(pos > l->num_nodes || pos < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -49,25 +40,24 @@ void listInsert(List* l, void* item, u32 pos) {
|
|||||||
for(u32 i = pos; i > 0; i--) {
|
for(u32 i = pos; i > 0; i--) {
|
||||||
aux = aux->next;
|
aux = aux->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* new = (Node*)malloc(sizeof(Node));
|
Node* new = (Node*)malloc(sizeof(Node));
|
||||||
new->item = item;
|
new->item = item;
|
||||||
new->next = aux->next;
|
new->next = aux->next;
|
||||||
aux->next = new;
|
aux->next = new;
|
||||||
|
|
||||||
|
if(pos == l->num_nodes) {
|
||||||
|
l->last = new;
|
||||||
|
}
|
||||||
|
|
||||||
l->num_nodes++;
|
l->num_nodes++;
|
||||||
rwlockWriteUnlock(&l->mutex);
|
rwlockWriteUnlock(&l->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void listInsertLast(List* l, void* item) {
|
void listInsertLast(List* l, void* item) {
|
||||||
rwlockWriteLock(&l->mutex);
|
rwlockWriteLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Node* new = (Node*)malloc(sizeof(Node));
|
Node* new = (Node*)malloc(sizeof(Node));
|
||||||
new->item = item;
|
new->item = item;
|
||||||
new->next = NULL;
|
new->next = NULL;
|
||||||
|
|
||||||
l->last->next = new;
|
l->last->next = new;
|
||||||
l->last = new;
|
l->last = new;
|
||||||
rwlockWriteUnlock(&l->mutex);
|
rwlockWriteUnlock(&l->mutex);
|
||||||
@ -75,9 +65,6 @@ void listInsertLast(List* l, void* item) {
|
|||||||
|
|
||||||
void listDelete(List* l, void* item) {
|
void listDelete(List* l, void* item) {
|
||||||
rwlockWriteLock(&l->mutex);
|
rwlockWriteLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node* aux = l->header;
|
Node* aux = l->header;
|
||||||
while(aux->next != NULL && aux->next->item != item) {
|
while(aux->next != NULL && aux->next->item != item) {
|
||||||
@ -96,9 +83,6 @@ void listDelete(List* l, void* item) {
|
|||||||
|
|
||||||
bool listIsInserted(List* l, void* item) {
|
bool listIsInserted(List* l, void* item) {
|
||||||
rwlockReadLock(&l->mutex);
|
rwlockReadLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Node* aux = l->header;
|
Node* aux = l->header;
|
||||||
while(aux != NULL && aux->item != item) {
|
while(aux != NULL && aux->item != item) {
|
||||||
aux = aux->next;
|
aux = aux->next;
|
||||||
@ -110,9 +94,6 @@ bool listIsInserted(List* l, void* item) {
|
|||||||
|
|
||||||
u32 listGetNumNodes(List* l) {
|
u32 listGetNumNodes(List* l) {
|
||||||
rwlockReadLock(&l->mutex);
|
rwlockReadLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
u32 result = l->num_nodes;
|
u32 result = l->num_nodes;
|
||||||
rwlockReadUnlock(&l->mutex);
|
rwlockReadUnlock(&l->mutex);
|
||||||
return result;
|
return result;
|
||||||
@ -120,11 +101,8 @@ u32 listGetNumNodes(List* l) {
|
|||||||
|
|
||||||
void* listGetItem(List* l, u32 pos) {
|
void* listGetItem(List* l, u32 pos) {
|
||||||
rwlockReadLock(&l->mutex);
|
rwlockReadLock(&l->mutex);
|
||||||
if(!l->isInited) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(pos >= l->num_nodes || pos < 0) {
|
if(pos >= l->num_nodes || pos < 0) {
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
Node* aux = l->header->next;
|
Node* aux = l->header->next;
|
||||||
for(u32 i = pos; i > 0; i--) {
|
for(u32 i = pos; i > 0; i--) {
|
||||||
|
Loading…
Reference in New Issue
Block a user