aboutsummaryrefslogtreecommitdiffstats
path: root/src/threads/synchlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/threads/synchlist.c')
-rw-r--r--src/threads/synchlist.c98
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;
+}
+