|
1197 | 1197 | \label{RWLOCKS}
|
1198 | 1198 |
|
1199 | 1199 | \begin{itemize}
|
1200 |
| -\item Not a part of POSIX threads from POSIX.1c, rather part of extension |
1201 |
| -POSIX.1j called ``advanced real-time extensions''. |
| 1200 | +\item You can also use static initialization |
| 1201 | +\texttt{PTHREAD\_RWLOCK\_INITIALIZER}, similarly to other synchronization |
| 1202 | +mechanisms. |
| 1203 | +\item Not a part of pthreads from POSIX.1c, rather part of extension POSIX.1j |
| 1204 | +called ``advanced real-time extensions''. |
1202 | 1205 | \item More than one thread can hold the lock for reading or at most one
|
1203 | 1206 | thread for writing (and no one for reading).
|
1204 | 1207 | \item Read-write locks are semantically similar to locking files using
|
1205 | 1208 | \texttt{fcntl} function.
|
1206 |
| -\item It is common that given implementation prefers writer threads to |
1207 |
| -reader threads. E.g. if a lock is owned by writer and some other thread |
| 1209 | +\item It is common that a given implementation prefers writer threads to |
| 1210 | +reader threads. E.g. if a lock is owned by a writer while some other thread |
1208 | 1211 | calls function \funnm{pthread\_rwlock\_rdlock} and there is at least one thread
|
1209 | 1212 | waiting in \funnm{pthread\_rwlock\_wrlock}, the writer will be given precedence.
|
1210 | 1213 | See \example{pthreads/pthread-rwlock-pref.c}.
|
1211 |
| -\item There is maximal count of locking operations in given implementation |
1212 |
| -(inferred from the type that holds the lock count). If the maximum is reached |
1213 |
| -\funnm{pthread\_rwlock\_rdlock} returns the \texttt{EAGAIN} error, |
1214 |
| -see \example{pthreads/pthread-rwlock-limit.c}. |
| 1214 | +\item There is a maximum number of locks allowed for each lock in any pthread |
| 1215 | +implementation (inferred from the type that holds the lock count). If the |
| 1216 | +maximum is reached \funnm{pthread\_rwlock\_rdlock} returns the \texttt{EAGAIN} |
| 1217 | +error, see \example{pthreads/pthread-rwlock-limit.c}. |
1215 | 1218 | \end{itemize}
|
1216 | 1219 |
|
1217 | 1220 | %%%%%
|
|
1362 | 1365 | the \texttt{PTHREAD\_BARRIER\_SERIAL\_THREAD} value
|
1363 | 1366 | in the last thread that reached the barrier so e.g. a collection of
|
1364 | 1367 | results from the last phase of the run can be done.
|
1365 |
| -\item The barrier condition is for example value of a counter to be 0. |
1366 |
| -Each thread that reaches the barrier decrements the counter which is |
1367 |
| -initialized to the number of threads in the beginning. |
1368 |
| -Once a thread decrements the counter and realizes it is not 0, |
1369 |
| -it will enter sleep on a condition variable. |
1370 |
| -If the thread is the one which discovers the counter to be 0, then instead of |
1371 |
| -calling \texttt{pthread\_cond\_wait} it will send a broadcast which will |
1372 |
| -wake up all the threads sleeping on the barrier. |
| 1368 | +\item To implement the barrier without the API above, the fact that all threads |
| 1369 | +have reached the barrier may be indicated by a counter value to be 0, for |
| 1370 | +example. Each thread that reaches the barrier decrements the counter which is |
| 1371 | +initialized to the number of threads in the beginning. Once a thread decrements |
| 1372 | +the counter and realizes it is not 0, it waits on a condition variable. If the |
| 1373 | +thread is the one which discovers the counter to be 0, instead of waiting it |
| 1374 | +sends a broadcast which wakes up all the threads sleeping on the barrier. |
1373 | 1375 | \texttt{pthread\_cond\_signal} is not enough, since it is necessary to wake up
|
1374 |
| -all the threads, not just one. |
1375 |
| -Before entering next phase the counter is initialized to previous value. |
1376 |
| -This needs to be done carefully, for example it is not possible just to |
1377 |
| -reinitialize the counter after the last thread reaches the barrier, |
1378 |
| -because like was shown on page \pageref{CONDITION_VARIABLES} after waking |
1379 |
| -up from \texttt{pthread\_cond\_wait} the threads need to test that the counter |
1380 |
| -is indeed 0 and if not they need to be put to sleep again. So it can happen |
1381 |
| -that only some (or none) of the threads would wake up. |
1382 |
| -How would you solve this problem ? See \example{pthreads/implement-barrier.c} |
1383 |
| -and \example{pthreads/implement-barrier-fixed.c} for solution. |
| 1376 | +all the threads, not just one. Before entering next phase the counter is |
| 1377 | +initialized to previous value. This needs to be done carefully, for example it |
| 1378 | +is not possible just to reinitialize the counter after the last thread reaches |
| 1379 | +the barrier, because like was shown on page \pageref{CONDITION_VARIABLES} after |
| 1380 | +waking up from \texttt{pthread\_cond\_wait} the threads need to test that the |
| 1381 | +counter is indeed 0 and if not they need to be put to sleep again. So it can |
| 1382 | +happen that only some (or none) of the threads would wake up. How would you |
| 1383 | +solve this problem? See \example{pthreads/implement-barrier.c} and |
| 1384 | +\example{pthreads/implement-barrier-fixed.c} for solution. |
1384 | 1385 | \end{itemize}
|
1385 | 1386 |
|
1386 |
| - |
1387 | 1387 | %%%%%
|
1388 | 1388 |
|
1389 | 1389 | ifdef([[[NOSPELLCHECK]]], [[[
|
|
0 commit comments