-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmutex.c
More file actions
64 lines (60 loc) · 1.55 KB
/
mutex.c
File metadata and controls
64 lines (60 loc) · 1.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//
// Created by dcat on 9/3/17.
//
#include <system.h>
#include <str.h>
#include <proc.h>
#include <timer.h>
#include <mutex.h>
#include <schedule.h>
#include <signal.h>
#include "mutex.h"
void mutex_init(mutex_lock_t *m) {
m->mutex = 1;
m->holdpid = 0;
memset(&m->wait_queue, 0, sizeof(proc_queue_t));
}
//FIXME some bug...
void mutex_lock(mutex_lock_t *m) {
int ints;
pcb_t *pcb = getpcb(getpid());
ASSERT(pcb);
scli(&ints);
if (m->holdpid == getpid())return;
uint8_t al;
__asm__ __volatile__(""
"movb $0,%%al;"
"xchgb %%al,%0;"
"movb %%al,%1;"::"m"(m->mutex), "m"(al), "ax"(0));
if (al == 1) {
m->holdpid = getpid();
//dprintf("proc %x get lock:%x", pcb->pid, m);
srestorei(&ints);
return;
} else {
//suspend it
dprintf("proc %x wait lock:%x holding by %x", getpid(), m, m->holdpid);
set_proc_status(pcb, STATUS_WAIT);
CHK(proc_queue_insert(&m->wait_queue, pcb), "");
srestorei(&ints);
dprintf("reschedule");
do_schedule(NULL);
}
_err:
srestorei(&ints);
PANIC("exception happened.");
}
void mutex_unlock(mutex_lock_t *m) {
int ints;
scli(&ints);
if (m->holdpid != getpid())goto _ret;
//dprintf("proc %x release lck:%x", getpid(), m);
__asm__ __volatile__(""
"movb $1,%%al;"
"xchgb %%al,%0;"::"m"(m->mutex), "ax"(0));
proc_queue_wakeupall(&m->wait_queue, true);
m->holdpid = -1;
_ret:
srestorei(&ints);
//do_schedule(NULL);
}