|
2340 | 2340 | the kernel data structures relevant to that process. |
2341 | 2341 | \item In other words -- the context of a process is its state. When the system |
2342 | 2342 | is executing the process, one says that it runs in the process context. |
2343 | | -The classic kernel handles interrupts in the context of interrupted process. |
| 2343 | +The classic kernel handles interrupts in the context of an interrupted process. |
2344 | 2344 | \item The threads were introduced to UNIX later - originally there were just |
2345 | | -processes that from today's perspective had only single thread. The possibility |
2346 | | -of using multiple threads was introduced because it was shown that it is |
2347 | | -beneficial to have multiple lines of execution within the same process on |
| 2345 | +processes that from today's perspective had only a single thread. The |
| 2346 | +possibility of using multiple threads was introduced because it was shown that |
| 2347 | +it is beneficial to have multiple lines of execution within the same process on |
2348 | 2348 | commonly shared data. |
2349 | 2349 | \item The memory areas of processes are isolated between each other, however |
2350 | 2350 | processes can communicate or explicitly share memory. |
|
2354 | 2354 | processes. |
2355 | 2355 | \item A system process that is running for the whole time and provides some |
2356 | 2356 | system services (\texttt{inetd}, \texttt{cron}, \texttt{sendmail}\dots) is |
2357 | | -called a \emph{daemon}. BSD system mascot is not a devil but a daemon. |
| 2357 | +called a \emph{daemon}. The BSD system mascot is not a devil but a daemon. |
2358 | 2358 | \item As Rob Pike mentioned in one of his lectures, this is a concurrency model |
2359 | 2359 | that can lead to parallelism. |
2360 | 2360 | \end{itemize} |
|
2365 | 2365 | \sltitle{kernel, modes, interrupts/traps (classic UNIX)} |
2366 | 2366 | \begin{itemize} |
2367 | 2367 | \item processes typically run in user mode |
2368 | | -\item a system call will cause a switch to kernel mode |
| 2368 | +\item a \emph{system call} will cause a switch to kernel mode |
2369 | 2369 | \item a process has one stack for each mode |
2370 | 2370 | \item the kernel is part of each user process, it is not a standalone process(es) |
2371 | 2371 | \item switching to different process is called \emph{context switching} |
2372 | | -\item interrupt handling is performed in the context of interrupted process |
| 2372 | +\item interrupt handling is performed in the context of an interrupted process |
2373 | 2373 | \item the classic kernel is non-preemptive |
2374 | 2374 | \end{itemize} |
2375 | 2375 | \end{slide} |
|
2387 | 2387 | a process can only block on its own. Modern Unixes use interrupt threads, |
2388 | 2388 | in their context the drivers \emsl{can} block. |
2389 | 2389 | \item The fact that the classic UNIX kernel is non-preemptive means that |
2390 | | -\emsl{one process cannot block another process}. |
| 2390 | +\emsl{one process cannot block another process}. For more information that is |
| 2391 | +outside of this lecture, search for \emph{kernel preemption}. |
2391 | 2392 | \item An interrupt can come while handling another interrupt. If its priority |
2392 | 2393 | is higher, it is accepted by the CPU. The sequence of accepted interrupts is |
2393 | 2394 | saved in an \emph{interrupt context stack}. |
2394 | | -\item \emsl{Modern kernels are very different in terms of interrupt handling, |
| 2395 | +\item \emsl{Modern kernels are quite different in terms of interrupt handling, |
2395 | 2396 | kernel preemption, etc.} |
2396 | 2397 | \end{itemize} |
2397 | 2398 |
|
|
2411 | 2412 |
|
2412 | 2413 | \begin{itemize} |
2413 | 2414 | \item If a Unix process is required to perform a system task, it will pass the |
2414 | | -control to the kernel using a system call. The kernel is code shared between |
2415 | | -all processes but accessible only to those processes that are running in |
2416 | | -kernel mode. The kernel is therefore not a standalone privileged process, |
2417 | | -it is still running in the context of a process (one that requested a system |
2418 | | -service via a system call or that was running when an interrupt came). |
| 2415 | +control to the kernel using a \emph{system call}. The kernel is code shared |
| 2416 | +between all processes but accessible only to those processes that are running in |
| 2417 | +kernel mode. The kernel is therefore not a standalone privileged process, it is |
| 2418 | +still running in the context of a process (one that requested a system service |
| 2419 | +via a system call or that was running when an interrupt came). |
2419 | 2420 | \item Inter-process communication in UNIX is achieved using system calls, |
2420 | 2421 | it is therefore handled by the kernel. |
2421 | 2422 | \item There can be system processes called \emph{kernel threads}, that are |
|
2440 | 2441 | \begin{slide} |
2441 | 2442 | \sltitle{System calls, functions} |
2442 | 2443 | \begin{itemize} |
2443 | | -\item In UNIX a distinction is made between \emsl{system calls} and \emsl{library |
| 2444 | +\item In UNIX a distinction is made between \emph{system calls} and \emph{library |
2444 | 2445 | functions}. This division is maintained in man pages: section \emsl{2} contains |
2445 | 2446 | system call man pages and section \emsl{3} library functions. |
2446 | 2447 | \begin{itemize} |
|
2461 | 2462 | \item The transition from userland to kernel can be costly; if the program |
2462 | 2463 | executes lot of syscalls, it can have a negative effect on its performance. |
2463 | 2464 | \emsl{A library function can but does not have to perform some system calls, |
2464 | | -however it always does some non-trivial work in user mode.} |
| 2465 | +however it commonly does some non-trivial work in user mode.} |
2465 | 2466 | \item It is possible to perform system calls directly in the assembler. |
2466 | 2467 | \item The kernel API is defined w.r.t. function calls of the standard library, |
2467 | 2468 | not w.r.t. interrupt level and data structures used by these functions when |
|
2493 | 2494 | \texttt{extern int \funnm{errno};} |
2494 | 2495 | \item a successful syscall never changes \texttt{errno}! It is therefore |
2495 | 2496 | necessary to test the return value first and then check \texttt{errno}. |
2496 | | -\item error messages depending on the \texttt{errno} value can be printed with\\ |
| 2497 | +\item error messages based on \texttt{errno} value can be printed with:\\ |
2497 | 2498 | \texttt{void \funnm{perror}(const char *\emph{s});} |
2498 | | -\item textual representation for a given value is returned by\\ |
| 2499 | +\item textual representation for a given value is returned by:\\ |
2499 | 2500 | \texttt{char *\funnm{strerror}(int \emph{errnum});} |
2500 | 2501 | \end{itemize} |
2501 | 2502 | \end{slide} |
2502 | 2503 |
|
2503 | 2504 | %%%%% |
2504 | 2505 |
|
2505 | 2506 | \begin{itemize} |
2506 | | -\item \label{ERRNO} In Solaris, \texttt{errno} is in reality defined in |
2507 | | -\texttt{libc} as a dereferenced pointer to an integer (specific to a userland thread) |
2508 | | -and the value is set right after the instruction for the system call. |
2509 | | -For example, on the i386 architecture the \texttt{errno} value is stored in the |
2510 | | -\texttt{eax} register after the return from the syscall (after the |
2511 | | -\texttt{sysenter} instruction is executed). Before the instruction, the register |
2512 | | -held the system call number. It is therefore the \texttt{libc} library that is |
2513 | | -responsible for the program to see the correct \texttt{errno} value. |
| 2507 | +\item Many \texttt{libc} functions and functions from other libraries set |
| 2508 | +\texttt{errno} on failure as well. You always need to consult the relevant |
| 2509 | +documentation. |
| 2510 | +\item \label{ERRNO} It is common nowadays that \texttt{errno} is in reality |
| 2511 | +defined in \texttt{libc} as a dereferenced pointer to an integer returned by a |
| 2512 | +function (returned pointer is specific to a userland thread) and the value is |
| 2513 | +set right after the instruction for the system call. For example, on the i386 |
| 2514 | +architecture the \texttt{errno} value is stored in the \texttt{eax} register |
| 2515 | +after the return from the syscall (after the \texttt{sysenter} instruction is |
| 2516 | +executed). Before the instruction, the register held the system call number. It |
| 2517 | +is therefore the \texttt{libc} library that is responsible for the program to |
| 2518 | +see the correct \texttt{errno} value. |
2514 | 2519 | \item The POSIX thread functions (\texttt{pthread\_*}) do not set |
2515 | | -\texttt{errno}, rather they return either zero or an error code. |
| 2520 | +\texttt{errno}, rather they return either zero or an error code. More on that |
| 2521 | +later. |
2516 | 2522 | \item For some calls, the value \texttt{-1} is semantically valid. To use such |
2517 | 2523 | functions, it is necessary to set \texttt{errno~=~0} before the call and check |
2518 | 2524 | whether the value changed after the call. E.g. the \texttt{strtol} function |
2519 | | -returns 0 on failure, which can also be a valid value in some cases |
| 2525 | +returns \texttt{0} on failure, which can also be a valid value in some cases |
2520 | 2526 | (and $-1$ is also a valid result value). |
2521 | 2527 | \item It is therefore necessary to always read the appropriate man page for the |
2522 | 2528 | system call or library function. |
|
0 commit comments