Lecture: concurrency Q&A
preparation
- read OSPP §6, Multi-Object Synchronization.
spinlocks in xv6
- show
spinlock.h
, spinlock.c
xchg
and ->locked
asm volatile
- would cpu or compiler reorder things?
- what’s
pushcli()
?
- can we use
->locked = 0
in release()
instead of xchg
?
more on locks
- spinlocks recap
- spin on
locked
(e.g., using xchg
)
- hold for very short times
- don’t yield CPU while holding lock
- (un)fairness issues: FIFO ordering?
- alternative: ticket spinlocks
- real world example: restaurants, banks, DMV, …
- use two variables
- next ticket
- “now serving” ticket
- take a number from
next
& wait until now_serving
reaches next
- see Linux kernel’s ticket spinlocks
struct lock { _Atomic int next, now_serving; };
void acquire(struct lock *l)
{
int ticket = atomic_fetch_add(&l->next, 1);
while (l->now_serving != ticket);
}
void release(struct lock *l)
{
++l->now_serving;
}
- many other locks
- MCS locks
- “blocking” locks: waiting threads yield the CPU
- rwlocks (e.g.,
pthread_rwlock_t
)
- RCU
- alternative: transactional memory
- example: Intel’s TSX
- demo using ph.c
- compile:
gcc -mrtm
- make sure your CPU supports TSX
- Linux: check for
hlm
and rtm
in /proc/cpuinfo
- OS X:
sysctl machdep.cpu | grep features
- otherwise, “Illegal instruction”
- how do you compare this interface to locks
- easy to use?
- performance?
- ideas for lab X?
#include <immintrin.h>
...
if (_xbegin() == _XBEGIN_STARTED) {
// do a few things
_xend();
} else {
// plan B (e.g., fail or retry)
}