...or do I have to write my own? (BTW I'm working in C)
I'm writing an implementation similar to what's on wikipedia:
volatile int lock = 0;
void Critical() {
while (TestAndSet(&lock) == 1);
critical section // only one process can be in this section at a time
lock = 0 // release lock when finished with the critical section
}
But I can't seem to find a prebuilt TestAndSet(volatile int *lock)
.
Examples of what they might look like include:
#define LOCKED 1
int TestAndSet(volatile int* lockPtr) {
int oldValue;
oldValue = *lockPtr;
*lockPtr = LOCKED;
return oldValue;
}
Ideally I'd like something that can work on both linux and windows. As well, I've read that the execution of atomic instructions is hardware dependant. I'm not sure this plays into things or how to tell if hardware supports it, and then run an alternative.
Thank you!
Additional contextual info: The reason I'm asking this question is for the development of a set of functions for accessing a data structure (e.g. add() fetch() delete() etc...) Several threads are accessing it for modification and for real-time displaying of certain elements.
Mutexes: I voted against mutexes (correct me if my rationale is ill-founded) because the critical area is not the entire hash table, but the specific member being accessed by a given function. So using a mutex would result in a bottleneck in performance of the whole data structure.
Alternative: What led me to looking at TestAndSet() is because it made more sense to put a "beingAccessed" flag on each element in the data structure. This flag would be checked by a function that wanted to access it, be set to true if it were false and then the function would do what it had to, then release that one element without freezing up the whole structure.
Comment @M.M: The sample implementation didn't feel right for the reason @chux and you both mention. For the busy wait, it's my understanding that it's used at a low level to develop higher level synchronization mechanisms. Please see my edit above re: mutexes. The volatile was not an attempt to ensure atomicity, but to ensure the value was loaded each time it was accessed when it was being checked by an atomic function because several threads could modify that variable at any time. The atomicity I imagine/am hoping is provided by the function acting on the variable in question. Question specific to something you wrote: your code says “Note: do not use "volatile"” but the standard function prototype you provided is volatile, so is the non volatile flag variable cast as volatile in the atomic function? Thank you.