diff options
Diffstat (limited to 'src/threads')
| -rw-r--r-- | src/threads/synch.c | 40 | ||||
| -rw-r--r-- | src/threads/synch.h | 17 | ||||
| -rw-r--r-- | src/threads/thread.c | 4 | ||||
| -rw-r--r-- | src/threads/thread.h | 26 |
4 files changed, 87 insertions, 0 deletions
diff --git a/src/threads/synch.c b/src/threads/synch.c index 317c68a..e714ce0 100644 --- a/src/threads/synch.c +++ b/src/threads/synch.c @@ -336,3 +336,43 @@ cond_broadcast (struct condition *cond, struct lock *lock) while (!list_empty (&cond->waiters)) cond_signal (cond, lock); } + +void +rwlock_init (struct rwlock *rwlock) +{ + sema_init (&rwlock->resource, 1); + lock_init (&rwlock->rmutex); + rwlock->readcount = 0; +} + +void +rwlock_write_p (struct rwlock *rwlock) +{ + sema_down (&rwlock->resource); +} + +void +rwlock_write_v (struct rwlock *rwlock) +{ + sema_up (&rwlock->resource); +} + +void +rwlock_read_p (struct rwlock *rwlock) +{ + lock_acquire (&rwlock->rmutex); + rwlock->readcount ++; + if (rwlock->readcount == 1) + sema_down (&rwlock->resource); + lock_release (&rwlock->rmutex); +} + +void +rwlock_read_v (struct rwlock *rwlock) +{ + lock_acquire (&rwlock->rmutex); + rwlock->readcount --; + if (rwlock->readcount == 0) + sema_up (&rwlock->resource); + lock_release (&rwlock->rmutex); +} diff --git a/src/threads/synch.h b/src/threads/synch.h index a19e88b..a76eecc 100644 --- a/src/threads/synch.h +++ b/src/threads/synch.h @@ -41,6 +41,23 @@ void cond_wait (struct condition *, struct lock *); void cond_signal (struct condition *, struct lock *); void cond_broadcast (struct condition *, struct lock *); +/* Readers-writers lock. + + Implementation of "First readers-writers problem" from + https://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem. */ +struct rwlock + { + struct semaphore resource; + struct lock rmutex; + unsigned readcount; + }; + +void rwlock_init (struct rwlock *); +void rwlock_write_p (struct rwlock *); +void rwlock_write_v (struct rwlock *); +void rwlock_read_p (struct rwlock *); +void rwlock_read_v (struct rwlock *); + /* Optimization barrier. The compiler will not reorder operations across an diff --git a/src/threads/thread.c b/src/threads/thread.c index 92d1aa8..3112a71 100644 --- a/src/threads/thread.c +++ b/src/threads/thread.c @@ -13,6 +13,7 @@ #include "threads/vaddr.h" #ifdef USERPROG #include "userprog/process.h" +#include "threads/malloc.h" #endif /* Random value for struct thread's `magic' member. @@ -435,6 +436,9 @@ init_thread (struct thread *t, const char *name, int priority) strlcpy (t->name, name, sizeof t->name); t->stack = (uint8_t *) t + PGSIZE; t->priority = priority; +#ifdef USERPROG + list_init (&t->children); +#endif t->magic = THREAD_MAGIC; } diff --git a/src/threads/thread.h b/src/threads/thread.h index 0039560..a3bc814 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -4,6 +4,9 @@ #include <debug.h> #include <list.h> #include <stdint.h> +#include "threads/synch.h" + +#define MAX_FDS 128 /* Max number of file descriptors per thread */ /* States in a thread's life cycle. */ enum thread_status @@ -19,6 +22,23 @@ enum thread_status typedef int tid_t; #define TID_ERROR ((tid_t) -1) /* Error value for tid_t. */ +/* The relationship between a parent and child process. + The child reports its exit status by setting exit_status. + The parent places the parent_child element in its list of children. +*/ +struct parent_child + { + struct list_elem elem; // owned by the parent + + // exit_status is readable by the parent + struct semaphore exit_sema; + int exit_status; + + struct lock l; + int alive_count; + tid_t child_tid; + }; + /* Thread priorities. */ #define PRI_MIN 0 /* Lowest priority. */ #define PRI_DEFAULT 31 /* Default priority. */ @@ -80,6 +100,7 @@ typedef int tid_t; only because they are mutually exclusive: only a thread in the ready state is on the run queue, whereas only a thread in the blocked state is on a semaphore wait list. */ + struct thread { /* Owned by thread.c. */ @@ -95,6 +116,11 @@ struct thread #ifdef USERPROG /* Owned by userprog/process.c. */ uint32_t *pagedir; /* Page directory. */ + struct file **fds; /* Pointer to array of file descriptors. */ + bool load_success; + + struct parent_child *parent; // one parent + struct list children; // multiple children #endif /* Owned by thread.c. */ |
