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 deadlockstruct 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]