lab3.1: locks
This commit is contained in:
parent
1b82f81d8c
commit
8fcc6b0ea4
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user