lab3.1: locks

This commit is contained in:
QcFe [PDS] 2020-05-28 15:27:02 +02:00
parent 1b82f81d8c
commit 8fcc6b0ea4
4 changed files with 78 additions and 5 deletions

View File

@ -30,3 +30,6 @@ options sfs # Always use the file system
#options netfs # You might write this as a project. #options netfs # You might write this as a project.
options dumbvm # Chewing gum and baling wire. options dumbvm # Chewing gum and baling wire.
#options semlock #locks with semaphores
options wchanlock #locks with wchans

View File

@ -444,6 +444,9 @@ optfile net test/nettest.c
defoption hello defoption hello
optfile hello main/hello.c optfile hello main/hello.c
defoption semlock
defoption wchanlock
# LAB2 # LAB2
file syscall/file_syscalls.c file syscall/file_syscalls.c
file syscall/proc_syscalls.c file syscall/proc_syscalls.c

View File

@ -37,6 +37,9 @@
#include <spinlock.h> #include <spinlock.h>
#include "opt-semlock.h"
#include "opt-wchanlock.h"
/* /*
* Dijkstra-style semaphore. * Dijkstra-style semaphore.
* *
@ -72,10 +75,19 @@ void V(struct semaphore *);
* The name field is for easier debugging. A copy of the name is * The name field is for easier debugging. A copy of the name is
* (should be) made internally. * (should be) made internally.
*/ */
struct lock { struct lock {
char *lk_name; char *lk_name;
volatile struct thread *owner;
#if OPT_SEMLOCK
struct semaphore *sem;
#elif OPT_WCHANLOCK
struct spinlock slk;
struct wchan *wchan;
#else
// add what you need here // add what you need here
// (don't forget to mark things volatile as needed) // (don't forget to mark things volatile as needed)
#endif
}; };
struct lock *lock_create(const char *name); struct lock *lock_create(const char *name);

View File

@ -156,6 +156,24 @@ lock_create(const char *name)
// add stuff here as needed // add stuff here as needed
#if OPT_SEMLOCK
lock->sem = sem_create(name, 1);
if (lock->sem == NULL) {
kfree(lock->lk_name);
kfree(lock);
return NULL;
}
#elif OPT_WCHANLOCK
lock->wchan = wchan_create(lock->lk_name);
if (lock->wchan == NULL) {
kfree(lock->lk_name);
kfree(lock);
return NULL;
}
spinlock_init(&lock->slk);
#endif
lock->owner = NULL;
return lock; return lock;
} }
@ -167,6 +185,12 @@ lock_destroy(struct lock *lock)
// add stuff here as needed // add stuff here as needed
kfree(lock->lk_name); kfree(lock->lk_name);
#if OPT_SEMLOCK
sem_destroy(lock->sem);
#elif OPT_WCHANLOCK
wchan_destroy(lock->wchan);
spinlock_cleanup(&lock->slk);
#endif
kfree(lock); kfree(lock);
} }
@ -175,7 +199,19 @@ lock_acquire(struct lock *lock)
{ {
// Write this // Write this
(void)lock; // suppress warning until code gets written #if OPT_SEMLOCK
P(lock->sem);
lock->owner = curthread;
#elif OPT_WCHANLOCK
spinlock_acquire(&lock->slk);
while (lock->owner != NULL) {
wchan_sleep(lock->wchan, &lock->slk);
}
lock->owner = curthread;
spinlock_release(&lock->slk);
#else
lock->owner = curthread;
#endif
} }
void void
@ -183,17 +219,36 @@ lock_release(struct lock *lock)
{ {
// Write this // Write this
(void)lock; // suppress warning until code gets written KASSERT(lock != NULL);
KASSERT(lock_do_i_hold(lock));
#if OPT_SEMLOCK
lock->owner = NULL;
V(lock->sem);
#elif OPT_WCHANLOCK
spinlock_acquire(&lock->slk);
lock->owner = NULL;
wchan_wakeall(lock->wchan, &lock->slk);
spinlock_release(&lock->slk);
#else
lock->owner = NULL;
#endif
} }
bool bool
lock_do_i_hold(struct lock *lock) lock_do_i_hold(struct lock *lock)
{ {
// Write this // Write this
KASSERT(lock != NULL);
#if OPT_WCHANLOCK
bool ret = true;
spinlock_acquire(&lock->slk);
ret = lock->owner == curthread;
spinlock_release(&lock->slk);
return ret; // dummy until code gets written
#else
return lock->owner == curthread;
#endif
(void)lock; // suppress warning until code gets written
return true; // dummy until code gets written
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////