|
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