|
61 | 61 | \sltitle{Implementation of threads} |
62 | 62 | \setlength{\baselineskip}{0.8\baselineskip} |
63 | 63 | \begin{description} |
64 | | -\item[library-thread model]~\\\vspace{-2.5ex} |
| 64 | +\item[library-thread model (1:N)]~\\\vspace{-2.5ex} |
65 | 65 | \begin{itemize} |
66 | 66 | \item threads are implemented in a library. Kernel has no knowledge of |
67 | 67 | such threads. |
|
70 | 70 | \item[$\oplus$] less overhead |
71 | 71 | \item[$\ominus$] more threads of the same process cannot run in parallel |
72 | 72 | \end{itemize} |
73 | | -\item [kernel-thread model]~\\\vspace{-2.5ex} |
| 73 | +\item [kernel-thread model (1:1)]~\\\vspace{-2.5ex} |
74 | 74 | \begin{itemize} |
75 | 75 | \item threads are a first class kernel citizen |
76 | 76 | \item[$\oplus$] more threads of the same process can run in parallel on |
77 | 77 | multiple CPUs |
78 | 78 | \end{itemize} |
79 | | -\item[hybrid models]~\\\vspace{-2.5ex} |
| 79 | +\item[hybrid models (M:N)]~\\\vspace{-2.5ex} |
80 | 80 | \begin{itemize} |
81 | 81 | \item N library threads scheduled on M kernel threads, N $>=$ M |
82 | 82 | \item[$\ominus$] too complex to implement, not really used today |
|
85 | 85 | \end{slide} |
86 | 86 |
|
87 | 87 | \begin{itemize} |
88 | | -\item Original Unix systems used library models. Today in general the kernel |
89 | | -model is used. |
| 88 | +\item Original Unix systems used library models (sometimes called |
| 89 | +\emph{lightweight threads} or \emph{green threads}). Today in general |
| 90 | +most of the systems stick to the 1:1 model. There was some evolution in |
| 91 | +the past, e.g. Solaris 9 was using the M:N model and switched to 1:1 in |
| 92 | +Solaris 10. |
90 | 93 | \item Threads implemented in a library may be either preemptive or |
91 | 94 | non-pre\-emp\-tive. To achieve preemption, you can use timers and signals. |
92 | 95 | However, if the objective is more in better modular programming than real |
93 | 96 | parallelism, usually non-preemptive threads do fine. Switching threads will be |
94 | 97 | done when a process would normally block in system calls. |
95 | | -\item \label{SETJMP} If a system call blocks in a library implemented thread, |
96 | | -the whole process will block as the kernel has no knowledge there are more |
97 | | -threads in the process. So the threading library is written the way that |
| 98 | +\item \label{SETJMP} If a system call blocks in a library implemented thread |
| 99 | +model, the whole process will block as the kernel has no knowledge there are |
| 100 | +more threads in the process. So the threading library is written the way that |
98 | 101 | non-blocking calls are used, the thread context is saved after that and the |
99 | 102 | library switches to another thread via \funnm{setjmp}() and \funnm{longjmp}() |
100 | 103 | system calls. Example: \example{pthreads/setjmp.c}. Another way is to use a |
101 | 104 | non-standard system call \funnm{swapcontext}() if the system provides it. |
| 105 | +\item To implement a 1:N library, there are several things for consideration: |
| 106 | +\begin{itemize} |
| 107 | +\item how to deal with threads trying to install \texttt{SIGALRM} handler |
| 108 | +if it is already used for firing signal to trigger the dispatcher/scheduler |
| 109 | +periodically |
| 110 | +\item how to implement separate stacks for each thread (especially when |
| 111 | +\texttt{setjmp} was chosen as a building block). |
| 112 | +\item what should be the thread states |
| 113 | +\item how to avoid all threads to be blocked when one threads blocks e.g. on I/O |
| 114 | +\end{itemize} |
102 | 115 | \end{itemize} |
103 | 116 |
|
104 | 117 | \begin{slide} |
|
0 commit comments