These problems should be done on your own. We're not going to be grading them strictly (we'll mainly look at whether you attempted them). But they will be reinforcing knowledge and skills, so you should totally work through them carefully.
// assume all the variables are initialized correctly
double alice_balance, bob_balance;
smutex_t mtx;
bool
transferBob2Alice(double trans) {
if (bob_balance > trans) {
smutex_lock(&mtx);
bob_balance = bob_balance - trans;
alice_balance = alice_balance + trans;
smutex_unlock(&mtx);
return true;
}
return false;
}
The implementation of function transferBob2Alice is not correct.
// assume all the variables are initialized correctly
double balance[2]; // 0 for alice, 1 for bob
smutex_t mtx[2]; // 0 for alice, 1 for bob
bool transfer(int from, int to, double trans) {
smutex_lock(&mtx[from]);
smutex_lock(&mtx[to]);
bool result = false;
if (balance[from] > trans) {
/*
* EDIT: corrected code is below. here is the original, typo'ed
* version
* balance[from] = balance[to] - trans;
* balance[from] = balance[to] + trans;
*/
balance[from] = balance[from] - trans;
balance[to] = balance[to] + trans;
result = true;
}
smutex_unlock(&mtx[to]);
smutex_unlock(&mtx[from]);
return result;
}
transfer() to
eliminate the possibility of deadlock
struct sharedlock {
int value; // when the lock is created, value is initialized to 0
};
reader_acquire(struct sharedlock*) reader_release(struct sharedlock*) writer_acquire(struct sharedlock*) writer_release(struct sharedlock*)We have given you the first of these, and your task is to write the last three of these. Each of these three functions only needs to be a single line of code.
reader_acquire() but have not
called reader_release()),
the lock's value equals the number of readers. writer_acquire() but has not called
writer_release()), its value is
-1.int cmpxchg_val(int* addr, int oldval, int newval): This is
an atomic operation that compares oldval to
*addr, and if the two are equal, it sets *addr =
newval. It returns the old contents of *addr.void atomic_decrement(int* arg): This atomically
performs *arg = *arg - 1.
// we are giving you the code for the first of the four functions:
void reader_acquire(struct sharedlock* lock) {
int curr_val;
while (1) {
// spin while a writer owns the lock
while ((curr_val = lock->value) == -1) {}
assert(curr_val >= 0);
// try to atomically increment the count, based on our best
// guess of how many readers there had been. if we were
// wrong, keep looping. if we got it right, then we
// succeeded in incrementing the count atomically, and we
// can proceed.
if (cmpxchg_val(&lock->value, curr_val, curr_val + 1) == curr_val)
break;
}
// lock->value now contains curr_val + 1
}
Write the other three functions! (Again, each needs only a single line
of code.)
smutex_t res;
void highPriority() {
... // do something
smutex_lock(&res);
... // handle resource
smutex_unlock(&res);
printf("A ");
}
void mediumPriority() {
... // do something
printf("B ");
}
void lowPriority() {
smutex_lock(&res);
... // handle resource
smutex_unlock(&res);
... // do something
printf("C ");
}
Write your answers in a text file. Name the file answers.txt and upload it on GauchoSpace
cmpxchg val()
/* pseudocode */
int cmpxchg_val(int* addr, int oldval, int newval) {
LOCK: // remember, this is pseudocode
int was = *addr;
if (*addr == oldval)
*addr = newval;
return was;
}
/* inline assembly */
int cmpxchg_val(int* addr, int oldval, int newval) {
int was;
asm volatile("lock cmpxchg %3, %0"
: "+m" (*addr), "=a" (was)
: "a" (oldval), "r" (newval)
: "cc");
return was;
}
atomic decrement()
/* pseudocode */
void atomic_decrement(int* arg) {
LOCK: // remember, this is pseudocode
*arg = *arg - 1;
}
/* inline assembly */
void atomic_decrement(int* arg) {
asm volatile("lock decl %0" : "+m" (*arg) : "m" (arg));
}
Last updated: 2019-01-28 09:24:18 -0800 [validate xhtml]