diff options
Diffstat (limited to 'src/threads/synchlist.c')
| -rw-r--r-- | src/threads/synchlist.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/threads/synchlist.c b/src/threads/synchlist.c new file mode 100644 index 0000000..cc1e570 --- /dev/null +++ b/src/threads/synchlist.c @@ -0,0 +1,98 @@ +// synchlist.cc +// Routines for synchronized access to a list. +// +// Implemented by surrounding the List abstraction +// with synchronization routines. +// +// Implemented in "monitor"-style -- surround each procedure with a +// lock acquire and release pair, using condition signal and wait for +// synchronization. +// +// Copyright (c) 1992-1993 The Regents of the University of California. +// All rights reserved. See copyright.h for copyright notice and limitation +// of liability and disclaimer of warranty provisions. +// +// modified by Vlad Jahundovics for Pintos (translation from C++ to C) + + +#include "copyright.h" +#include "synchlist.h" +#include "threads/malloc.h" + +//---------------------------------------------------------------------- +// SynchList::SynchList +// Initialize the data structures needed for a +// synchronized list, empty to start with. +// Elements can now be added to the list. +//---------------------------------------------------------------------- + +void sl_init(struct SynchList *sl) +{ + list_init(&sl->sl_list); + lock_init(&sl->sl_lock); + cond_init(&sl->sl_empty); +} + + +//---------------------------------------------------------------------- +// SynchList::~SynchList +// Remove and de-allocate all elements of the synchronized list +//---------------------------------------------------------------------- + +void sl_destroy(struct SynchList *sl) +{ + struct list_elem *e; + struct SL_element *sl_elem; + while(!list_empty(&sl->sl_list)){ + e = list_pop_front(&sl->sl_list); + sl_elem = list_entry(e, struct SL_element, elem); + free(sl_elem); + } +} + + +//---------------------------------------------------------------------- +// SynchList::Append +// Append an "item" to the end of the list. Wake up anyone +// waiting for an element to be appended. +// +// "item" is the thing to put on the list, it can be a pointer to +// anything. +//---------------------------------------------------------------------- + +void sl_append(struct SynchList *sl, void *item) +{ + lock_acquire(&sl->sl_lock); // enforce mutual exclusive access to the list + struct SL_element *sl_elem = malloc(sizeof(struct SL_element)); + sl_elem->item = item; + list_push_back(&sl->sl_list, &sl_elem->elem); + cond_signal(&sl->sl_empty,&sl->sl_lock); // wake up a waiter, if any + lock_release(&sl->sl_lock); + return; +} + + +//---------------------------------------------------------------------- +// SynchList::Remove +// Remove an "item" from the beginning of the list. Wait if +// the list is empty. +// Returns: +// The removed item. +//---------------------------------------------------------------------- + +void *sl_remove(struct SynchList *sl) +{ + struct list_elem *e; + void *item; + lock_acquire(&sl->sl_lock); // enforce mutual exclusion + while(list_empty(&sl->sl_list)){ + cond_wait(&sl->sl_empty, &sl->sl_lock); // wait until list isn't empty + } + e = list_pop_front(&sl->sl_list); + struct SL_element *sl_elem = list_entry(e, struct SL_element, elem); + item = sl_elem->item; + free(sl_elem); + lock_release(&sl->sl_lock); + return item; +} + |
