Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/patches/ASST1-sol/sol10.patch
2096 views
1
diff --git a/kern/include/synch.h b/kern/include/synch.h
2
index ac3714b..461eedc 100644
3
--- a/kern/include/synch.h
4
+++ b/kern/include/synch.h
5
@@ -74,8 +74,12 @@ void V(struct semaphore *);
6
*/
7
struct lock {
8
char *lk_name;
9
- // add what you need here
10
- // (don't forget to mark things volatile as needed)
11
+
12
+ // BEGIN SOLUTION
13
+ struct wchan *lk_wchan;
14
+ struct spinlock lk_lock;
15
+ volatile struct thread *lk_holder;
16
+ // END SOLUTION
17
};
18
19
struct lock *lock_create(const char *name);
20
@@ -113,8 +117,10 @@ void lock_destroy(struct lock *);
21
22
struct cv {
23
char *cv_name;
24
- // add what you need here
25
- // (don't forget to mark things volatile as needed)
26
+
27
+ // BEGIN SOLUTION
28
+ struct wchan *cv_wchan;
29
+ // END SOLUTION
30
};
31
32
struct cv *cv_create(const char *name);
33
diff --git a/kern/include/version.h b/kern/include/version.h
34
index 9fec0e8..4734a98 100644
35
--- a/kern/include/version.h
36
+++ b/kern/include/version.h
37
@@ -35,6 +35,7 @@
38
* code we gave you.
39
*/
40
#define BASE_VERSION "1.99.05"
41
+#define ASST1SOL_VERSION "1.0"
42
43
/*
44
* Change this as you see fit in the course of hacking the system.
45
diff --git a/kern/startup/main.c b/kern/startup/main.c
46
index be4c4b8..535a864 100644
47
--- a/kern/startup/main.c
48
+++ b/kern/startup/main.c
49
@@ -96,7 +96,7 @@ boot(void)
50
*/
51
52
kprintf("\n");
53
- kprintf("OS/161 base system version %s\n", BASE_VERSION);
54
+ kprintf("OS/161 base version %s ASST1 solution version %s\n", BASE_VERSION, ASST1SOL_VERSION);
55
kprintf("%s", harvard_copyright);
56
kprintf("\n");
57
58
diff --git a/kern/thread/synch.c b/kern/thread/synch.c
59
index 9a7468c..fb983b4 100644
60
--- a/kern/thread/synch.c
61
+++ b/kern/thread/synch.c
62
@@ -163,7 +163,16 @@ lock_create(const char *name)
63
return NULL;
64
}
65
66
- // add stuff here as needed
67
+ // BEGIN SOLUTION
68
+ lock->lk_wchan = wchan_create(lock->lk_name);
69
+ if (lock->lk_wchan == NULL) {
70
+ kfree(lock->lk_name);
71
+ kfree(lock);
72
+ return NULL;
73
+ }
74
+ spinlock_init(&lock->lk_lock);
75
+ lock->lk_holder = NULL;
76
+ // END SOLUTION
77
78
return lock;
79
}
80
@@ -173,7 +182,11 @@ lock_destroy(struct lock *lock)
81
{
82
KASSERT(lock != NULL);
83
84
- // add stuff here as needed
85
+ // BEGIN SOLUTION
86
+ KASSERT(lock->lk_holder == NULL);
87
+ spinlock_cleanup(&lock->lk_lock);
88
+ wchan_destroy(lock->lk_wchan);
89
+ // END SOLUTION
90
91
kfree(lock->lk_name);
92
kfree(lock);
93
@@ -182,27 +195,52 @@ lock_destroy(struct lock *lock)
94
void
95
lock_acquire(struct lock *lock)
96
{
97
- // Write this
98
+ // BEGIN SOLUTION
99
+ DEBUGASSERT(lock != NULL);
100
+ KASSERT(curthread->t_in_interrupt == false);
101
+
102
+ spinlock_acquire(&lock->lk_lock);
103
+ while (lock->lk_holder != NULL) {
104
+ /* As in the semaphore. */
105
+ wchan_lock(lock->lk_wchan);
106
+ spinlock_release(&lock->lk_lock);
107
+ wchan_sleep(lock->lk_wchan);
108
+
109
+ spinlock_acquire(&lock->lk_lock);
110
+ }
111
112
- (void)lock; // suppress warning until code gets written
113
+ lock->lk_holder = curthread;
114
+ spinlock_release(&lock->lk_lock);
115
+ // END SOLUTION
116
}
117
118
void
119
lock_release(struct lock *lock)
120
{
121
- // Write this
122
-
123
- (void)lock; // suppress warning until code gets written
124
+ // BEGIN SOLUTION
125
+ DEBUGASSERT(lock != NULL);
126
+
127
+ spinlock_acquire(&lock->lk_lock);
128
+ lock->lk_holder = NULL;
129
+ wchan_wakeone(lock->lk_wchan);
130
+ spinlock_release(&lock->lk_lock);
131
+ // END SOLUTION
132
}
133
134
bool
135
lock_do_i_hold(struct lock *lock)
136
{
137
- // Write this
138
+ // BEGIN SOLUTION
139
+ bool ret;
140
141
- (void)lock; // suppress warning until code gets written
142
+ DEBUGASSERT(lock != NULL);
143
144
- return true; // dummy until code gets written
145
+ spinlock_acquire(&lock->lk_lock);
146
+ ret = (lock->lk_holder == curthread);
147
+ spinlock_release(&lock->lk_lock);
148
+
149
+ return ret;
150
+ // END SOLUTION
151
}
152
153
////////////////////////////////////////////////////////////
154
@@ -226,7 +264,14 @@ cv_create(const char *name)
155
return NULL;
156
}
157
158
- // add stuff here as needed
159
+ // BEGIN SOLUTION
160
+ cv->cv_wchan = wchan_create(cv->cv_name);
161
+ if (cv->cv_wchan == NULL) {
162
+ kfree(cv->cv_name);
163
+ kfree(cv);
164
+ return NULL;
165
+ }
166
+ // END SOLUTION
167
168
return cv;
169
}
170
@@ -236,7 +281,9 @@ cv_destroy(struct cv *cv)
171
{
172
KASSERT(cv != NULL);
173
174
- // add stuff here as needed
175
+ // BEGIN SOLUTION
176
+ wchan_destroy(cv->cv_wchan);
177
+ // END SOLUTION
178
179
kfree(cv->cv_name);
180
kfree(cv);
181
@@ -245,23 +292,28 @@ cv_destroy(struct cv *cv)
182
void
183
cv_wait(struct cv *cv, struct lock *lock)
184
{
185
- // Write this
186
- (void)cv; // suppress warning until code gets written
187
- (void)lock; // suppress warning until code gets written
188
+ // BEGIN SOLUTION
189
+ wchan_lock(cv->cv_wchan);
190
+ lock_release(lock);
191
+ wchan_sleep(cv->cv_wchan);
192
+ lock_release(lock);
193
+ // END SOLUTION
194
}
195
-
196
+
197
void
198
cv_signal(struct cv *cv, struct lock *lock)
199
{
200
- // Write this
201
- (void)cv; // suppress warning until code gets written
202
- (void)lock; // suppress warning until code gets written
203
+ // BEGIN SOLUTION
204
+ (void)lock;
205
+ wchan_wakeone(cv->cv_wchan);
206
+ // END SOLUTION
207
}
208
-
209
+
210
void
211
cv_broadcast(struct cv *cv, struct lock *lock)
212
{
213
- // Write this
214
- (void)cv; // suppress warning until code gets written
215
- (void)lock; // suppress warning until code gets written
216
+ // BEGIN SOLUTION
217
+ (void)lock;
218
+ wchan_wakeall(cv->cv_wchan);
219
+ // END SOLUTION
220
}
221
222