Reputation: 548
Below is the code is given in OSTEP book regarding the implementation of a lock using test and set instruction. My question is that in such implementation, couldn't a thread that is not holding the lock call the unlock function and take away the lock?
typedef struct __lock_t {
int flag;
} lock_t;
void init(lock_t *lock) {
// 0 indicates that lock is available, 1 that it is held
lock->flag = 0;
}
void lock(lock_t *lock) {
while (TestAndSet(&lock->flag, 1) == 1)
; // spin-wait (do nothing)
}
void unlock(lock_t *lock) {
lock->flag = 0;
}
Upvotes: 0
Views: 1465
Reputation: 37214
My question is that in such implementation, couldn't a thread that is not holding the lock call the unlock function and take away the lock?
There's nothing wrong with (e.g.) one thread acquiring a lock, notifying another thread that it can proceed (or maybe spawning a new thread), then the other thread releasing the lock.
Something is very wrong if a single thread acquires a lock and then releases it twice.
To detect bugs (while still supporting all legitimate scenarios), you'd want to detect "unlock()
called when lock not held". You could do that by using an atomic TestAndClear()
in the unlock()
.
If you want to enforce "only the thread that acquired the lock may release the lock" then you have to know which thread acquired the lock, so you have to store a thread ID in the lock when its acquired (e.g. maybe by using an atomic "compare, and exchange if it was equal").
Upvotes: 0
Reputation: 617
It's assumed that it's a coding error so that case should not be happening.
Upvotes: 0