tested code and documented it

This commit is contained in:
Juan Antonio Hernández Cánovas 2018-08-24 21:16:00 +02:00
parent e3a4e26875
commit b11e3b2e14
4 changed files with 95 additions and 46 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);
} }
} }

View File

@ -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--) {