The difference between the two specified functions, omp_init_lock_with_hint()
and omp_init_nest_lock_with_hint()
is that it initializes a lock simple and this initializes a lock nestled.
The difference between the two (apart from the obvious that one receives a omp_lock_t *
and the other one omp_nest_lock_t *
) is that a task that gets a simple lock via omp_set_lock()
can’t call omp_set_lock()
in the same lock without first releasing it using omp_unset_lock()
, under penalty of generating a deadlock.
Other Openmp tasks can call omp_set_lock()
in a latch already belonging to a different task; they will latch until the task that currently holds the latch releases it using omp_unset_lock()
(and that the other tasks in front of it in the queue waiting for the latch also get and release the latch).
Already to a omp_nest_lock_t
, if the task owner of the lock calls omp_set_nest_lock()
in it, it will merely increase an internal counter, and by calling omp_unset_nest_lock()
this counter will be decreased. If the value of the counter reaches zero, the lock is released. In other words, although the call to omp_set_nest_lock()
in a lock already belonging to the task does not cause deadlock, the task has to issue so many omp_unset_nest_lock()
how much issued omp_set_nest_lock()
before the lock is released.
As for the usage examples, I will need some time to restore my knowledge in Openmp, but the general idea is that with the simple lock, each task gets the lock with omp_set_lock()
, perform the synchronous and infallible operations (no exceptions) in the critical region, and then release the lock with omp_unset_lock()
. In the case of nested_lock, the task can do more complex things, such as getting the lock with omp_set_nest_lock()
, wait for an event and call omp_unset_nest_lock()
in a callback.