Question 3 -- 10 points
Behold the following monitor/condition variable calls:
- Mon_t *mon_create() -- create and return a monitor.
- void mon_enter(Mon_t *) -- enter a monitor.
- void mon_exit(Mon_t *) -- exit a monitor.
- Cv_t *cv_create() -- create and return a condition variable.
- void cv_wait(Cv_t *, Mon_t *) -- wait on a condition variable.
- void cv_signal(Cv_t *) -- signal on a condition variable.
Implement the following general semaphore calls (also provide a typedef
for Gsem_t:
- Gsem_t *gsem_create(int) -- create and a semaphore with a
given value.
- void gsem_P(Gsem_t *) -- Call P() on the semaphore.
- void gsem_V(Gsem_t *) -- Call V() on the semaphore.
Don't worry about your #includes.
Answer
This is so straightforward it needs no explanation:
typedef struct {
Mon_t *m;
Cv_t *c;
int val;
} Gsem_t;
Gsem_t *gsem_create(int i)
{
Gsem_t *g;
if (i < 0) return NULL;
g = (Gsem_t *) malloc(sizeof(Gsem_t));
g->m = mon_create();
g->c = cv_create();
g->val = i;
return g;
}
void gsem_P(Gsem_t *g)
{
mon_enter(g->m);
g->val--;
if (g->val < 0) cv_wait(g->c, g->m);
mon_exit(g->m);
}
void gsem_V(Gsem_t *g)
{
mon_enter(g->m);
g->val++;
if (g->val <= 0) cv_signal(g->c);
mon_exit(g->m);
}
Grading
This was a very simple problem. Basically, you started at 10 points,
and lost points for the following:
- A: You omitted monitors entirely. 5 points.
- B: You didn't use the monitors correctly. 3 points.
- C: You use a while instead of an if in
gsem_P(): 2 points.
- D: You waited in gsem_V(): 2 points.
- E: You decrement after calling wait() in gsem_P()
(and it's protected by g->val < 0): 1 point.
- F: You mixed up your < and <='s: 1 point.
If your answer didn't really make any sense, but you had the struct
set up right, I gave you two points.
Histogram