2022-11-04 09:35:42 -07:00

45 lines
934 B
C

/*
* @@name: atomic.3
* @@type: C
* @@operation: compile
* @@expect: success
* @@version: omp_3.1
*/
int fetch_and_add(int *p)
{
/* Atomically read the value of *p and then increment it. The
previous value is returned. This can be used to implement a
simple lock as shown below.
*/
int old;
#pragma omp atomic capture
{ old = *p; (*p)++; }
return old;
}
/*
* Use fetch_and_add to implement a lock
*/
struct locktype {
int ticketnumber;
int turn;
};
void do_locked_work(struct locktype *lock)
{
int atomic_read(const int *p);
void work();
// Obtain the lock
int myturn = fetch_and_add(&lock->ticketnumber);
while (atomic_read(&lock->turn) != myturn)
;
// Do some work. The flush is needed to ensure visibility of
// variables not involved in atomic directives
#pragma omp flush
work();
#pragma omp flush
// Release the lock
fetch_and_add(&lock->turn);
}