这是一篇来自北美的c++代写作业案例分享
CS 444/544 OS II
Lab Session #8
Concurrency Lab #2
Fork Concurrency Lab 2
• Go to
• https://gitlab.unexploitable.systems/root/concurrency2
• Click fork
• Set visibility: Private
Clone your lab
• On flip1,2,3 or os1 or 2
• git clone git@gitlab.unexploitable.systems:[your-gitlab-id]/concurrency2.git
• This will generate a directory ‘concurrency2’ • Copy your c1.c to concurrency2 directory
Some commands
• make
• Will build all test programs
• make grade
• Will run all tests with grading script
• make clean
• Remove all files. You can build all by running ‘make’ again
Check
Check 2
Copy your c1.c to the repository
Check 3
deadlock_q1
• Please resolve ‘deadlock’ in thread_func_0 and 1
deadlock_q1
• Please resolve ‘deadlock’ in thread_func_0 and 1
deadlock_q2
• Please resolve ‘deadlock’ in thread_func_0 and 1
deadlock_q3
• Please resolve ‘deadlock’ in thread_func_0 and 1
How to Remove No Preemption
Release the lock if obtaining a resource fails…
top: lock(A);
if (trylock(B) == -1) { unlock(A);
goto top; }
…
Can’t acquire B, then Release A!
deadlock_q3
• Please use _xchg() as trylock()
• if (xchg() == 1), you failed to acquire the lock • if (xchg() == 0), you have acquired the lock
• Algorithm
• Acquire l0
• Try Acquire l1
• If acquired, great!
• If not acquired, release l0, and go back to the first step
deadlock_q4
- DO NOT use lock at this time..
- Please use _cmpxchg (lock cmpxchg, an atomic operation) toincrement counter values…
- Thread 0 increments the counter by 1
- Thread 1 increments the counter by 2
How to Remove Mutual Exclusion
• Do not use lock
• Use atomic operations instead
• Replace locks with atomic primitives
• compare_and_swap(uint64_t *addr, uint64_t prev, uint64_t value); • if *addr == prev, then update *addr = value;
• lock cmpxchg in x86..
void add (int *val, int amt) { Mutex_lock(&m);
*val += amt; Mutex_unlock(&m);
int old = *value;
} while(!CompAndSwap(val, old, old+amt);
}
void add (int *val, int amt) { do {
}
A simple thread-safe array (array.c)
• Two or more threads will use an array (or more)
• Their use must be synchronized to get a consistent result
Test1
• Two threads, each inserts 300,000 items to the array a.
• Expected result: 600,000 items
Test2
• One thread adds 300,000 items • The other thread removes
300,000 itmes
• Expected Result: 0 items…
Test3
- One thread returns an array that contains the first half of the element in the array
- The other thread removes 300,000 itmes
- Expected Result: getting first 150,000 items
Test4
- One thread returns a concatenated array of two arrays..
- One other thread removes 300,000 items from a
- One other thread removes 300,000 items from b
- The other threads inserts 300,000 items to c
- Expected Result: a = 0, b = 0, c = 900,000
Array.c
• Change the implementation of struct Array
• Place locks if required
• Implement nolock functions if required • E.g., nolock_insert