From bd7f212f903aff5ea9f0cb4822a2f0a4d0e516bd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 20 Nov 2023 09:18:11 +0000 Subject: [PATCH] deploy: 1921940718548c784594cb51f3a9e62d2c1f2100 --- 404.html | 4 +- .../Asynchronous Web Server/index.html | 4 +- .../src/http-parser/index.html | 4 +- Assignments/Memory Allocator/index.html | 4 +- Assignments/Mini Libc/index.html | 4 +- Assignments/Mini Shell/index.html | 4 +- Assignments/Mini Shell/util/parser/index.html | 4 +- Assignments/Parallel Graph/index.html | 62 +++++++++++-------- Assignments/index.html | 6 +- Lab/Application Interaction/arena/index.html | 4 +- Lab/Application Interaction/dbus/index.html | 4 +- Lab/Application Interaction/index.html | 4 +- .../os-cloud/index.html | 4 +- .../overview/index.html | 4 +- .../password-cracker/index.html | 4 +- .../quiz/cgroups-vs-namespaces/index.html | 4 +- .../quiz/container-vs-vm/index.html | 4 +- .../quiz/time-server-interop/index.html | 4 +- .../quiz/time-server/index.html | 4 +- .../quiz/timer/index.html | 4 +- .../quiz/vm-creation/index.html | 4 +- .../time-server/index.html | 4 +- .../x-window-system/index.html | 4 +- Lab/Compute/arena/index.html | 4 +- Lab/Compute/copy-on-write/index.html | 4 +- Lab/Compute/hardware-perspective/index.html | 4 +- Lab/Compute/index.html | 4 +- Lab/Compute/overview/index.html | 4 +- .../processes-threads-apache2/index.html | 4 +- Lab/Compute/processes/index.html | 4 +- Lab/Compute/quiz/apache2-strace/index.html | 4 +- .../cause-of-file-not-found-error/index.html | 4 +- .../quiz/child-faults-after-write/index.html | 4 +- .../index.html | 4 +- .../create-sleepy-process-ending/index.html | 4 +- Lab/Compute/quiz/fiber-strace/index.html | 4 +- .../mini-shell-stops-after-command/index.html | 4 +- Lab/Compute/quiz/mmap-cow-flag/index.html | 4 +- .../quiz/notify-only-with-mutex/index.html | 4 +- .../quiz/number-of-running-ults/index.html | 4 +- .../quiz/parent-faults-before-fork/index.html | 4 +- .../quiz/parent-of-sleep-processes/index.html | 4 +- Lab/Compute/quiz/processes-speedup/index.html | 4 +- .../quiz/seg-fault-exit-code/index.html | 4 +- .../quiz/semaphore-equivalent/index.html | 4 +- .../quiz/sleeping-on-a-fiber/index.html | 4 +- Lab/Compute/quiz/state-of-new-ult/index.html | 4 +- .../quiz/tcb-libult-unikraft/index.html | 4 +- Lab/Compute/quiz/thread-memory/index.html | 4 +- Lab/Compute/quiz/time-slice-value/index.html | 4 +- .../quiz/tls-synchronization/index.html | 4 +- Lab/Compute/quiz/tls-var-copies/index.html | 4 +- .../type-of-scheduler-in-libult/index.html | 4 +- Lab/Compute/quiz/ult-thread-ids/index.html | 4 +- .../quiz/who-calls-execve-parent/index.html | 4 +- .../quiz/why-use-completed-queue/index.html | 4 +- Lab/Compute/synchronization/index.html | 4 +- Lab/Compute/threads/index.html | 4 +- Lab/Compute/user-level-threads/index.html | 4 +- Lab/Data/arena/index.html | 4 +- Lab/Data/index.html | 4 +- Lab/Data/investigate-memory/index.html | 4 +- Lab/Data/memory-security/index.html | 4 +- Lab/Data/overview/index.html | 4 +- Lab/Data/process-memory/index.html | 4 +- Lab/Data/quiz/bypass-canary/index.html | 4 +- Lab/Data/quiz/half-page/index.html | 4 +- Lab/Data/quiz/malloc-brk/index.html | 4 +- Lab/Data/quiz/malloc-mmap/index.html | 4 +- Lab/Data/quiz/memory-access/index.html | 4 +- Lab/Data/quiz/memory-aslr/index.html | 4 +- Lab/Data/quiz/memory-granularity/index.html | 4 +- Lab/Data/quiz/memory-leaks/index.html | 4 +- Lab/Data/quiz/memory-regions-vars/index.html | 4 +- .../quiz/memory-stack-protector/index.html | 4 +- Lab/Data/quiz/mmap-file/index.html | 4 +- Lab/Data/quiz/operators/index.html | 4 +- Lab/Data/quiz/page-allocation/index.html | 4 +- Lab/Data/quiz/stack-layout/index.html | 4 +- Lab/Data/quiz/string-buff-over/index.html | 4 +- Lab/Data/quiz/string-strcpy/index.html | 4 +- Lab/Data/quiz/valgrind-leaks/index.html | 4 +- Lab/Data/working-memory/index.html | 4 +- Lab/IO/arena/index.html | 4 +- Lab/IO/async-io/index.html | 4 +- Lab/IO/beyond-network-sockets/index.html | 4 +- Lab/IO/client-server-model/index.html | 4 +- Lab/IO/file-descriptors/index.html | 4 +- Lab/IO/file-handlers/index.html | 4 +- Lab/IO/file-mappings/index.html | 4 +- Lab/IO/index.html | 4 +- Lab/IO/io-internals/index.html | 4 +- Lab/IO/io-multiplexing/index.html | 4 +- Lab/IO/local-io-in-action/index.html | 4 +- Lab/IO/networking-101/index.html | 4 +- Lab/IO/overview/index.html | 4 +- Lab/IO/pipes/index.html | 4 +- .../anonymous-pipes-limitation/index.html | 4 +- Lab/IO/quiz/bind-error-cause/index.html | 4 +- .../client-server-sender-receiver/index.html | 4 +- Lab/IO/quiz/deluge-tcp-udp/index.html | 4 +- Lab/IO/quiz/execve/index.html | 4 +- Lab/IO/quiz/fewer-than-2-copies/index.html | 4 +- Lab/IO/quiz/file-handler-c/index.html | 4 +- Lab/IO/quiz/firefox-tcp-udp/index.html | 4 +- Lab/IO/quiz/flush-libc-buffer/index.html | 4 +- Lab/IO/quiz/fopen-syscall/index.html | 4 +- Lab/IO/quiz/fopen-w/index.html | 4 +- Lab/IO/quiz/local-io-errors/index.html | 4 +- .../quiz/mmap-read-write-benchmark/index.html | 4 +- Lab/IO/quiz/o-trunc/index.html | 4 +- Lab/IO/quiz/pipe-ends/index.html | 4 +- Lab/IO/quiz/prints-work-no-stdio/index.html | 4 +- Lab/IO/quiz/receiver-socket-fd/index.html | 4 +- Lab/IO/quiz/server-copies/index.html | 4 +- Lab/IO/quiz/stderr-fd/index.html | 4 +- Lab/IO/quiz/strace-printf/index.html | 4 +- Lab/IO/quiz/syscalls-cp/index.html | 4 +- Lab/IO/quiz/write-file-permissions/index.html | 4 +- Lab/IO/redirections/index.html | 4 +- Lab/IO/remote-io/index.html | 4 +- Lab/IO/zero-copy/index.html | 4 +- Lab/Software Stack/app-investigate/index.html | 4 +- Lab/Software Stack/arena/index.html | 4 +- Lab/Software Stack/basic-syscall/index.html | 4 +- .../common-functions/index.html | 4 +- Lab/Software Stack/high-level-lang/index.html | 4 +- Lab/Software Stack/index.html | 4 +- Lab/Software Stack/libc/index.html | 4 +- Lab/Software Stack/libcall-syscall/index.html | 4 +- Lab/Software Stack/modern-sw-stack/index.html | 4 +- Lab/Software Stack/overview/index.html | 4 +- .../quiz/common-functions/index.html | 4 +- .../quiz/high-level-lang/index.html | 4 +- Lab/Software Stack/quiz/libc/index.html | 4 +- .../quiz/libcall-syscall/index.html | 4 +- Lab/Software Stack/quiz/libs/index.html | 4 +- Lab/Software Stack/quiz/software/index.html | 4 +- .../quiz/syscall-wrapper/index.html | 4 +- Lab/Software Stack/quiz/syscalls/index.html | 4 +- Lab/Software Stack/static-dynamic/index.html | 4 +- Lab/Software Stack/syscall-wrapper/index.html | 4 +- Lab/index.html | 4 +- Lab/lab-setup/index.html | 4 +- Lecture/Application-Interaction/index.html | 4 +- Lecture/Compute/index.html | 4 +- Lecture/Data/index.html | 4 +- Lecture/IO/index.html | 4 +- Lecture/Software-Stack/index.html | 4 +- Lecture/index.html | 4 +- assets/js/935f2afb.a906aa4d.js | 1 - assets/js/935f2afb.f48ac3b3.js | 1 + assets/js/b5c587af.ba3613c2.js | 1 - assets/js/b5c587af.bfed2af8.js | 1 + ...n.ccc549b8.js => runtime~main.d2300de6.js} | 2 +- index.html | 4 +- markdown-page/index.html | 4 +- resources/index.html | 4 +- rules-and-grading/index.html | 4 +- 159 files changed, 347 insertions(+), 335 deletions(-) delete mode 100644 assets/js/935f2afb.a906aa4d.js create mode 100644 assets/js/935f2afb.f48ac3b3.js delete mode 100644 assets/js/b5c587af.ba3613c2.js create mode 100644 assets/js/b5c587af.bfed2af8.js rename assets/js/{runtime~main.ccc549b8.js => runtime~main.d2300de6.js} (98%) diff --git a/404.html b/404.html index 923550f03b..9ddc7c7bcd 100644 --- a/404.html +++ b/404.html @@ -4,13 +4,13 @@ Page Not Found | Operating Systems - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/Assignments/Asynchronous Web Server/index.html b/Assignments/Asynchronous Web Server/index.html index 719add3a3f..aedea7504b 100644 --- a/Assignments/Asynchronous Web Server/index.html +++ b/Assignments/Asynchronous Web Server/index.html @@ -4,7 +4,7 @@ Asynchronous Web Server | Operating Systems - + @@ -28,7 +28,7 @@ These folders are created and removed using the init and cleanup arguments to _test/run_test.sh.

Behind the Scenes

Tests are basically unit tests.

Each test function follows the unit test patter: initialization, action, evaluation.

Each test starts the server, creates a given context, checks for validity and then terminates the server process.

Debugging

Logs are collected in test.log and wget.log files.

Resources

- + \ No newline at end of file diff --git a/Assignments/Asynchronous Web Server/src/http-parser/index.html b/Assignments/Asynchronous Web Server/src/http-parser/index.html index c3f33cc4d1..030d292a8a 100644 --- a/Assignments/Asynchronous Web Server/src/http-parser/index.html +++ b/Assignments/Asynchronous Web Server/src/http-parser/index.html @@ -4,7 +4,7 @@ HTTP Parser | Operating Systems - + @@ -48,7 +48,7 @@ buffer to avoid copying memory around if this fits your application.

Reading headers may be a tricky task if you read/parse headers partially. Basically, you need to remember whether last header callback was field or value and apply following logic:

(on_header_field and on_header_value shortened to on_h_*)
------------------------ ------------ --------------------------------------------
| State (prev. callback) | Callback | Description/action |
------------------------ ------------ --------------------------------------------
| nothing (first call) | on_h_field | Allocate new buffer and copy callback data |
| | | into it |
------------------------ ------------ --------------------------------------------
| value | on_h_field | New header started. |
| | | Copy current name,value buffers to headers |
| | | list and allocate new buffer for new name |
------------------------ ------------ --------------------------------------------
| field | on_h_field | Previous name continues. Reallocate name |
| | | buffer and append callback data to it |
------------------------ ------------ --------------------------------------------
| field | on_h_value | Value for current header started. Allocate |
| | | new buffer and copy callback data to it |
------------------------ ------------ --------------------------------------------
| value | on_h_value | Value continues. Reallocate value buffer |
| | | and append callback data to it |
------------------------ ------------ --------------------------------------------

See examples of reading in headers:

- + \ No newline at end of file diff --git a/Assignments/Memory Allocator/index.html b/Assignments/Memory Allocator/index.html index 575e5eb996..b67116e4ac 100644 --- a/Assignments/Memory Allocator/index.html +++ b/Assignments/Memory Allocator/index.html @@ -4,7 +4,7 @@ Memory Allocator | Operating Systems - + @@ -52,7 +52,7 @@ Every other address is displayed as <label> + offset, where the label is the closest mapped address.

run_tests.py supports three modes:

If you want to run a single test, you give its name or its path as arguments to run_tests.py:

student@os:~/.../mem-alloc/tests$ python3 run_tests.py test-all
OR
student@os:~/.../mem-alloc/tests$ python3 run_tests.py snippets/test-all

Debugging in VSCode

If you are using Visual Studio Code, you can use the launch.json configurations to run tests.

Setup the breakpoints in the source files or the tests and go to Run and Debug (F5). Select Run test script and press F5. This will enter a dialogue where you can choose which test to run.

You can find more on this in the official documentation: Debugging with VSCode.

If VSCode complains about MAP_ANON argument for mmap() change C_Cpp.default.cStandard option to gnu11.

Resources

- + \ No newline at end of file diff --git a/Assignments/Mini Libc/index.html b/Assignments/Mini Libc/index.html index 86465300e3..076ff3c469 100644 --- a/Assignments/Mini Libc/index.html +++ b/Assignments/Mini Libc/index.html @@ -4,7 +4,7 @@ Mini-libc | Operating Systems - + @@ -33,7 +33,7 @@ The maximum grade is obtained by dividing the number of points to 10, for a maximum grade of 90.

A successful run will show the output:

student@so:~/.../assignments/mini-libc/tests$ make check
[...]
test_strcpy ........................ passed ... 9
test_strcpy_append ........................ passed ... 9
test_strncpy ........................ passed ... 9
test_strncpy_cut ........................ passed ... 9
test_strcat ........................ passed ... 9
test_strcat_from_zero ........................ passed ... 9
test_strcat_multiple ........................ passed ... 9
test_strncat ........................ passed ... 9
test_strncat_cut ........................ passed ... 9
test_strcmp_equal ........................ passed ... 9
test_strcmp_same_size_less ........................ passed ... 1
test_strcmp_same_size_greater ........................ passed ... 9
test_strcmp_diff_size_less ........................ passed ... 1
test_strcmp_diff_size_greater ........................ passed ... 9
test_strncmp_equal_size_equal ........................ passed ... 9
test_strncmp_diff_contents_equal ........................ passed ... 9
test_strncmp_diff_size_equal ........................ passed ... 9
test_strchr_exists ........................ passed ... 11
test_strchr_exists_twice ........................ passed ... 9
test_strchr_not_exists ........................ passed ... 1
test_strrchr_exists ........................ passed ... 11
test_strrchr_exists_twice ........................ passed ... 9
test_strrchr_not_exists ........................ passed ... 1
test_strstr_exists ........................ passed ... 11
test_strstr_exists_twice ........................ passed ... 9
test_strstr_not_exists ........................ passed ... 1
test_strrstr_exists ........................ passed ... 11
test_strrstr_exists_twice ........................ passed ... 9
test_strrstr_not_exists ........................ passed ... 1
test_memcpy ........................ passed ... 11
test_memcpy_part ........................ passed ... 9
test_memcmp_equal_size_equal ........................ passed ... 9
test_memcmp_diff_contents_equal ........................ passed ... 9
test_memcmp_diff_size_equal ........................ passed ... 9
test_memset ........................ passed ... 9
test_memset_part ........................ passed ... 9
test_memmove_apart ........................ passed ... 9
test_memmove_src_before_dst ........................ passed ... 9
test_memmove_src_after_dst ........................ passed ... 9
test_open_non_existent_file ........................ passed ... 8
test_open_invalid_access_mode ........................ passed ... 8
test_open_file_as_directory ........................ passed ... 8
test_open_directory_for_writing ........................ passed ... 8
test_open_force_invalid_creation ........................ passed ... 8
test_open_close_existent_file ........................ passed ... 8
test_open_close_create_file ........................ passed ... 8
test_open_read_write_only_mode ........................ passed ... 8
test_open_write_read_only_mode ........................ passed ... 8
test_lseek_invalid_fd ........................ passed ... 8
test_lseek_invalid_whence ........................ passed ... 8
test_lseek_invalid_offset ........................ passed ... 8
test_lseek_set ........................ passed ... 8
test_lseek_cur ........................ passed ... 8
test_lseek_end ........................ passed ... 8
test_lseek_combined ........................ passed ... 8
test_truncate_read_only_file ........................ passed ... 8
test_truncate_invalid_size ........................ passed ... 8
test_truncate_directory ........................ passed ... 8
test_truncate_non_existent_file ........................ passed ... 8
test_truncate_file ........................ passed ... 8
test_ftruncate_read_only_file ........................ passed ... 8
test_ftruncate_invalid_size ........................ passed ... 8
test_ftruncate_directory ........................ passed ... 8
test_ftruncate_bad_fd ........................ passed ... 8
test_ftruncate_file ........................ passed ... 8
test_stat_non_existent_file ........................ passed ... 8
test_stat_regular_file ........................ passed ... 8
test_fstat_bad_fd ........................ passed ... 8
test_fstat_regular_file ........................ passed ... 8
test_puts ........................ passed ... 15
test_open_close_create_file ........................ passed ... 10
test_open_close_read_byte ........................ passed ... 10
test_ftruncate ........................ passed ... 10
test_truncate ........................ passed ... 10
test_fstat ........................ passed ... 10
test_stat ........................ passed ... 10
test_sleep ........................ passed ... 20
test_nanosleep ........................ passed ... 20
test_mmap ........................ passed ... 8
test_mmap_bad_fd ........................ passed ... 8
test_mmap_bad_flags ........................ passed ... 8
test_mremap ........................ passed ... 8
test_malloc ........................ passed ... 8
test_malloc_two ........................ passed ... 8
test_malloc_access ........................ passed ... 8
test_malloc_memset ........................ passed ... 8
test_malloc_memcpy ........................ passed ... 8
test_calloc ........................ passed ... 8
test_realloc ........................ passed ... 8
test_realloc_access ........................ passed ... 8
test_realloc_memset ........................ passed ... 8
test_realloc_array ........................ passed ... 8
test_malloc ........................ passed ... 10
test_multiple_malloc ........................ passed ... 10
test_malloc_free ........................ passed ... 10
test_multiple_malloc_free ........................ passed ... 10
test_malloc_free_sequence ........................ passed ... 10
test_malloc_perm_ok ........................ passed ... 10
test_malloc_perm_notok ........................ passed ... 10
test_mmap ........................ passed ... 10
test_mmap_munmap ........................ passed ... 10
test_mmap_perm_ok ........................ passed ... 10
test_mmap_perm_notok ........................ passed ... 10
test_mmap_perm_none ........................ passed ... 10

Total: 90/100

Running the Linters

To run the linters, use the make linter command in the tests/ directory. Note that the linters have to be installed on your system: checkpatch.pl, cpplint, shellcheck with certain configuration options. It's easiest to run them in a Docker-based setup with everything configured:

student@so:~/.../assignments/mini-libc/tests$ make lint
[...]
cd .. && checkpatch.pl -f checker/*.sh tests/*.sh
[...]
cd .. && cpplint --recursive src/ tests/ checker/
[...]
cd .. && shellcheck checker/*.sh tests/*.sh

Behind the Scenes

For a fine grained approach, build tests and ignore errors (due to missing source code and header files) by using:

student@so:~/.../assignments/mini-libc/tests$ make -i

Then run the tests, either individually via executable files and scripts:

student@so:~/.../assignments/mini-libc/tests$ ./test_lseek.sh
test_lseek ........................ passed ... 10

student@so:~/.../assignments/mini-libc/tests$ ./test_memory
test_mmap ........................ passed ... 8
test_mmap_bad_fd ........................ passed ... 8
[...]

Or run them all via the run_all_tests.sh script:

student@so:~/.../assignments/mini-libc/tests$ ./run_all_tests.sh
test_strcpy ........................ passed ... 9
test_strcpy_append ........................ passed ... 9
test_strncpy ........................ passed ... 9
[...]

Resources

- + \ No newline at end of file diff --git a/Assignments/Mini Shell/index.html b/Assignments/Mini Shell/index.html index 65f9b3a410..12825a0a46 100644 --- a/Assignments/Mini Shell/index.html +++ b/Assignments/Mini Shell/index.html @@ -4,7 +4,7 @@ Minishell | Operating Systems - + @@ -31,7 +31,7 @@ To see the results of the tests, you can check _test/outputs/ directory.

Checkpatch

checkpatch.pl is a script used in the development of the Linux kernel. It is used to check patches that are submitted to the kernel mailing list for adherence to the coding style guidelines of the Linux kernel.

The script checks the code for common coding style issues, such as indentation, spacing, line length, function and variable naming conventions, and other formatting rules. It also checks for some common errors, such as uninitialized variables, memory leaks, and other potential bugs.

You can download the checkpatch.pl script from the official Linux kernel repository.

Running the following command will show you linting warnings and errors:

./checkpatch.pl --no-tree --terse -f /path/to/your/code.c
- + \ No newline at end of file diff --git a/Assignments/Mini Shell/util/parser/index.html b/Assignments/Mini Shell/util/parser/index.html index ba62822813..fb842a7498 100644 --- a/Assignments/Mini Shell/util/parser/index.html +++ b/Assignments/Mini Shell/util/parser/index.html @@ -4,7 +4,7 @@ Parser | Operating Systems - + @@ -14,7 +14,7 @@ To use the parser, you need to link the object files parser.yy.o and parser.tab.o with your program.

Example

Tests

More tests can be found in the tests directory:

student@os:/.../minishell/util/parser$ cd tests

student@os:/.../minishell/util/parser/tests$ ../DisplayStructure &>small_tests.out <small_tests.txt

student@os:/.../minishell/util/parser/tests$ cat small_tests.out
> mkdir tmp
Command successfully read!
command_t (
scmd (
simple_command_t (
verb (
'mkdir'
)
params (
'tmp'
)
)
)
)

> cd tmp
Command successfully read!
command_t (
scmd (

...
student@os:/.../minishell/util/parser/tests$ ../DisplayStructure &>ugly_tests.out <ugly_tests.txt

student@os:/.../minishell/util/parser/tests$ ../DisplayStructure &>negative_tests.out <negative_tests.txt

Note

The parser will fail with an error of unknown character if you use the Linux parser (which considers the end of line as \n) on Windows files (end of line as \r\n) because at the end of the lines (returned by getline()) there will be a \r followed by \n. The opposite works (Windows parser with Linux files). The test files use the Linux convention (\n).

Other information

More information about the parser can be found in the file parser.h.

- + \ No newline at end of file diff --git a/Assignments/Parallel Graph/index.html b/Assignments/Parallel Graph/index.html index dc9cbc6731..12ec74cdb2 100644 --- a/Assignments/Parallel Graph/index.html +++ b/Assignments/Parallel Graph/index.html @@ -3,38 +3,50 @@ -Parallel Graph | Operating Systems - +Parallel Graph | Operating Systems +
-
Skip to main content

Parallel Graph

For this assignment we will implement a generic thread pool, which we will then use to traverse a graph and compute the sum of the elements contained by the nodes. +

Parallel Graph

Objectives

  • Learn how to design and implement parallel programs
  • Gain skills in using synchronization primitives for parallel programs
  • Get a better understanding of the POSIX threading and synchronization API
  • Gain insight on the differences between serial and parallel programs

Statement

Implement a generic thread pool, then use it to traverse a graph and compute the sum of the elements contained by the nodes. You will be provided with a serial implementation of the graph traversal and with most of the data structures needed to implement the thread pool. -Your job is to write the thread pool routines and then use the thread pool to traverse the graph.

Thread Pool Description

A thread pool contains a given number of active threads that simply wait to be given specific tasks. -The threads are created when the thread pool is created they poll a task queue until a task is available. -Once tasks are put in the task queue, the threads start running the task. -A thread pool creates N threads when the thread pool is created and does not destroy (join) them throughout the lifetime of the thread pool. -That way, the penalty of creating and destroying threads ad hoc is avoided. -As such, you must implement the following functions (marked with TODO in the provided skeleton):

  • task_create: creates an os_task_t that will be put in the task queue - a task consists of a function pointer and an argument.
  • add_task_in_queue: adds a given task in the thread pool's task queue.
  • get_task: get a task from the thread pool's task queue.
  • threadpool_create: allocate and initialize a new thread pool.
  • thread_loop_function: all the threads in the thread pool will execute this function - they all wait until a task is available in the task queue; once they grab a task they simply invoke the function that was provided to task_create.
  • threadpool_stop: stop all the threads from execution.

Notice that the thread pool is completely independent from any given application. -Any function can be registered in the task queue.

Graph Traversal

Once you have implemented the thread pool, you need to test it by using it for computing the sum of all the nodes of a graph. -A serial implementation for this algorithm is provided in skep/serial.c +Your job is to write the thread pool routines and then use the thread pool to traverse the graph.

Support Code

The support code consists of the directories:

  • src/ is the skeleton parallel graph implementation. +You will have to implement missing parts marked as TODO items.

  • utils/ utility files (used for debugging & logging)

  • tests/ are tests used to validate (and grade) the assignment.

Implementation

Thread Pool Description

A thread pool contains a given number of active threads that simply wait to be given specific tasks. +The threads are created when the thread pool is created. +Each thread continuously polls the task queue for available tasks. +Once tasks are put in the task queue, the threads poll tasks, and start running them. +A thread pool creates N threads upon its creation and does not destroy (join) them throughout its lifetime. +That way, the penalty of creating and destroying threads ad-hoc is avoided. +As such, you must implement the following functions (marked with TODO in the provided skeleton, in src/os_threadpool.c):

  • enqueue_task(): Enqueue task to the shared task queue. +Use synchronization.
  • dequeue_task(): Dequeue task from the shared task queue. +Use synchronization.
  • wait_for_completion(): Wait for all worker threads. +Use synchronization.
  • create_threadpool(): Create a new thread pool.
  • destroy_threadpool(): Destroy a thread pool. +Assume all threads have been joined.

You must also update the os_threadpool_t structure in src/os_threadpool.h with the required bits for synchronizing the parallel implementation.

Notice that the thread pool is completely independent of any given application. +Any function can be registered in the task queue.

Since the threads are polling the task queue indefinitely, you need to define a condition for them to stop once the graph has been traversed completely. +That is, the condition used by the wait_for_completion() function. +The recommended way is to note when no threads have any more work to do. +Since no thread is doing any work, no other task will be created.

Graph Traversal

Once you have implemented the thread pool, you need to test it by doing a parallel traversal of all connected nodes in a graph. +A serial implementation for this algorithm is provided in src/serial.c. To make use of the thread pool, you will need to create tasks that will be put in the task queue. -A task consists of 2 steps:

  • adding the current node value to the overall sum.
  • creating tasks and adding them to the task queue for the neighbouring nodes.

Since the threads are polling the task queue indefinitely, you need to find a condition for the threads to stop once the graph has been traversed completely. -This condition should be implemented in a function that is passed to threadpool_stop. -threadpool_stop then needs to wait for the condition to be satisfied and then joins all the threads.

Synchronization

For synchronization you can use mutexes, semaphores, spinlocks, condition variables - anything that grinds your gear. -However, you are not allowed to use hacks such as sleep, printf synchronization or adding superfluous computation.

Input Files

Reading the graphs from the input files is being taken care of the functions implemented in src/os_graph.c. -A graph is represented in input files as follows:

  • first line contains 2 integers N and M: N - number of nodes, M - numbed or edges
  • second line contains N integer numbers - the values of the nodes
  • the next M lines contain each 2 integers that represent the source and the destination of an edge

Data Structures

Graph

A graph is represented internally as an os_graph_t (see src/os_graph.h).

List

A list is represented internally as an os_queue_t (see src/os_list.h). -You will use this list to implement the task queue.

Thread pool

A thread pool is represented internally as an os_threadpool_t (see src/os_threadpool.h) -The thread pool contains information about the task queue and the threads.

You are not allowed to modify these data structures. -However, you can create other data structures that leverage these ones.

Infrastructure

Compilation

To compile both the serial and the parallel version, enter the src/ directory and run:

make

That will create the serial and parallel binaries/

Testing

Input tests cases are located in tests/in/. -The parallel and the serial version should provide the same results for the same input test case.

If you want manually run a single test, use commands such as below while in the src/ directory:

$./parallel ../tests/in/test5.in
-11

$ ./serial ../tests/in/test5.in
-11

Checker

The testing is automated and performed with the checker.py script from the tests/ directory. -It's easiest to use the Makefile to run the tests:

$ make check
[...]
SRC_PATH=../src python checker.py
test1.in ....................... passed ... 4.5
test2.in ....................... passed ... 4.5
test3.in ....................... passed ... 4.5
test4.in ....................... passed ... 4.5
test5.in ....................... passed ... 4.5
test6.in ....................... passed ... 4.5
test7.in ....................... passed ... 4.5
test8.in ....................... passed ... 4.5
test9.in ....................... passed ... 4.5
test10.in ....................... passed ... 4.5
test11.in ....................... passed ... 4.5
test12.in ....................... passed ... 4.5
test13.in ....................... passed ... 4.5
test14.in ....................... passed ... 4.5
test15.in ....................... passed ... 4.5
test16.in ....................... passed ... 4.5
test17.in ....................... passed ... 4.5
test18.in ....................... passed ... 4.5
test19.in ....................... passed ... 4.5
test20.in ....................... passed ... 4.5

Total: 90/100

It's recommended that you use the local Docker-based checker. -You would use the command:

./local.sh checker

to run the checker in a Docker-based environment that is identical to the one used for the official assignment evaluation.

Grading

The grade that the checker outputs is not the final grade. -Your homework will be manually inspected and may suffer from penalties ranging from 1 to 100 points depending on the severity of the hack, including, but not limited to:

  • using a single mutex at the beginning of the traversal
  • not using the thread pool to solve the homework
  • inefficient usage of synchronization
  • incorrect graph traversal

Deployment

Your implementation needs to be contained in the src/os_threadpool.c and src/os_parallel.c files. +A task consists of 2 steps:

  1. Add the current node value to the overall sum.
  2. Create tasks and add them to the task queue for the neighbouring nodes.

Implement this in the src/parallel.c (see the TODO items). +You must implement the parallel and synchronized version of the process_node() function, also used in the serial implementation.

Synchronization

For synchronization you can use mutexes, semaphores, spinlocks, condition variables - anything that grinds your gear. +However, you are not allowed to use hacks such as sleep(), printf() synchronization or adding superfluous computation.

Input Files

Reading the graphs from the input files is being taken care of the functions implemented in src/os_graph.c. +A graph is represented in input files as follows:

  • First line contains 2 integers N and M: N - number of nodes, M - numbed or edges
  • Second line contains N integer numbers - the values of the nodes.
  • The next M lines contain each 2 integers that represent the source and the destination of an edge.

Data Structures

Graph

A graph is represented internally by the os_graph_t structure (see src/os_graph.h).

List

A list is represented internally by the os_queue_t structure (see src/os_list.h). +You will use this list to implement the task queue.

Thread Pool

A thread pool is represented internally by the os_threadpool_t structure (see src/os_threadpool.h). +The thread pool contains information about the task queue and the threads.

Requirements

Your implementation needs to be contained in the src/os_threadpool.c, src/os_threadpool.h and src/parallel.c files. Any other files that you are using will not be taken into account. -Any modifications that you are doing to the other files in the src/ directory will not be taken into account.

- +Any modifications that you are doing to the other files in the src/ directory will not be taken into account.

Operations

Building

To build both the serial and the parallel versions, run make in the src/ directory:

student@so:~/.../content/assignments/parallel-graph$ cd src/

student@so:~/.../assignments/parallel-graph/src$ make

That will create the serial and parallel binaries.

Testing and Grading

Testing is automated. +Tests are located in the tests/ directory.

student@so:~/.../assignments/parallel-graph/tests$ ls -F
Makefile checker.py grade.sh@ in/

To test and grade your assignment solution, enter the tests/ directory and run grade.sh. +Note that this requires linters being available. +The easiest is to use a Docker-based setup with everything installed and configured. +When using grade.sh you will get grades for checking correctness (maximum 90 points) and for coding style (maxim 10 points). +A successful run will provide you an output ending with:

### GRADE


Checker: 90/ 90
Style: 10/ 10
Total: 100/100


### STYLE SUMMARY


Running the Checker

To run only the checker, use the make check command in the tests/ directory:

student@so:~/.../assignments/parallel-graph/tests$ make check
[...]
SRC_PATH=../src python checker.py
make[1]: Entering directory '...'
rm -f *~
[...]
TODO
test1.in ....................... failed ... 0.0
test2.in ....................... failed ... 0.0
test3.in ....................... failed ... 0.0
[...]

Total: 0/100

Obviously, all tests will fail, as there is no implementation.

Each test is worth a number of points. +The maximum grade is 90.

A successful run will show the output:

student@so:~/.../assignments/parallel-graph/tests$ make check
[...]
SRC_PATH=../src python checker.py
test1.in ....................... passed ... 4.5
test2.in ....................... passed ... 4.5
test3.in ....................... passed ... 4.5
test4.in ....................... passed ... 4.5
test5.in ....................... passed ... 4.5
test6.in ....................... passed ... 4.5
test7.in ....................... passed ... 4.5
test8.in ....................... passed ... 4.5
test9.in ....................... passed ... 4.5
test10.in ....................... passed ... 4.5
test11.in ....................... passed ... 4.5
test12.in ....................... passed ... 4.5
test13.in ....................... passed ... 4.5
test14.in ....................... passed ... 4.5
test15.in ....................... passed ... 4.5
test16.in ....................... passed ... 4.5
test17.in ....................... passed ... 4.5
test18.in ....................... passed ... 4.5
test19.in ....................... passed ... 4.5
test20.in ....................... passed ... 4.5

Total: 90/100

Running the Linters

To run the linters, use the make lint command in the tests/ directory:

student@so:~/.../assignments/parallel-graph/tests$ make lint
[...]
cd .. && checkpatch.pl -f checker/*.sh tests/*.sh
[...]
cd .. && cpplint --recursive src/ tests/ checker/
[...]
cd .. && shellcheck checker/*.sh tests/*.sh

Note that the linters have to be installed on your system: checkpatch.pl, cpplint, shellcheck. +They also need to have certain configuration options. +It's easiest to run them in a Docker-based setup with everything configured.

Fine-Grained Testing

Input tests cases are located in tests/in/. +If you want to run a single test, use commands such as below while in the src/ directory:

$./parallel ../tests/in/test5.in
-38

$ ./serial ../tests/in/test5.in
-38

Results provided by the serial and parallel implementation must be the same for the test to successfully pass.

+ \ No newline at end of file diff --git a/Assignments/index.html b/Assignments/index.html index fc2f84a6da..39e39da087 100644 --- a/Assignments/index.html +++ b/Assignments/index.html @@ -4,13 +4,13 @@ Assignments | Operating Systems - +
-
Skip to main content
- +
Skip to main content
+ \ No newline at end of file diff --git a/Lab/Application Interaction/arena/index.html b/Lab/Application Interaction/arena/index.html index 91da3306f7..352d9abc7d 100644 --- a/Lab/Application Interaction/arena/index.html +++ b/Lab/Application Interaction/arena/index.html @@ -4,7 +4,7 @@ Arena | Operating Systems - + @@ -47,7 +47,7 @@ So, in order to make the internet work, all we have to do is a simple NAT, with a command like:

root@8333e5cefb0d:/app# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE

Now, the virtual machines should have internet access:

root@8333e5cefb0d:/app# ssh root@192.168.0.2
[...]
root@ubuntu:~# curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

Now your task is to run the iptables command above automatically when the system starts, so that it's not necessary to run it manually like we did in the above example.

A good place to do this is in the create_one_network function in network.py. There you can add another subprocess.run call to run iptables. The 192.168.0.0/24 value should not be hardcoded, but you can take it from the ip_with_prefixlen member of the Net object.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/dbus/index.html b/Lab/Application Interaction/dbus/index.html index 66d484e185..801808cf80 100644 --- a/Lab/Application Interaction/dbus/index.html +++ b/Lab/Application Interaction/dbus/index.html @@ -4,7 +4,7 @@ D-Bus | Operating Systems - + @@ -38,7 +38,7 @@ Indeed, we see that this object exists in d-feet as well:

dfeet-firefox

We can try to call the OpenURL method ourselves, directly from d-feet. The method has only one argument of the type Array of [Byte]. Although there's no documentation for it, we can use the same byte array that we saw in dbus-monitor:

   array of bytes [
02 00 00 00 1a 00 00 00 2f 00 00 00 2f 68 6f 6d 65 2f 61 64 72 69 61 6e
73 00 2f 6f 70 74 2f 66 69 72 65 66 6f 78 2f 66 69 72 65 66 6f 78 00 77
77 77 2e 67 6f 6f 67 6c 65 2e 63 6f 6d 00
]

(Note that 77 77 77 2e 67 6f 6f 67 6c 65 2e 63 6f 6d at the end is the string www.google.com, so that's another confirmation that we're on the right track).

dfeet-url-open

- + \ No newline at end of file diff --git a/Lab/Application Interaction/index.html b/Lab/Application Interaction/index.html index aa34c55a0d..c2a5469b03 100644 --- a/Lab/Application Interaction/index.html +++ b/Lab/Application Interaction/index.html @@ -4,13 +4,13 @@ Application Interaction | Operating Systems - +
Skip to main content
- + \ No newline at end of file diff --git a/Lab/Application Interaction/os-cloud/index.html b/Lab/Application Interaction/os-cloud/index.html index 4926b658fb..8346af6e9f 100644 --- a/Lab/Application Interaction/os-cloud/index.html +++ b/Lab/Application Interaction/os-cloud/index.html @@ -4,7 +4,7 @@ OS Cloud | Operating Systems - + @@ -57,7 +57,7 @@ Then delete all vm disks with sudo rm -rf vm-disks/*.

With vm_stop implemented, the system should work like this:

student@os:~/.../support/os-cloud$ curl -s localhost:5000/vm_list | jq .
[
{
"id": 1,
"name": "my_vm"
}
]
student@os:~/.../support/os-cloud$ curl -H "Content-Type: application/json" -d '{ "id": 1}' localhost:5000/vm_scurl -s -H "Content-Type: application/json" -d '{ "id": 1 }' localhost:5000/vm_info | jq .
{
"disk_size": 10737418240,
"id": 1,
"ip": "192.168.0.2",
"mem_size": 2147483648,
"name": "my_vm",
"network": "default",
"os": "ubuntu_22.04",
"state": "RUNNING"
}

The vm is in the RUNNING state. Now let's stop it:

student@os:~/.../support/os-cloud$ curl -H "Content-Type: application/json" -d '{ "id": 1}' localhost:5000/vm_stop
{"status":"ok"}
student@os:~/.../support/os-cloud$ curl -s -H "Content-Type: application/json" -d '{ "id": 1 }' localhost:5000/vm_info | jq .
{
"disk_size": 10737418240,
"id": 1,
"ip": "192.168.0.2",
"mem_size": 2147483648,
"name": "my_vm",
"network": "default",
"os": "ubuntu_22.04",
"state": "STOPPED"
}

Now the state is STOPPED. Inside the container, the qemu process should be gone as well:

student@os:~/.../support/os-cloud$ docker-compose exec os-cloud bash
root@b0600eff8903:/app# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 10:00 ? 00:00:00 /sbin/docker-init -- python3 -u app.py
root 7 1 0 10:00 ? 00:00:00 python3 -u app.py
root 33 0 0 10:00 pts/3 00:00:00 bash
root 41 33 0 10:00 pts/3 00:00:00 ps -ef

Finally, the vm can be started again using vm_start:

student@os:~/.../support/os-cloud$ curl -H "Content-Type: application/json" -d '{ "id": 1}' localhost:5000/vm_start
{"status":"ok"}
- + \ No newline at end of file diff --git a/Lab/Application Interaction/overview/index.html b/Lab/Application Interaction/overview/index.html index 939c69ea28..caabdc681a 100644 --- a/Lab/Application Interaction/overview/index.html +++ b/Lab/Application Interaction/overview/index.html @@ -4,14 +4,14 @@ Application Interaction | Operating Systems - +
Skip to main content

Application Interaction

In this chapter, you will discover various mechanisms through which applications on a system can interact. You will see these mechanisms in action in existing applications, but also use them in some code of your own.

Setup

Make sure the following packages are installed:

sudo apt-get -y update; sudo apt-get -y install net-tools x11-apps libssl-dev d-feet firefox

Contents

  1. Time Server
  2. Password Cracker
  3. The X Window System
  4. D-Bus
  5. OS Cloud
  6. Arena
- + \ No newline at end of file diff --git a/Lab/Application Interaction/password-cracker/index.html b/Lab/Application Interaction/password-cracker/index.html index 921aeba4a0..f72cc6a2c3 100644 --- a/Lab/Application Interaction/password-cracker/index.html +++ b/Lab/Application Interaction/password-cracker/index.html @@ -4,7 +4,7 @@ Password Cracker | Operating Systems - + @@ -25,7 +25,7 @@ One simple way to do this is to print out the current process ID at the beginning of the function. To get the current process ID, use the getpid function from the os module.

Multithreaded Version in Python

Code in support/password-cracker/python/password-cracker-multithread.py.

The Python equivalent of the previous multithreaded version.

student@os:~/.../support/password-cracker$ python3 python/password-cracker-multithread.py
worker 7 found haxx

This example is given only to provide an idea of how a multithreaded program is written. Remember that CPU-bound threads in python don't actually run in parallel, due to the Global Interpreter Lock.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/quiz/cgroups-vs-namespaces/index.html b/Lab/Application Interaction/quiz/cgroups-vs-namespaces/index.html index a8a69774e5..1737e36ca4 100644 --- a/Lab/Application Interaction/quiz/cgroups-vs-namespaces/index.html +++ b/Lab/Application Interaction/quiz/cgroups-vs-namespaces/index.html @@ -4,14 +4,14 @@ Cgroups versus namespaces | Operating Systems - +
Skip to main content

Cgroups versus namespaces

Question Text

Which of the following affirmations about namespaces and cgroups is correct?

Question Answers

  • Cgroups provide resource management and namespaces provide isolation and security.
  • Namespaces provide resource management and cgroups provide isolation and security.

  • Both provide resource management.

  • Both provide isolation and security.

Feedback

They both serve different purposes, cgroups provide resource management and namespaces provide isolation and security. Cgroups manage resources, while namespaces isolate and secure them.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/quiz/container-vs-vm/index.html b/Lab/Application Interaction/quiz/container-vs-vm/index.html index a91b06cc5f..511bdaf34a 100644 --- a/Lab/Application Interaction/quiz/container-vs-vm/index.html +++ b/Lab/Application Interaction/quiz/container-vs-vm/index.html @@ -4,13 +4,13 @@ Container versus VM | Operating Systems - +
Skip to main content

Container versus VM

Question Text

What is one advantage of using containers over VMs in regard to starting times and memory consumption?

Question Answers

  • VMs can start up faster and use less memory than containers.
  • Containers can start up faster and use less memory than VMs.
  • The comparison cannot be made.

Feedback

This means that they impose less resource overhead than virtual machines, which need to run a complete guest operating system on top of the host operating system using a hypervisor.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/quiz/time-server-interop/index.html b/Lab/Application Interaction/quiz/time-server-interop/index.html index 46239523e0..d86a50f72d 100644 --- a/Lab/Application Interaction/quiz/time-server-interop/index.html +++ b/Lab/Application Interaction/quiz/time-server-interop/index.html @@ -4,7 +4,7 @@ Time Server Interoperability | Operating Systems - + @@ -12,7 +12,7 @@
Skip to main content

Time Server Interoperability

Question Text

Is the protocol between the python server and the python client the same? Can we run the python server and connect to it via the C client?

Question Answers

  • Yes
  • No, the protocols are different

Feedback

By doing the same investigation on the python server we discover that the protocol is the same. This means that we can run the python server and the C client, or the C server and python client, and everything will work:

student@os:~/.../support/time-server/python$ python3 server.py
student@os:~/.../support/time-server$ ./client 127.0.0.1 2000
The time is Thu Sep 1 11:48:03 2022
- + \ No newline at end of file diff --git a/Lab/Application Interaction/quiz/time-server/index.html b/Lab/Application Interaction/quiz/time-server/index.html index f2f2c31e07..207b0a3f8c 100644 --- a/Lab/Application Interaction/quiz/time-server/index.html +++ b/Lab/Application Interaction/quiz/time-server/index.html @@ -4,13 +4,13 @@ Time Server Protocol | Operating Systems - +
Skip to main content

Time Server Protocol

Question Text

What format does the message exchanged between the server and the client have?

Question Answers

  • 4 byte length (little endian) followed by 8 byte timestamp (little endian)

  • 8 byte length (little endian) followed by 4 byte timestamp (little endian)

  • 4 byte length (big endian) followed by 8 byte timestamp (big endian)
  • 8 byte length (big endian) followed by 4 byte timestamp (big endian)

Feedback

If we consider one output example:

00000000  00 00 00 08 00 00 00 00  63 1b a9 50              |........c..P|
0000000c

We can identify the 4 byte length in big endian (00 00 00 08), then the 8 byte timestamp (00 00 00 00 63 1b a9 50), also in big endian.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/quiz/timer/index.html b/Lab/Application Interaction/quiz/timer/index.html index bfd5693642..89dba00e4e 100644 --- a/Lab/Application Interaction/quiz/timer/index.html +++ b/Lab/Application Interaction/quiz/timer/index.html @@ -4,13 +4,13 @@ Oneko Timer | Operating Systems - +
Skip to main content

Oneko Timer

Question Text

What is the purpose of the timer used in the Oneko's implementantion

Question Answers

  • Slow down the cat
  • Speed up the cat

  • It server no purpose

Feedback

The purpose of the timer is to delay the cat. You can verify this by running

while true; do kill -14 $(pidof oneko)

You'll notice the cat is much faster in following your mouse.

Try and find other ways to "hack" Oneko to make it move faster.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/quiz/vm-creation/index.html b/Lab/Application Interaction/quiz/vm-creation/index.html index e0357f607a..b4d73e2eab 100644 --- a/Lab/Application Interaction/quiz/vm-creation/index.html +++ b/Lab/Application Interaction/quiz/vm-creation/index.html @@ -4,13 +4,13 @@ VM Creation | Operating Systems - +
Skip to main content

VM Creation

Question Text

How do you create a new virtual machine with a memory of 3GB and disk size of 100 GB?

Question Answers

  • By running curl -H "Content-Type: application/json" -d '{ "name": "my_vm", "image": "ubuntu_22.04", "network": "default", "mem_size": "3G", "disk_size": "100G"}' localhost:5000/vm_create
  • By running curl -H "Content-Type: application/json" -d '{ "name": "my_vm", "image": "ubuntu_22.04", "network": "default", "mem_size": "3G", "disk_size": "100G"}' localhost:5000/vm_delete

  • By running curl -H "Content-Type: application/json" -d '{ "name": "my_vm", "image": "ubuntu_22.04", "network": "default", "mem_size": "3G", "disk_size": "101G"}' localhost:5000/vm_create

  • By running curl -H "Content-Type: application/json" -d '{ "name": "my_vm", "image": "ubuntu_22.04", "network": "default", "mem_size": "6G", "disk_size": "1000G"}' localhost:5000/vm_delete

Feedback

We need to uso curl with the right path localhost:5000/vm_create, specifying the right data { "name": "my_vm", "image": "ubuntu_22.04", "network": "default", "mem_size": "3G", "disk_size": "100G"}.

- + \ No newline at end of file diff --git a/Lab/Application Interaction/time-server/index.html b/Lab/Application Interaction/time-server/index.html index 52d5c4c1e7..e641cf40fc 100644 --- a/Lab/Application Interaction/time-server/index.html +++ b/Lab/Application Interaction/time-server/index.html @@ -4,7 +4,7 @@ Time Server | Operating Systems - + @@ -14,7 +14,7 @@ Once a client has connected, the server will send the current time to it. The client will then print the received time to the console.

Let's build and run this example:

student@os:~/.../support/time-server$ make
gcc -Wall -o server server.c
gcc -Wall -o client client.c
student@os:~/.../support/time-server$ ./server

Then, in another terminal:

student@os:~/.../support/time-server$ ./client 127.0.0.1 2000
The time is Thu Sep 1 11:48:03 2022

Python Version

In support/time-server/python we have the equivalent python implementation for both the server and client:

student@os:~/.../support/time-server/python$ python3 server.py
student@os:~/.../support/time-server/python$ python3 client.py 127.0.0.1 2000
The time is Thu Sep 1 11:58:01 2022

Practice

Try to figure out the protocol used by the server and the client. You can do this by reading the source code, corroborated with information obtained at runtime.

Run the server again (the version in C), but instead of running the client, let's run netcat and pipe the output to hexdump:

nc -d 127.0.0.1 2000 | hexdump -C

Quiz

Quiz

- + \ No newline at end of file diff --git a/Lab/Application Interaction/x-window-system/index.html b/Lab/Application Interaction/x-window-system/index.html index c2a2c681ee..1a35811642 100644 --- a/Lab/Application Interaction/x-window-system/index.html +++ b/Lab/Application Interaction/x-window-system/index.html @@ -4,7 +4,7 @@ The X Window System | Operating Systems - + @@ -17,7 +17,7 @@ A very simple example is the xeyes application:

student@os:~$ strace -e trace=socket,connect xeyes
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path=@"/tmp/.X11-unix/X0"}, 20) = 0

As expected, the application creates a Unix socket, then connects to the path @"/tmp/.X11-unix/X0".

Furthermore, let's confirm that there is actual communication taking place between xeyes and the X server. We'll run xeyes again, and then we'll keep moving the mouse cursor around. When the mouse is moved, the following events are taking place:

So, if we run xeyes under strace, we expect to see some communication on the Unix socket that is created at the beginning:

strace -e 'trace=!poll' -e trace='socket,connect,recvmsg' xeyes |& grep -v '\-1 EAGAIN'

strace-xeyes

- + \ No newline at end of file diff --git a/Lab/Compute/arena/index.html b/Lab/Compute/arena/index.html index 45cae795cc..767420d8f8 100644 --- a/Lab/Compute/arena/index.html +++ b/Lab/Compute/arena/index.html @@ -4,7 +4,7 @@ Arena | Operating Systems - + @@ -130,7 +130,7 @@ Note the second number go up in the monitoring terminal.

Comment the posix_fadvise() call, recompile the program, and run it again. You won't get any major page fault, because the file contents are cached by the OS, to avoid those page faults. As a rule, the OS will avoid major page faults whenever possible, because they are very costly in terms of running time.

- + \ No newline at end of file diff --git a/Lab/Compute/copy-on-write/index.html b/Lab/Compute/copy-on-write/index.html index 021111e3ef..5d1463c5a8 100644 --- a/Lab/Compute/copy-on-write/index.html +++ b/Lab/Compute/copy-on-write/index.html @@ -4,7 +4,7 @@ Copy-on-Write | Operating Systems - + @@ -33,7 +33,7 @@ It's a way of marking certain allocated pages so that copy-on-write is disabled. As you may imagine, changes made by the parent to this memory are visible to the child and vice-versa. You can learn more about it in its dedicated section in the Arena.

- + \ No newline at end of file diff --git a/Lab/Compute/hardware-perspective/index.html b/Lab/Compute/hardware-perspective/index.html index 726cdca42c..ee4ca0a001 100644 --- a/Lab/Compute/hardware-perspective/index.html +++ b/Lab/Compute/hardware-perspective/index.html @@ -4,7 +4,7 @@ Hardware Perspective | Operating Systems - + @@ -31,7 +31,7 @@ Similarly, each process can spawn however many threads, which are also managed by the OS. The OS decides when and on what CPU core to make each thread run. This is in line with the general interaction between an application and the hardware: it is always mediated by the OS.

- + \ No newline at end of file diff --git a/Lab/Compute/index.html b/Lab/Compute/index.html index eba9a4ed44..a8d86b733a 100644 --- a/Lab/Compute/index.html +++ b/Lab/Compute/index.html @@ -4,13 +4,13 @@ Compute | Operating Systems - +
Skip to main content
- + \ No newline at end of file diff --git a/Lab/Compute/overview/index.html b/Lab/Compute/overview/index.html index 00957e5dfd..ae9c19ca62 100644 --- a/Lab/Compute/overview/index.html +++ b/Lab/Compute/overview/index.html @@ -4,13 +4,13 @@ Compute | Operating Systems - +
Skip to main content
- + \ No newline at end of file diff --git a/Lab/Compute/processes-threads-apache2/index.html b/Lab/Compute/processes-threads-apache2/index.html index 7833e7d8dc..b8b9263b5e 100644 --- a/Lab/Compute/processes-threads-apache2/index.html +++ b/Lab/Compute/processes-threads-apache2/index.html @@ -4,7 +4,7 @@ Usage of Processes and Threads in `apache2` | Operating Systems - + @@ -37,7 +37,7 @@ This is required by the very large workloads such applications are commonly required to process.

These rules are not set in stone, though. Like we saw in the apache2 example, the server uses multiple threads as well as multiple processes. This provides a degree of stability - if one worker thread crashes, it will only crash the other threads belonging to the same process - while still taking advantage of the light resource usage inherent to threads.

These kinds of trade-offs are a normal part of the development of real-world applications.

- + \ No newline at end of file diff --git a/Lab/Compute/processes/index.html b/Lab/Compute/processes/index.html index af0bcbd890..d6e2410c61 100644 --- a/Lab/Compute/processes/index.html +++ b/Lab/Compute/processes/index.html @@ -4,7 +4,7 @@ Processes | Operating Systems - + @@ -84,7 +84,7 @@ Use a similar logic and a similar set of prints to those in the support code. Take a look at the printed PIDs. Make sure the PPID of the "grandchild" is the PID of the child, whose PPID is, in turn, the PID of the parent.

Moral of the story: Usually the execution flow is:

  1. fork(), followed by

  2. wait() (called by the parent)

  3. exit(), called by the child.

The order of last 2 steps may be swapped.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/apache2-strace/index.html b/Lab/Compute/quiz/apache2-strace/index.html index 7c16c8a4eb..6338456bfa 100644 --- a/Lab/Compute/quiz/apache2-strace/index.html +++ b/Lab/Compute/quiz/apache2-strace/index.html @@ -4,14 +4,14 @@ `apache2` Document Root | Operating Systems - +
Skip to main content

apache2 Document Root

Question Text

What is the document root of the apache2 server?

Question Answers

  • /etc/apache2
  • /usr/local/apache2/htdocs/
  • /var/www/html

  • /var/www/apache2/htdocs

Feedback

In strace we see that the server opens the file /usr/local/apache2/htdocs/index.html. This means that the document root is /usr/local/apache2/htdocs/.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/cause-of-file-not-found-error/index.html b/Lab/Compute/quiz/cause-of-file-not-found-error/index.html index cb6b714391..0dbd974bf3 100644 --- a/Lab/Compute/quiz/cause-of-file-not-found-error/index.html +++ b/Lab/Compute/quiz/cause-of-file-not-found-error/index.html @@ -4,7 +4,7 @@ Cause of `FileNotFoundError` | Operating Systems - + @@ -15,7 +15,7 @@ It's impossible to say what kind of data will be used by the first thread. In our case, the data is the file you give to the script as an argument. If scheduling the parent process or its running time takes long enough, the file may have been created by the time the parent needs it, but we can never be sure.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/child-faults-after-write/index.html b/Lab/Compute/quiz/child-faults-after-write/index.html index ca3fb868da..c6c6ff6e20 100644 --- a/Lab/Compute/quiz/child-faults-after-write/index.html +++ b/Lab/Compute/quiz/child-faults-after-write/index.html @@ -4,13 +4,13 @@ Child Faults After Write | Operating Systems - +
Skip to main content

Child Faults After Write

Question Text

What causes the page faults registered by the child after the fifth step?

Question Answers

  • The child writes data to the frames it previously shared with its parent and the copy-on-write mechanism copies and remaps them before writing said data
  • Demand paging propagates the lazy allocation of pages from the parent to the child

  • Creating the child process inherently duplicates some frames

  • They are caused by the loader forking itself when creating the child process

  • They are caused by the bash process forking itself when creating the child process

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/coarse-vs-granular-critical-section/index.html b/Lab/Compute/quiz/coarse-vs-granular-critical-section/index.html index 2089c8fce2..4e40926b82 100644 --- a/Lab/Compute/quiz/coarse-vs-granular-critical-section/index.html +++ b/Lab/Compute/quiz/coarse-vs-granular-critical-section/index.html @@ -4,7 +4,7 @@ Coarse vs Granular Critical Section | Operating Systems - + @@ -14,7 +14,7 @@ The second thread then finds the mutex locked and enters the WAITING state. When the first thread finishes its loop, it calls unlock() and wakes up the second thread, which acquires the lock and starts its loop.

In the more granular example, in the worst case, the holder of the mutex can change at every step of the loop. This would mean 1 context switch per step per thread, i.e. 20 million context switches.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/create-sleepy-process-ending/index.html b/Lab/Compute/quiz/create-sleepy-process-ending/index.html index 45c87cb268..62539ddefd 100644 --- a/Lab/Compute/quiz/create-sleepy-process-ending/index.html +++ b/Lab/Compute/quiz/create-sleepy-process-ending/index.html @@ -4,14 +4,14 @@ `create_sleepy` Process Ending | Operating Systems - +
Skip to main content

create_sleepy Process Ending

Question Text

Why does the create_sleepy process wait a very long time before ending? Use system's man page to find the answer.

Question Answers

  • Because the code is unoptimised (the default optimisation level is -O0)

  • Because the operating system takes very long to finish the process

  • Because system returns when the command given to it (sleep 1000) ends
  • Because the CPU is very slow

Feedback

The man page says it clearly:

system() returns after the command has been completed.

Therefore, in our case, it returns after sleep 1000 ends.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/fiber-strace/index.html b/Lab/Compute/quiz/fiber-strace/index.html index 117e01dee4..b6ee8df997 100644 --- a/Lab/Compute/quiz/fiber-strace/index.html +++ b/Lab/Compute/quiz/fiber-strace/index.html @@ -4,14 +4,14 @@ Fiber Strace | Operating Systems - +
Skip to main content

Fiber Strace

Question Text

How many clone() system calls are performed when creating a fiber?

Question Answers

  • none
  • one for each fiber

  • one for every 2 fibers

  • 2 for each fiber

Feedback

Being user-level threads, the fibers aren't created by the operating system. The only system calls that you see used are mmap() and munmap(), used to create each fiber's stack.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/mini-shell-stops-after-command/index.html b/Lab/Compute/quiz/mini-shell-stops-after-command/index.html index 440808182a..39787808de 100644 --- a/Lab/Compute/quiz/mini-shell-stops-after-command/index.html +++ b/Lab/Compute/quiz/mini-shell-stops-after-command/index.html @@ -4,7 +4,7 @@ Mini-shell Stops After Command | Operating Systems - + @@ -13,7 +13,7 @@ So when you exec*("ls"), for example, the mini_shell process becomes ls. There is no more mini_shell past this point. So when ls ends, there is no mini_shell process to continue its execution anymore.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/mmap-cow-flag/index.html b/Lab/Compute/quiz/mmap-cow-flag/index.html index ac3e85c561..d90d7de27b 100644 --- a/Lab/Compute/quiz/mmap-cow-flag/index.html +++ b/Lab/Compute/quiz/mmap-cow-flag/index.html @@ -4,13 +4,13 @@ Copy-on-write Flag for `mmap()` | Operating Systems - +
Skip to main content

Copy-on-write Flag for mmap()

Question Text

From the description in its man page, what flag should we pass to mmap() in order to mark the mapped pages as copy-on-write?

Question Answers

  • MAP_SHARED
  • MAP_PRIVATE
  • MAP_ANONYMOUS

  • MAP_POPULATE

Feedback

Quoting the man page:

MAP_PRIVATE
Create a private copy-on-write mapping.
- + \ No newline at end of file diff --git a/Lab/Compute/quiz/notify-only-with-mutex/index.html b/Lab/Compute/quiz/notify-only-with-mutex/index.html index 56173082bc..04482e19d6 100644 --- a/Lab/Compute/quiz/notify-only-with-mutex/index.html +++ b/Lab/Compute/quiz/notify-only-with-mutex/index.html @@ -4,7 +4,7 @@ Both Condition and Mutex | Operating Systems - + @@ -13,7 +13,7 @@ For this reason, it is unsafe to only use a mutex as a notification mechanism. In addition, a mutex cannot notify more than one thread at once, if we so desire. Mutexes are only meant to be used to isolate a critical section within the same thread.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/number-of-running-ults/index.html b/Lab/Compute/quiz/number-of-running-ults/index.html index 6438296c68..3f7ac4a59e 100644 --- a/Lab/Compute/quiz/number-of-running-ults/index.html +++ b/Lab/Compute/quiz/number-of-running-ults/index.html @@ -4,14 +4,14 @@ Number of RUNNING User-Level Threads | Operating Systems - +
Skip to main content

Number of RUNNING User-Level Threads

Question Text

How many threads can be RUNNING simultaneously if we only create them using the API exposed by libult.so?

Question Answers

  • Equal to the number of cores on the CPU
  • 1
  • None

  • 2: the main thread and another one for the created threads

Feedback

Only kernel-level threads can run in parallel. Since all libult.so threads are user-level threads, they run within the same kernel-level thread, so only one of them can run at any time.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/parent-faults-before-fork/index.html b/Lab/Compute/quiz/parent-faults-before-fork/index.html index c17eeddfe0..ab928399e1 100644 --- a/Lab/Compute/quiz/parent-faults-before-fork/index.html +++ b/Lab/Compute/quiz/parent-faults-before-fork/index.html @@ -4,13 +4,13 @@ Parent Faults before `fork()` | Operating Systems - +
Skip to main content

Parent Faults before fork()

Question Text

What causes the page faults that occur between the first and second steps?

Question Answers

  • Calling fork() duplicates the pages previously allocated by the parent
  • Demand paging makes the pages in the p array to be mapped to frames only when written
  • The OS duplicates the parent's pages in preparation for fork()

  • mmap() sets the pages to be mapped at a later time, decided by the OS

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/parent-of-sleep-processes/index.html b/Lab/Compute/quiz/parent-of-sleep-processes/index.html index cd7dd3d5b0..e7072823ab 100644 --- a/Lab/Compute/quiz/parent-of-sleep-processes/index.html +++ b/Lab/Compute/quiz/parent-of-sleep-processes/index.html @@ -4,7 +4,7 @@ Parent of `sleep` Processes | Operating Systems - + @@ -13,7 +13,7 @@ Why?

Question Answers

Feedback

When a process dies without waiting for the termination of all its children, those processes are now orphans. Then the systemd process adopts those orphan processes by default. On older Linux systems, it was the init process who adopted orphans.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/processes-speedup/index.html b/Lab/Compute/quiz/processes-speedup/index.html index c6bb49bfe0..414499bd15 100644 --- a/Lab/Compute/quiz/processes-speedup/index.html +++ b/Lab/Compute/quiz/processes-speedup/index.html @@ -4,7 +4,7 @@ Processes Speedup | Operating Systems - + @@ -16,7 +16,7 @@ Therefore there will always be parts of any given program that cannot be run in parallel. As a result, the speedup can never be equal to the number of processes between which we spread the workload.

It is possible to compute the speedup obtained from parallelising a portion of a given program. The formula is rather simple and is called Amdahl's law

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/seg-fault-exit-code/index.html b/Lab/Compute/quiz/seg-fault-exit-code/index.html index b03f87f93b..55924166ce 100644 --- a/Lab/Compute/quiz/seg-fault-exit-code/index.html +++ b/Lab/Compute/quiz/seg-fault-exit-code/index.html @@ -4,7 +4,7 @@ Seg Fault Exit Code | Operating Systems - + @@ -13,7 +13,7 @@ We can use the WIFSIGNALED() and WTERMSIG() marcros. By doing so, we see the exit code of the faulty child process is 11. We can then use the kill -l command to view the code of each signal and SIGSEGV has the code 11.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/semaphore-equivalent/index.html b/Lab/Compute/quiz/semaphore-equivalent/index.html index ce85bd6d19..3802c66492 100644 --- a/Lab/Compute/quiz/semaphore-equivalent/index.html +++ b/Lab/Compute/quiz/semaphore-equivalent/index.html @@ -4,14 +4,14 @@ Semaphore Equivalent | Operating Systems - +
Skip to main content

Semaphore Equivalent

Question Text

From running and inspecting the code in support/apache2-simulator/apache2_simulator_semaphore.py, which of the following is an an equivalent to the value of the semaphore sem?

Question Answers

  • The value of msg_mutex

  • The time a worker thread has to wait before running

  • The length of the messages list
  • The number of worker threads

Feedback

sem is incremented (release()) upon adding a message to the messages list and decremented (acquire()) when removing a message from said list. So it's a rough equivalent to the length of this list.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/sleeping-on-a-fiber/index.html b/Lab/Compute/quiz/sleeping-on-a-fiber/index.html index a29c81cf22..8f449ea2c4 100644 --- a/Lab/Compute/quiz/sleeping-on-a-fiber/index.html +++ b/Lab/Compute/quiz/sleeping-on-a-fiber/index.html @@ -4,14 +4,14 @@ Sleeping on a Fiber | Operating Systems - +
Skip to main content

Sleeping on a Fiber

Question Text

What happens if a fiber calls sleep()?

Question Answers

  • the whole kernel-level thread is blocked
  • only that fiber is blocked, and is scheduled out

  • nothing, a fiber can't sleep

  • the whole process sleeps - regardless of how many threads there are

Feedback

The whole thread on which the fiber runs is blocked until the sleep() call is finished. For this reason, the fibers are best used with asynchronous operations, which you will explore in the following weeks.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/state-of-new-ult/index.html b/Lab/Compute/quiz/state-of-new-ult/index.html index 50ea188320..65d57d45eb 100644 --- a/Lab/Compute/quiz/state-of-new-ult/index.html +++ b/Lab/Compute/quiz/state-of-new-ult/index.html @@ -4,14 +4,14 @@ State of new ULT | Operating Systems - +
Skip to main content

State of new ULT

Question Text

What is the first state that is assigned to a newly created ULT?

Question Answers

  • RUNNING
  • READY
  • COMPLETED

Feedback

Inside the function threads_create(), we can see the following snippet queue_enqueue(ready, new). Each new thread is thus added to the READY queue.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/tcb-libult-unikraft/index.html b/Lab/Compute/quiz/tcb-libult-unikraft/index.html index 48c80f2743..2431bb6b42 100644 --- a/Lab/Compute/quiz/tcb-libult-unikraft/index.html +++ b/Lab/Compute/quiz/tcb-libult-unikraft/index.html @@ -4,7 +4,7 @@ Similarities Between the TCBs of `libult` and Unikraft | Operating Systems - + @@ -14,7 +14,7 @@ argument and arg are pointers to the arguments of start_routine and entry, respectively. context and ctx are the contexts in which the new threads run. return_value and prv are both pointers to the values returned by the thread functions.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/thread-memory/index.html b/Lab/Compute/quiz/thread-memory/index.html index af778f5976..0d91bc8605 100644 --- a/Lab/Compute/quiz/thread-memory/index.html +++ b/Lab/Compute/quiz/thread-memory/index.html @@ -4,14 +4,14 @@ Thread Memory | Operating Systems - +
Skip to main content

Thread Memory

Question Text

Is data used by a thread inaccessible from other threads?

Question Answers

  • Yes, each thread has its own stack
  • No, each thread can access every address from the virtual address space
  • Only the heap is shared

  • Only the heap and the read-only zones are shared

Feedback

Each thread has the same perspective on the system memory - it thinks it owns it all. Therefore, it can perform pointer arithmetic to access every memory address.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/time-slice-value/index.html b/Lab/Compute/quiz/time-slice-value/index.html index d805a0a50a..ad09944f30 100644 --- a/Lab/Compute/quiz/time-slice-value/index.html +++ b/Lab/Compute/quiz/time-slice-value/index.html @@ -4,13 +4,13 @@ Time Slice Value | Operating Systems - +
Skip to main content

Time Slice Value

Question Text

Using the man page, what is the time slice used by the scheduler in libult.so?

Question Answers

  • 100 milliseconds

  • 10 microseconds

  • 100 microseconds

  • 10 milliseconds

Feedback

The code we're interested in lies in the function init_profiling_timer():

const struct itimerval timer = {
{ 0, 10000 },
{ 0, 1 } // arms the timer as soon as possible
};

The man page gives the following definition the struct itimerval:

struct itimerval {
struct timeval it_interval; /* Interval for periodic timer */
struct timeval it_value; /* Time until next expiration */
};

struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};

So when constructing the timer variable, { 0, 10000 } means 0 seconds and 10000 microseconds, i.e. 0 seconds and 10 milliseconds.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/tls-synchronization/index.html b/Lab/Compute/quiz/tls-synchronization/index.html index e5f3be8567..87003c7a8b 100644 --- a/Lab/Compute/quiz/tls-synchronization/index.html +++ b/Lab/Compute/quiz/tls-synchronization/index.html @@ -4,14 +4,14 @@ TLS Synchronization | Operating Systems - +
Skip to main content

TLS Synchronization

Question Text

Is placing var from support/race-condition/c/race_condition_tls.c in the TLS a valid form of synchronization?

Question Answers

  • No, because the race condition remains. It just doesn't manifest itself anymore
  • No, because the threads now access different variables, not the same one
  • Yes, because we now remove the race condition

  • Yes, because now the result is correct

Feedback

Synchronization means that both threads should access the same variable, whereas placing it in the TLS makes each of them access a copy of the variable.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/tls-var-copies/index.html b/Lab/Compute/quiz/tls-var-copies/index.html index aef3ab56ef..4bd07847b1 100644 --- a/Lab/Compute/quiz/tls-var-copies/index.html +++ b/Lab/Compute/quiz/tls-var-copies/index.html @@ -4,13 +4,13 @@ TLS `var` Copies | Operating Systems - +
Skip to main content

TLS var Copies

Question Text

How many copies of the var variable from support/race-condition/c/race_condition_tls.c are there after each thread has modified it at leas once?

Question Answers

  • 1

  • 2

  • 3
  • 5

Feedback

There are 3 copies one for the main() thread, another one for increment_var() and the third for decrement_var().

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/type-of-scheduler-in-libult/index.html b/Lab/Compute/quiz/type-of-scheduler-in-libult/index.html index 3cbcf96505..8dc5a3e7c5 100644 --- a/Lab/Compute/quiz/type-of-scheduler-in-libult/index.html +++ b/Lab/Compute/quiz/type-of-scheduler-in-libult/index.html @@ -4,7 +4,7 @@ Type of Scheduler in `libult.so` | Operating Systems - + @@ -13,7 +13,7 @@ Which type of scheduler does libult.so use?

Question Answers

Feedback

libult.so uses a preemptive scheduler. Its timer is initialised in the init_profiling_timer() function. The context switch is performed in the handle_sigprof() function.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/ult-thread-ids/index.html b/Lab/Compute/quiz/ult-thread-ids/index.html index 792e5dad18..e64a1e65cc 100644 --- a/Lab/Compute/quiz/ult-thread-ids/index.html +++ b/Lab/Compute/quiz/ult-thread-ids/index.html @@ -4,7 +4,7 @@ ULT Thread IDs | Operating Systems - + @@ -15,7 +15,7 @@ This is needed in order to associate a ucontext_t with the main thread as well, so the main thread can also be run.

Feedback

The threads_create() function calls init_first_context(), which, in turn, calls tcb_new(), thus creating the first context associated with the main thread (the one calling threads_create() the first time). Without this, the scheduler in libult.so wouldn't be able to run the main thread.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/who-calls-execve-parent/index.html b/Lab/Compute/quiz/who-calls-execve-parent/index.html index d74fd6ea7c..62ef36b236 100644 --- a/Lab/Compute/quiz/who-calls-execve-parent/index.html +++ b/Lab/Compute/quiz/who-calls-execve-parent/index.html @@ -4,13 +4,13 @@ Who Calls `execve` in the Log of the Parent Process? | Operating Systems - +
Skip to main content

Who Calls execve in the Log of the Parent Process?

Question Text

Which process calls execve("sleepy_creator", ["sleepy_creator"], ...), that you found in the log of the parent process?

Question Answers

  • The kernel because that's where the loader is located

  • The loader because it is the loader who creates new processes

  • The C runtime because this is the C interpreter

  • bash because we run sleepy_creator from terminal, i.e. from bash

Feedback

All processes spawned from the command-line are children of the current bash process.

- + \ No newline at end of file diff --git a/Lab/Compute/quiz/why-use-completed-queue/index.html b/Lab/Compute/quiz/why-use-completed-queue/index.html index 4cb91b7a13..f818dcd840 100644 --- a/Lab/Compute/quiz/why-use-completed-queue/index.html +++ b/Lab/Compute/quiz/why-use-completed-queue/index.html @@ -4,7 +4,7 @@ The Need for a COMPLETED Queue | Operating Systems - + @@ -14,7 +14,7 @@ It is used by threads_create() to start executing the given function. This is a wrapper that calls the function associated with the thread (this->start_routine), saves its result and then calls threads_exit() to store this result in the COMPLETED queue.

- + \ No newline at end of file diff --git a/Lab/Compute/synchronization/index.html b/Lab/Compute/synchronization/index.html index 638bd197da..d94e6e3010 100644 --- a/Lab/Compute/synchronization/index.html +++ b/Lab/Compute/synchronization/index.html @@ -4,7 +4,7 @@ Synchronization | Operating Systems - + @@ -134,7 +134,7 @@ See that they differ.

  • Modify the value of var in the main() function before calling pthread_create(). Notice that the value doesn't propagate to the other threads. This is because, upon creating a new thread, its TLS is initialised.

  • - + \ No newline at end of file diff --git a/Lab/Compute/threads/index.html b/Lab/Compute/threads/index.html index 7d1eec8d20..7505a68225 100644 --- a/Lab/Compute/threads/index.html +++ b/Lab/Compute/threads/index.html @@ -4,7 +4,7 @@ Threads | Operating Systems - + @@ -58,7 +58,7 @@ You can check the executable is statically linked by executing the command ldd multithreaded. Notice the same effect of the thread creation on the process memory layout: the creation of a new stack of 8192 KB.

  • Make a program in another language of your choice that creates threads. Investigate it with pmap.

  • Quiz

    - + \ No newline at end of file diff --git a/Lab/Compute/user-level-threads/index.html b/Lab/Compute/user-level-threads/index.html index 114cd18ce7..01bd1bc64f 100644 --- a/Lab/Compute/user-level-threads/index.html +++ b/Lab/Compute/user-level-threads/index.html @@ -4,7 +4,7 @@ User-Level Threads | Operating Systems - + @@ -44,7 +44,7 @@ The work_stealing scheduler, as the name suggests, will "steal" fibers from other schedulers. So, if the shared_work scheduler tried to balance the available work between the available threads, the work_stealing one will focus on having as many threads as possible on 100% workload. Vary the number of threads and fibers, and the workload (maybe put each fibre to do some computational-intensive work), and observe the results.

    C++ unique_lock

    unique_lock is a type of mutex that is unlocked automatically when the end of its scope is reached (end of function or bracket-pair).

    - + \ No newline at end of file diff --git a/Lab/Data/arena/index.html b/Lab/Data/arena/index.html index 964e4e65b6..df18813ac3 100644 --- a/Lab/Data/arena/index.html +++ b/Lab/Data/arena/index.html @@ -4,7 +4,7 @@ Arena | Operating Systems - + @@ -68,7 +68,7 @@ Comment the version(none) annotation for the assignment operator and implement the logic so that the reference counted array is correct. When an object is assigned to another object, we need to first decrement the count for the object that is being assigned to, then fill the fields similarly to the copy constructor case and lastly increment the count for the assigned object. After completing the exercise, make sure that the memory is properly managed.

  • Play with your reference counted array and create different scenarios to test its limits.

  • - + \ No newline at end of file diff --git a/Lab/Data/index.html b/Lab/Data/index.html index cfe512fad1..9be3279c03 100644 --- a/Lab/Data/index.html +++ b/Lab/Data/index.html @@ -4,13 +4,13 @@ Data | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lab/Data/investigate-memory/index.html b/Lab/Data/investigate-memory/index.html index 2298875f0f..b19dfed96d 100644 --- a/Lab/Data/investigate-memory/index.html +++ b/Lab/Data/investigate-memory/index.html @@ -4,7 +4,7 @@ Investigate Memory Actions | Operating Systems - + @@ -44,7 +44,7 @@ Also, if the XMALLOC_POISON macro is defined, all the allocated data is overwritten with a "poison" value (0xA5). This is useful for early detection of memory-related issues, although, evidently, it adds overhead.

    We can look for parts of the source code with the largest number of uses of xmalloc():

    student@os:~/.../lab/support/git$ grep -rc 'xmalloc(' . | grep -v ':0' | sort -n -t ':' -k 20
    [...]
    ./compat/mingw.c:6
    ./submodule-config.c:6
    ./merge-recursive.c:7

    We can look into the merge-recursive.c file for uses of the xmalloc() function.

    Practice

    1. Do the same actions as above for the mmap() and xmmap() function calls.

      Note that these are not memory allocation calls, since a valid fd file argument is passed. These are file mapping calls, that we will talk more as part of the I/O chapter.

    - + \ No newline at end of file diff --git a/Lab/Data/memory-security/index.html b/Lab/Data/memory-security/index.html index d412078cef..81c660247d 100644 --- a/Lab/Data/memory-security/index.html +++ b/Lab/Data/memory-security/index.html @@ -4,7 +4,7 @@ Memory Security | Operating Systems - + @@ -59,7 +59,7 @@ Try to identify the canary value. Using the addr variable, write 2 scanf instructions: one that overwrites the canary with the corect value and one that overwrites the return address with the address of function pawned. In case of a successful exploit a video will be offered as reward.

    Answer this quiz

    - + \ No newline at end of file diff --git a/Lab/Data/overview/index.html b/Lab/Data/overview/index.html index 7d726d9476..5ec700d1c1 100644 --- a/Lab/Data/overview/index.html +++ b/Lab/Data/overview/index.html @@ -4,7 +4,7 @@ Data | Operating Systems - + @@ -16,7 +16,7 @@ The programming language analyzes the use of these variables and outputs code that uses an interface provided by the operating system. This interface offers the possibility to allocate/deallocate different variables in certain memory regions. Next, the operating system manages the execution of the program and provides the actual physical addresses that are used to interact with the data.

    Moreover, the operating system governs the competing access of multiple programs to memory, ensuring that a program does not have access to a different program's memory.

    Contents

    1. Working with Memory
    2. Process Memory
    3. Investigate Memory
    4. Memory Security
    5. Arena
    - + \ No newline at end of file diff --git a/Lab/Data/process-memory/index.html b/Lab/Data/process-memory/index.html index 4d025aa4ad..a42210f6a8 100644 --- a/Lab/Data/process-memory/index.html +++ b/Lab/Data/process-memory/index.html @@ -4,7 +4,7 @@ Process Memory | Operating Systems - + @@ -67,7 +67,7 @@ You will get more detailed information about this in the I/O chapter.

    Browse the two source code files (mmap_copy.c and read_write_copy.c) for a glimpse on how the two types of copies are implemented.

    Quiz

    Practice

    1. Use a different value for BUFSIZE and see if that affects the comparison between the two executables.

    2. Add a sleep() call to the mmap_copy.c file after the files were mapped. Rebuild the program and run it. On a different console, use pmap to view the two new memory regions that were added to the process, by mapping the in.dat and out.dat files.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/bypass-canary/index.html b/Lab/Data/quiz/bypass-canary/index.html index 8f198bc3eb..0a18dc7807 100644 --- a/Lab/Data/quiz/bypass-canary/index.html +++ b/Lab/Data/quiz/bypass-canary/index.html @@ -4,13 +4,13 @@ Bypass Canary | Operating Systems - +
    Skip to main content

    Bypass Canary

    Question

    If we enable ASLR, can we still exploit the stack_protector program?

    • no, because the address of pawned is going to be different for every run.

    • yes, because ASLR cannot work well when the canary is activated.

    • yes, because ASLR randomizes the start address of a section, but the offsets remain the same.
    • no, because the address to which addr points to is going to be random
    - + \ No newline at end of file diff --git a/Lab/Data/quiz/half-page/index.html b/Lab/Data/quiz/half-page/index.html index 541862f814..ce1ad5d1ef 100644 --- a/Lab/Data/quiz/half-page/index.html +++ b/Lab/Data/quiz/half-page/index.html @@ -4,7 +4,7 @@ Half Page | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    Half Page

    Question Text

    char *p = malloc(2 * 1024);

    What is a potential problem when allocating half a page?

    Question Answers

    • It will fragment the virtual memory because users should always request at least one page

    • Asking for less than a page might place the memory on two different pages

    • Writing to the other half may be allowed
    • Allocations smaller than one page should use the stack

    Feedback

    The OS allocates memory in chunks of 4 KB (the page size). If the memory we allocate happens to be placed at the beginning of a page, we have permission to update the second half of this page despite not requesting it. This might be a problem because buffer overflows can pass unnoticed.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/malloc-brk/index.html b/Lab/Data/quiz/malloc-brk/index.html index 1e35e375c9..ffbd38ed82 100644 --- a/Lab/Data/quiz/malloc-brk/index.html +++ b/Lab/Data/quiz/malloc-brk/index.html @@ -4,14 +4,14 @@ Malloc `brk()` | Operating Systems - +
    Skip to main content

    Malloc brk()

    Question Text

    When does malloc() use brk()?

    Question Answers

    • brk() is outdated, malloc() always uses mmap()
    • When it allocates a small chunk of memory
    • When it allocates an array

    • When it's working with dynamic libraries

    Feedback

    malloc() uses both brk() and mmap(), but preffers brk() for small chunks of memory to keep granular allocations in a contiguous area. This way, free() does not necessarily return the memory to the OS as it might only mark the zone as "free" within libc's allocator and reuse it for later allocations.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/malloc-mmap/index.html b/Lab/Data/quiz/malloc-mmap/index.html index 8b58ac3a20..f79d416237 100644 --- a/Lab/Data/quiz/malloc-mmap/index.html +++ b/Lab/Data/quiz/malloc-mmap/index.html @@ -4,7 +4,7 @@ Malloc `mmap()` | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    Malloc mmap()

    Question Text

    When does malloc() use mmap()?

    Question Answers

    • When it allocates read-only memory

    • When it allocates zeroed memory

    • When it allocates chunks of memory bigger than an internal threshold
    • When the heap is full

    Feedback

    malloc uses both brk() and mmap(), but prefers mmap() for big chunks of memory (by default larger than 128 KB). This value can be altered using mallopt() with the param argument set to M_MMAP_THRESHOLD. These memroy blocks are unlikely to be reused so they are not placed on heap to avoid memory fragmentation.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/memory-access/index.html b/Lab/Data/quiz/memory-access/index.html index d2c51a6edd..7df56cbfda 100644 --- a/Lab/Data/quiz/memory-access/index.html +++ b/Lab/Data/quiz/memory-access/index.html @@ -4,7 +4,7 @@ Modify String | Operating Systems - + @@ -13,7 +13,7 @@ One stores a constant pointer, cp, whereas the other stores the actual string. The compiler thinks that cp is able to modify the memory location that it points therefore it passes compilation. But at runtime a segmentation fault is issued because we are accessing data that is stored in read-only memory.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/memory-aslr/index.html b/Lab/Data/quiz/memory-aslr/index.html index ecd5d3f362..c0510f1ab5 100644 --- a/Lab/Data/quiz/memory-aslr/index.html +++ b/Lab/Data/quiz/memory-aslr/index.html @@ -4,13 +4,13 @@ ASLR | Operating Systems - +
    Skip to main content

    ASLR

    Question Text

    If we enable ASLR and run the bo_write_practice executable with the previously payload what vulnerabilities will we be able to still exploit?

    Question Answers

    • we can still jump to the secret_func

    • we can both still jump to the secret_func and overwrite the local variable

    • we can jump to a library function

    • we can still overwrite the local variable
    - + \ No newline at end of file diff --git a/Lab/Data/quiz/memory-granularity/index.html b/Lab/Data/quiz/memory-granularity/index.html index 8e0b21767d..cfb2d940f3 100644 --- a/Lab/Data/quiz/memory-granularity/index.html +++ b/Lab/Data/quiz/memory-granularity/index.html @@ -4,14 +4,14 @@ Memory Granularity | Operating Systems - +
    Skip to main content

    Memory Granularity

    Question Text

    What is the granularity of the size of memory sections?

    Question Answers

    • 4 bytes

    • 4 MB

    • 4 KB
    • 1 KB

    Feedback

    All sizes of memory areas are multiple of 4 KB (the page size). Also, all addresses start at multiple of 4 KB.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/memory-leaks/index.html b/Lab/Data/quiz/memory-leaks/index.html index f2c5921b94..b0ee52a6fc 100644 --- a/Lab/Data/quiz/memory-leaks/index.html +++ b/Lab/Data/quiz/memory-leaks/index.html @@ -4,14 +4,14 @@ Memory Leaks | Operating Systems - +
    Skip to main content

    Memory Leaks

    Question Text

    What happens to the leaked memory when the process finishes execution?

    Question Answers

    • It will be freed by the OS garbage collector

    • It remains unusable until the first restart

    • It is freed alongside all memory used by process
    • It will remain reachable untill another process explicitely frees it

    Feedback

    When a process ends, all its memory zones are freed by the OS to be reused. Leaking memory becomes a major problem in case of programs that run indefinitely, because the leaked memory will stack, causing a memory outage.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/memory-regions-vars/index.html b/Lab/Data/quiz/memory-regions-vars/index.html index cc9888714c..46c1e9806a 100644 --- a/Lab/Data/quiz/memory-regions-vars/index.html +++ b/Lab/Data/quiz/memory-regions-vars/index.html @@ -4,7 +4,7 @@ Variables in memory regions | Operating Systems - + @@ -14,7 +14,7 @@ Non-static local variables go on the.stack (c, k). malloc()'ed memory goes on the.heap. For k, the pointer is stored on the.stack, but the allocated memory, to which k points is stored on the.heap.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/memory-stack-protector/index.html b/Lab/Data/quiz/memory-stack-protector/index.html index 226c608f3e..b735ea3129 100644 --- a/Lab/Data/quiz/memory-stack-protector/index.html +++ b/Lab/Data/quiz/memory-stack-protector/index.html @@ -4,7 +4,7 @@ Stack Protector | Operating Systems - + @@ -13,7 +13,7 @@ Why is that?

    Question Answers

    Feedback

    When using the canary, to minimize the damage a buffer overflow could cause, the buffers are always placed right below the canary. By doing so, a buffer overflow will not overwrite anything. However, it is still possible to overwrite other local buffers, provided that a function declares more than 1 array or if we use the pointer directly.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/mmap-file/index.html b/Lab/Data/quiz/mmap-file/index.html index 9f53fc7f9b..895b078d0f 100644 --- a/Lab/Data/quiz/mmap-file/index.html +++ b/Lab/Data/quiz/mmap-file/index.html @@ -4,14 +4,14 @@ `mmap()` file | Operating Systems - +
    Skip to main content

    mmap() file

    Question Text

    What is one advantage of mapping a file in memory?

    Question Answers

    • It reduces interaction with the disk
    • Consumes less memory

    • It is faster because it does not uses the file API

    • Allows all threads to use the same memory area

    Feedback

    After mapping a file in memory, all changes will be visible only in memory. When removing the mapping or explicitely calling msync() the information from memory will be visible on disk.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/operators/index.html b/Lab/Data/quiz/operators/index.html index 6fb9af9fe2..b43bb2f5bb 100644 --- a/Lab/Data/quiz/operators/index.html +++ b/Lab/Data/quiz/operators/index.html @@ -4,13 +4,13 @@ Operator Overloading | Operating Systems - +
    Skip to main content

    Operator Overloading

    Question Text

    How many constructor calls, copy constructor calls, assignment operator calls and destructor calls does the following program issue?

    Obj quiz(Obj o1, Obj o2)
    {
    o2 = o1;
    return o2;
    }
    void main()
    {
    Obj b = quiz(o1, o2);
    }

    Question Answers

    • constructor calls = 0, copy constructor calls = 3, assignment operator calls = 1, destructor calls = 3
    • constructor calls = 1, copy constructor calls = 2, assignment operator calls = 1, destructor calls = 2

    • constructor calls = 0, copy constructor calls = 2, assignment operator calls = 1, destructor calls = 2

    • constructor calls = 0, copy constructor calls = 3, assignment operator calls = 1, destructor calls = 1

    Feedback

    • There are no constructor calls because there is no object construction when using int.

    • There are 3 copy constructor calls: for passing o1, for passing o2, and for returning o2.

    • There is 1 assignment operator call for o2 = o1.

    • There are 3 destructor calls, because each constructed object needs to be destroyed.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/page-allocation/index.html b/Lab/Data/quiz/page-allocation/index.html index 92733ffbad..671d74a969 100644 --- a/Lab/Data/quiz/page-allocation/index.html +++ b/Lab/Data/quiz/page-allocation/index.html @@ -4,14 +4,14 @@ Page Allocation | Operating Systems - +
    Skip to main content

    Page Allocation

    Question Text

    student@os:~/.../lab/support/static-dynamic$ size hello-static
    text data bss dec hex filename
    893333 20996 7128 921457 e0f71 hello-static

    How many bytes should we add to the .data section to make its size 28 KB, instead of 24 KB?

    Question Answers

    • 1 KB

    • 4 KB

    • 3580 bytes

    • 3581 bytes

    Feedback

    The total size must be 1 byte over the 24 KB threshold to cause a new page allocation. So in order to get that past the current size of 20996, we need 3581 bytes:

    student@os:~$ echo "24 * 1024 + 1 - 20996" | bc
    3581
    - + \ No newline at end of file diff --git a/Lab/Data/quiz/stack-layout/index.html b/Lab/Data/quiz/stack-layout/index.html index 7420b41852..f457836833 100644 --- a/Lab/Data/quiz/stack-layout/index.html +++ b/Lab/Data/quiz/stack-layout/index.html @@ -4,13 +4,13 @@ Stack layout | Operating Systems - +
    Skip to main content

    Stack layout

    Question Text

    What is the stack layout for the fun function in the bo_write.c program (starting from a high address)?

    Question Answers

    • return address, old rbp, maybe some padding, variable a, b[0], b[1], b[2]
    • return address, old rbp, maybe some padding, variable a, b[2], b[1], b[0]
    • return address, maybe some padding, variable a, b[0], b[1], b[2]

    • return address, old rbp, maybe some padding, b[0], b[1], b[2], variable a

    Feedback

    Look at the assembly code and notice the exact layout.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/string-buff-over/index.html b/Lab/Data/quiz/string-buff-over/index.html index f269ddc5b0..51c7b2db8d 100644 --- a/Lab/Data/quiz/string-buff-over/index.html +++ b/Lab/Data/quiz/string-buff-over/index.html @@ -4,14 +4,14 @@ String Buffer Overflow | Operating Systems - +
    Skip to main content

    String Buffer Overflow

    Question Text

    Why does the buffer overflow occur?

    Question Answers

    • the initial string, declared in main(), does not contain a terminating null byte.

    • the buffer is not large enough to store the copied bytes.

    • memcpy() skips the copying of terminating null bytes.

    • memcpy() copies 4 bytes, whereas the size of the string, including the terminating null byte, is 5.

    Feedback

    The string "soso" has length equal to 4, however, 5 bytes are actually used to store it, including the terminating null byte. Even though the buffer declared in fun() is not large enough to store the 5 bytes, the underlying issue is that we copying just 4 bytes, thus skipping the null byte.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/string-strcpy/index.html b/Lab/Data/quiz/string-strcpy/index.html index 614d28a9e0..1a98340a00 100644 --- a/Lab/Data/quiz/string-strcpy/index.html +++ b/Lab/Data/quiz/string-strcpy/index.html @@ -4,13 +4,13 @@ Strcpy Buffer Overflow | Operating Systems - +
    Skip to main content

    Strcpy Buffer Overflow

    Question Text

    Does any buffer overflow occur with the latest version of the program?

    Question Answers

    • no, because strcpy() was designed to correctly handle such situations.

    • no, because the string is correctly printed, i.e. no extra characters.

    • we cannot know

    • yes, strcpy() copies the entirety of the source, including the \0; since the size of dst is 4 the null byte overwrites the least significant byte of var

    Feedback

    Print the contents of variable var.

    - + \ No newline at end of file diff --git a/Lab/Data/quiz/valgrind-leaks/index.html b/Lab/Data/quiz/valgrind-leaks/index.html index 2079bd047c..2987dc1684 100644 --- a/Lab/Data/quiz/valgrind-leaks/index.html +++ b/Lab/Data/quiz/valgrind-leaks/index.html @@ -4,7 +4,7 @@ Valgrind Leaks | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    Valgrind Leaks

    Question Text

    struct student {
    char *name;
    int age;
    }

    struct student *s = malloc(sizeof(*s));
    s->name = strdup("Reginald");
    // ...
    free(s);

    What are the leaks in the above c program?

    Question Answers

    • There are no leaks

    • s->name is definitely lost

    • s->name is indirectly lost
    • s->name is still reachable

    Feedback

    strdup() allocates memory for a string so the returned pointer must be freed. Freeing s will leave us unable to free s->name, so s->name is indirectly lost. Find more about valgrind leak categories here.

    - + \ No newline at end of file diff --git a/Lab/Data/working-memory/index.html b/Lab/Data/working-memory/index.html index d78455d7f1..49e967a45f 100644 --- a/Lab/Data/working-memory/index.html +++ b/Lab/Data/working-memory/index.html @@ -4,7 +4,7 @@ Working with Memory | Operating Systems - + @@ -75,7 +75,7 @@ Note: Although using printf() calls is a viable option, we strongly suggest you use GDB.
  • Fix the program.
  • Analyze the corresponding Python and D implementation.
  • What is the expected result in each case? Why? Run the programs and see what happens.

    - + \ No newline at end of file diff --git a/Lab/IO/arena/index.html b/Lab/IO/arena/index.html index 97c3383d94..e90a8ed8df 100644 --- a/Lab/IO/arena/index.html +++ b/Lab/IO/arena/index.html @@ -4,7 +4,7 @@ Arena | Operating Systems - + @@ -29,7 +29,7 @@ Look at the buff/cache column. One possible output is shown below. It says the OS is caching 7 GB of data.

    student@os:~$ free -h
    total used free shared buff/cache available
    Mem: 15Gi 8,1Gi 503Mi 691Mi 7,0Gi 6,5Gi
    Swap: 7,6Gi 234Mi 7,4Gi
    - + \ No newline at end of file diff --git a/Lab/IO/async-io/index.html b/Lab/IO/async-io/index.html index 74be3b3f8d..f5d42841e4 100644 --- a/Lab/IO/async-io/index.html +++ b/Lab/IO/async-io/index.html @@ -4,7 +4,7 @@ Asynchronous I/O | Operating Systems - + @@ -35,7 +35,7 @@ not avoiding doing a lot of processing, as is the case with the fibonacci() function. In that particular case, having thread-based asynchronous I/O and the GIL will be a good option, as you rely on the thread scheduler to be able to serve multiple I/O channels simultaneously. This later approach is called I/O multiplexing, discussed in the next section.

    - + \ No newline at end of file diff --git a/Lab/IO/beyond-network-sockets/index.html b/Lab/IO/beyond-network-sockets/index.html index d98b427832..4f047f6147 100644 --- a/Lab/IO/beyond-network-sockets/index.html +++ b/Lab/IO/beyond-network-sockets/index.html @@ -4,7 +4,7 @@ Beyond Network Sockets | Operating Systems - + @@ -31,7 +31,7 @@ Use the example at the bottom of the UNIX socket man page if you get stuck at bind(). When you're done, compile the code and then run send_unix_socket. If you did this task correctly, receive_unix_socket should display the flag.

    - + \ No newline at end of file diff --git a/Lab/IO/client-server-model/index.html b/Lab/IO/client-server-model/index.html index f75beae27a..3955457802 100644 --- a/Lab/IO/client-server-model/index.html +++ b/Lab/IO/client-server-model/index.html @@ -4,7 +4,7 @@ Client-Server Model | Operating Systems - + @@ -40,7 +40,7 @@ If it can't, then that process is not Deluge. Otherwise, it is Deluge and that connection is immediately closed :)) This may sound like a stupid way of checking whether a process is Deluge or not, but if it's stupid and it works, then it's not stupid!

    - + \ No newline at end of file diff --git a/Lab/IO/file-descriptors/index.html b/Lab/IO/file-descriptors/index.html index 1bdaf900de..07a3c31264 100644 --- a/Lab/IO/file-descriptors/index.html +++ b/Lab/IO/file-descriptors/index.html @@ -4,7 +4,7 @@ File Descriptors | Operating Systems - + @@ -74,7 +74,7 @@ As usual, use the man pages when in doubt about either of them.

    libcsyscall
    fopen()open()
    fread()read()
    fwrite()write()
    fseek()lseek()
    fclose()close()

    So for most equivalents, just remove the leading f when moving from the libc function to the underlying syscall.

    For a quick recap of the flags we've discussed so far, take a look at the following table. But don't bother memorising it. You can find it any time in by typing man fopen in your terminal.

    fopen() modeopen() flag
    "r"O_RDONLY
    "w"O_WRONLY │ O_CREAT │ O_TRUNC
    "a"O_WRONLY │ O_CREAT │ O_APPEND
    "r+"O_RDWR
    "w+"O_RDWR │ O_CREAT │ O_TRUNC
    "a+"O_RDWR │ O_CREAT │ O_APPEND
    - + \ No newline at end of file diff --git a/Lab/IO/file-handlers/index.html b/Lab/IO/file-handlers/index.html index 9e77bc3b77..d9f9fc4877 100644 --- a/Lab/IO/file-handlers/index.html +++ b/Lab/IO/file-handlers/index.html @@ -4,7 +4,7 @@ File Handling | Operating Systems - + @@ -34,7 +34,7 @@ Most of the time, opendir() is used instead. But what does it return? Find out in the "File Descriptors" section.

    - + \ No newline at end of file diff --git a/Lab/IO/file-mappings/index.html b/Lab/IO/file-mappings/index.html index 93d056b789..2b54e3c554 100644 --- a/Lab/IO/file-mappings/index.html +++ b/Lab/IO/file-mappings/index.html @@ -4,7 +4,7 @@ File Mappings | Operating Systems - + @@ -39,7 +39,7 @@ So file mappings are especially useful for randomly accessing file data. Accessing the i-th byte in a file becomes the same as mapping[i], which is obviously more efficient than calling lseek(). File mappings are also useful when we have to overwrite existing data multiple times or when we read certain chunks multiple times.

    - + \ No newline at end of file diff --git a/Lab/IO/index.html b/Lab/IO/index.html index c682898265..166b50ab72 100644 --- a/Lab/IO/index.html +++ b/Lab/IO/index.html @@ -4,13 +4,13 @@ IO | Operating Systems - +
    Skip to main content

    IO

    - + \ No newline at end of file diff --git a/Lab/IO/io-internals/index.html b/Lab/IO/io-internals/index.html index 42adb22d05..6138a3c732 100644 --- a/Lab/IO/io-internals/index.html +++ b/Lab/IO/io-internals/index.html @@ -4,7 +4,7 @@ I/O Internals | Operating Systems - + @@ -58,7 +58,7 @@ This concept is known as double buffering. In the following section, we will see how to make use of this internal buffering to optimise network requests.

    Notice that the script in support/buffering/benchmark_buffering.sh also uses echo 3 > /proc/sys/vm/drop_caches. That section in the Arena that we mentioned earlier is becoming even more interesting.

    - + \ No newline at end of file diff --git a/Lab/IO/io-multiplexing/index.html b/Lab/IO/io-multiplexing/index.html index 36062deb08..c79fcdd719 100644 --- a/Lab/IO/io-multiplexing/index.html +++ b/Lab/IO/io-multiplexing/index.html @@ -4,7 +4,7 @@ I/O Multiplexing | Operating Systems - + @@ -23,7 +23,7 @@ The server is now multiplexing both connections.

  • Create a script and / or a program to exercise the server. Create many connections to the server and continuously send messages to the server. See it multiplex the I/O channels (one for each connection - actually two: one for receiving and one for sending).

  • - + \ No newline at end of file diff --git a/Lab/IO/local-io-in-action/index.html b/Lab/IO/local-io-in-action/index.html index 327d80cdcb..97034b5880 100644 --- a/Lab/IO/local-io-in-action/index.html +++ b/Lab/IO/local-io-in-action/index.html @@ -4,7 +4,7 @@ Local I/O in Action | Operating Systems - + @@ -32,7 +32,7 @@ For this, it calls lt.bdecode().

    As before, error handling is important:

    try:
    with open(_filepath, 'rb') as _file:
    resume_data = lt.bdecode(_file.read())
    except (OSError, EOFError, RuntimeError) as ex:
    if self.torrents:
    log.warning('Unable to load %s: %s', _filepath, ex)
    resume_data = None

    So now we know how Deluge handles local files. But we still don't know how it gets those files from peers. We'll find out how in the following sections.

    - + \ No newline at end of file diff --git a/Lab/IO/networking-101/index.html b/Lab/IO/networking-101/index.html index 8844fb8bab..a9e8e4e852 100644 --- a/Lab/IO/networking-101/index.html +++ b/Lab/IO/networking-101/index.html @@ -4,7 +4,7 @@ Networking 101 | Operating Systems - + @@ -46,7 +46,7 @@ What arguments do you need to pass to netstat to see receiver.py? Do you need the whole -tuapn? No.

    Conclusion

    The difference between TCP and UDP can be summarised as follows:

    TCP vs UDP

    - + \ No newline at end of file diff --git a/Lab/IO/overview/index.html b/Lab/IO/overview/index.html index 642e5b1dcb..6d638f975a 100644 --- a/Lab/IO/overview/index.html +++ b/Lab/IO/overview/index.html @@ -4,7 +4,7 @@ I/O | Operating Systems - + @@ -16,7 +16,7 @@ It will always run the same code on the same data and, thus, produce the same result. This may be useful in some narrow cases, such as calculating the decimals of Pi. However, for more real-world-facing applications such as web servers, operating systems and databases inputs and outputs are mandatory.

    The most simplistic representation of a compute system is a black box that receives some input and delivers some output.

    Compute System - Oversimplified

    In this session, we will look into how a compute system interacts with the outside world to get and produce these inputs and outputs.

    1. File Handlers
    2. File Descriptors
    3. Redirections
    4. Pipes
    5. Local I/O in Action
    6. Remote I/O
    7. Networking 101
    8. Client-Server Model
    9. Beyond Network Sockets
    10. File Mappings
    11. IO Internals
    12. Zero-copy
    13. Asynchronous I/O
    14. I/O Multiplexing
    15. Arena
    - + \ No newline at end of file diff --git a/Lab/IO/pipes/index.html b/Lab/IO/pipes/index.html index c125bbc30d..4549037a24 100644 --- a/Lab/IO/pipes/index.html +++ b/Lab/IO/pipes/index.html @@ -4,7 +4,7 @@ Pipes | Operating Systems - + @@ -64,7 +64,7 @@ This buffer holds the data that is passed between processes, not the filesystem. So we still don't break our 2 desires from the beginning of this section: to allow data transfer and to do so efficiently.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/anonymous-pipes-limitation/index.html b/Lab/IO/quiz/anonymous-pipes-limitation/index.html index 1bae68a455..b1c72ff333 100644 --- a/Lab/IO/quiz/anonymous-pipes-limitation/index.html +++ b/Lab/IO/quiz/anonymous-pipes-limitation/index.html @@ -4,7 +4,7 @@ Limitation of Anonymous Pipes | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    Limitation of Anonymous Pipes

    Question Text

    What of the following is the largest drawback of using anonymous pipes (created with pipe()) for inter-process communication?

    Question Answers

    • they only allow unidirectional communication
    • they only allow IPC between "related" processes (parent - child - grandchild etc.)
    • if more processes use the same end of the same pipe, there may be race conditions

    • a pipe only has 2 file descriptors, but some processes may need more channels to communicate

    Feedback

    Out of the answers above, the only limitation that cannot be overcome by using pipes alone is the requirement for the processes using them to be related. The parent must create the pipes so the children can inherit them. All other downsides can be overcome by using more pipes.

    The answer to this is to employ some filesystem support.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/bind-error-cause/index.html b/Lab/IO/quiz/bind-error-cause/index.html index dfcbbaee63..e2cc39d11f 100644 --- a/Lab/IO/quiz/bind-error-cause/index.html +++ b/Lab/IO/quiz/bind-error-cause/index.html @@ -4,7 +4,7 @@ Cause of `bind()` Error | Operating Systems - + @@ -13,7 +13,7 @@ You will get an error. What is its cause?

    Question Answers

    Feedback

    One port may only be bound to one socket at a time. The fact that it's the same program (same source code) using it is irrelevant because they're different processes.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/client-server-sender-receiver/index.html b/Lab/IO/quiz/client-server-sender-receiver/index.html index eaa356d1ce..0e16f4346f 100644 --- a/Lab/IO/quiz/client-server-sender-receiver/index.html +++ b/Lab/IO/quiz/client-server-sender-receiver/index.html @@ -4,7 +4,7 @@ `sender.py` and `receiver.py` Client-Server Parallel | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    sender.py and receiver.py Client-Server Parallel

    Question Text

    Drawing a parallel from the UDP examples in support/send-receive/, which of the sender and receiver is similar to the server and which is similar to the client?

    Question Answers

    • both are similar to clients

    • both are similar to servers

    • receiver.py is similar to a server and sender.py is similar to a client
    • receiver.py is similar to a client and sender.py is similar to a server

    Feedback

    receiver.py is the passive component. It has to be started first and then waits for sender.py (the client) to send data. Furthermore, you can only have one receiver.py running at the same time (remember the multiple bind() bug) and multiple sender.pys.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/deluge-tcp-udp/index.html b/Lab/IO/quiz/deluge-tcp-udp/index.html index ffd5bc4b2a..b6124a4720 100644 --- a/Lab/IO/quiz/deluge-tcp-udp/index.html +++ b/Lab/IO/quiz/deluge-tcp-udp/index.html @@ -4,7 +4,7 @@ Deluge: TCP or UDP | Operating Systems - + @@ -14,7 +14,7 @@ The only situation when correctness may be overlooked is when some given data will be quckly replaced by some other data. But files are persistent. If you download a video game from as a torrent (we've all done that), you want to keep it for a while and first and foremost, it has to work properly, i.e. not be corrupt.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/execve/index.html b/Lab/IO/quiz/execve/index.html index 673d57c76d..f84ffd58c5 100644 --- a/Lab/IO/quiz/execve/index.html +++ b/Lab/IO/quiz/execve/index.html @@ -4,7 +4,7 @@ Effect of `execve()` Syscall | Operating Systems - + @@ -13,7 +13,7 @@ causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.

    Simply put, we can say that execve() replaces the VAS of the current process with that of the program given as argument.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/fewer-than-2-copies/index.html b/Lab/IO/quiz/fewer-than-2-copies/index.html index 1a4fe5e670..de3577b1ee 100644 --- a/Lab/IO/quiz/fewer-than-2-copies/index.html +++ b/Lab/IO/quiz/fewer-than-2-copies/index.html @@ -4,7 +4,7 @@ Fewer than Two Copies | Operating Systems - + @@ -16,7 +16,7 @@ They are both connected to the CPU via the motherboard, so it's the CPU's job to do the transfer. For this, it needs a "temporary buffer". Then the NIC needs its own buffer because the speed of the network may be slower than the speed at which it receives data from the kernel, so it needs some memory where to place the "surplus" while waiting for the network to "clear".

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/file-handler-c/index.html b/Lab/IO/quiz/file-handler-c/index.html index 4cfab3f7dc..f9ea0653b8 100644 --- a/Lab/IO/quiz/file-handler-c/index.html +++ b/Lab/IO/quiz/file-handler-c/index.html @@ -4,14 +4,14 @@ File handler in C | Operating Systems - +
    Skip to main content

    File handler in C

    Question Text

    What is the type of the file handler in the C code located in support/simple-file-operations/file_operations.c?

    Question Answers

    • File
    • FILE *
    • FILE

    • void *

    • struct file

    Feedaback

    The file is opened using either of the following lines:

    f = fopen(file_name, "r");

    f = fopen(file_name, "w");

    The type of f is FILE *: FILE *f.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/firefox-tcp-udp/index.html b/Lab/IO/quiz/firefox-tcp-udp/index.html index 2b44a3eb41..9ef09de2f4 100644 --- a/Lab/IO/quiz/firefox-tcp-udp/index.html +++ b/Lab/IO/quiz/firefox-tcp-udp/index.html @@ -4,7 +4,7 @@ Firefox: TCP or UDP? | Operating Systems - + @@ -16,7 +16,7 @@ We don't update text-based content too often and since it needs to be precise, handling broken packets is important. On the other hand, a streaming-based site, such as YouTube sends data in real time and thus a few errors here and there can be omitted. So https://open-education-hub.github.io/operating-systems is going to be served via TCP, while YouTube videos via UDP.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/flush-libc-buffer/index.html b/Lab/IO/quiz/flush-libc-buffer/index.html index a3ba78bde8..4116fae695 100644 --- a/Lab/IO/quiz/flush-libc-buffer/index.html +++ b/Lab/IO/quiz/flush-libc-buffer/index.html @@ -4,14 +4,14 @@ Flush Libc Buffer | Operating Systems - +
    Skip to main content

    Flush Libc Buffer

    Question Text

    Which of the following is a method of flushing libc's internal buffer?

    Question Answers

    • print a \0 character
    • print a \n character
    • print a space character

    • print a \t character

    Feedback

    Newlines (\n) force printf() to dump the internal buffer associated with the stdout FILE struct. If you place a \n character within one of the strings in support/buffering/printf_buffering.c, a write() syscall will be made right after it.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/fopen-syscall/index.html b/Lab/IO/quiz/fopen-syscall/index.html index 49c5461b0a..2213996050 100644 --- a/Lab/IO/quiz/fopen-syscall/index.html +++ b/Lab/IO/quiz/fopen-syscall/index.html @@ -4,14 +4,14 @@ Syscall Used by `fopen()` | Operating Systems - +
    Skip to main content

    Syscall Used by fopen()

    Question Text

    Use strace to determine the syscall called by fopen() to access the file. Which one is it?

    Question Answers

    • read()
    • openat()
    • write()

    • fstat()

    Feedaback

    student@os:~/.../lab/support/simple-file-handling$ strace ./file_operations
    [...]
    openat(AT_FDCWD, "file.txt", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0664, st_size=11, ...}) = 0
    read(3, "C was here!", 4096) = 11
    [...]

    So fopen()'s (main) underlying syscall is openat().

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/fopen-w/index.html b/Lab/IO/quiz/fopen-w/index.html index 6d29c175e1..653bcc4d63 100644 --- a/Lab/IO/quiz/fopen-w/index.html +++ b/Lab/IO/quiz/fopen-w/index.html @@ -4,14 +4,14 @@ open()` equivalent of `fopen(..., "w") | Operating Systems - +
    Skip to main content

    open() equivalent of fopen(..., "w")

    Question Text

    Use strace on the code in support/simple-file-operations/file_operations.c to find the flags used by openat() when calling fopen(file_name, "w"). First, try to make an educated guess and only then verify your answer by running strace.

    Question Answers

    • O_WRONLY | O_CREAT | O_TRUNC
    • O_WRONLY | O_CREAT

    • O_WRONLY

    • O_WRONLY | O_TRUNC

    Feedback

    student@os:~/.../lab/support/simple-file-operations$ strace ./file_operations
    [...]
    openat(AT_FDCWD, "file.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
    [...]
    - + \ No newline at end of file diff --git a/Lab/IO/quiz/local-io-errors/index.html b/Lab/IO/quiz/local-io-errors/index.html index 07119f5d86..3d4a351538 100644 --- a/Lab/IO/quiz/local-io-errors/index.html +++ b/Lab/IO/quiz/local-io-errors/index.html @@ -4,14 +4,14 @@ I/O Errors | Operating Systems - +
    Skip to main content

    I/O Errors

    Question Text

    Which of the following types of errors are unlikely to occur during an I/O operation?

    Question Answers

    • The current user does not have sufficient permisions to access a given file

    • There is not enough space left on the disk

    • The file offset has reached the end of the file when reading
    • Some data blocks in the filesystem are corrupted

    Feedback

    We can always reposition the file offset within a given file with either a fseek() library call or an lseek() syscall, so this is not an error. The others are more difficult to manage, so can be regarded as errors.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/mmap-read-write-benchmark/index.html b/Lab/IO/quiz/mmap-read-write-benchmark/index.html index 477a784549..0cd42239f2 100644 --- a/Lab/IO/quiz/mmap-read-write-benchmark/index.html +++ b/Lab/IO/quiz/mmap-read-write-benchmark/index.html @@ -4,7 +4,7 @@ `mmap()` vs `read()` and `write()` Benchmark | Operating Systems - + @@ -13,7 +13,7 @@ However, you might get different results on your system. This depends on your storage device (SSD vs HDD) and its specific speed (like its RPM for an HDD). So the more conservative answer is to say that this depends on external aspects and that, in general, the 2 implementations are more or less equivalent.

    If you want to know why there isn't much of a difference between the 2 implementations, check out this explanation.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/o-trunc/index.html b/Lab/IO/quiz/o-trunc/index.html index 4b41542435..6886b7fb42 100644 --- a/Lab/IO/quiz/o-trunc/index.html +++ b/Lab/IO/quiz/o-trunc/index.html @@ -4,13 +4,13 @@ `O_TRUNC` Flag Behaviour | Operating Systems - +
    Skip to main content

    O_TRUNC Flag Behaviour

    Question Text

    How does the O_TRUNC flag change the behaviour of open()?

    Question Answers

    • the previous content of the file is deleted
    • new data will be appended to the file

    • newly written data will be ignored

    Feedback

    The man page provides us with unlimited wisdon:

    If the file already exists and is a regular file and the access mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0.

    Setting the length of the file to 0 is equivalent to deleting the previous content of the file.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/pipe-ends/index.html b/Lab/IO/quiz/pipe-ends/index.html index 48fcc18df1..b76969cb4e 100644 --- a/Lab/IO/quiz/pipe-ends/index.html +++ b/Lab/IO/quiz/pipe-ends/index.html @@ -4,7 +4,7 @@ Pipe Ends | Operating Systems - + @@ -16,7 +16,7 @@ Note each of these numbers is followed by a letter. As you might have guessed:

    Also, the man page is quite clear on this issue:

    pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/prints-work-no-stdio/index.html b/Lab/IO/quiz/prints-work-no-stdio/index.html index e2d740dd7f..2186641c9f 100644 --- a/Lab/IO/quiz/prints-work-no-stdio/index.html +++ b/Lab/IO/quiz/prints-work-no-stdio/index.html @@ -4,14 +4,14 @@ Prints Working after Closing `stdio` | Operating Systems - +
    Skip to main content

    Prints Working after Closing stdio

    Question Text

    Why does support/redirect/redirect.c, still print messages to the console after closing file descriptor 1 (stdout)?

    Question Answers

    • because wait_for_input() calls fprintf(stderr, ...), which prints to stderr (file descriptor 2)
    • because the default file descriptors cannot be "truly" closed

    • because the other two default file descriptors are still linked to the console

    • because the wait_for_input() function started printed before closing the stdout file descriptor

    Feedback

    If you look at wait_for_input() closely, you'll notice it calls fprintf(stderr, ...). stderr is liked to file descriptor 2, which is left unchanged so we can still write data to it.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/receiver-socket-fd/index.html b/Lab/IO/quiz/receiver-socket-fd/index.html index aa9df4c733..04944bf4c4 100644 --- a/Lab/IO/quiz/receiver-socket-fd/index.html +++ b/Lab/IO/quiz/receiver-socket-fd/index.html @@ -4,13 +4,13 @@ Receiver Socked File Descriptor | Operating Systems - +
    Skip to main content

    Receiver Socked File Descriptor

    Question Text

    What is the type of the file descriptor that corresponds to the socket created by support/send-receive/receiver.py?

    Question Answers

    • only file descriptors that are linked to files have types

    • DIR

    • REG

    • CHR

    • IPv4

    Feedback

    Running lsof yields the following output:

    student@os:~$ lsof -p 59681
    COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
    python3 59681 student cwd DIR 8,1 0 559322 /home/student/operating-systems-oer/content/chapters/io/lab/support/send-receive
    python3 59681 student rtd DIR 259,6 4096 2 /
    python3 59681 student txt REG 259,6 5502744 1835857 /usr/bin/python3.8
    python3 59681 student mem REG 259,6 8631488 1835827 /usr/lib/locale/locale-archive
    python3 59681 student mem REG 259,6 108936 1835887 /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
    python3 59681 student mem REG 259,6 182560 1836149 /usr/lib/x86_64-linux-gnu/libexpat.so.1.6.11
    python3 59681 student mem REG 259,6 1369384 1857443 /usr/lib/x86_64-linux-gnu/libm-2.31.so
    python3 59681 student mem REG 259,6 14880 1857476 /usr/lib/x86_64-linux-gnu/libutil-2.31.so
    python3 59681 student mem REG 259,6 18848 1857439 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
    python3 59681 student mem REG 259,6 157224 1857471 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
    python3 59681 student mem REG 259,6 2029592 1857435 /usr/lib/x86_64-linux-gnu/libc-2.31.so
    python3 59681 student mem REG 259,6 27002 2506848 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
    python3 59681 student mem REG 259,6 191504 1835092 /usr/lib/x86_64-linux-gnu/ld-2.31.so
    python3 59681 student 0u CHR 136,1 0t0 4 /dev/pts/1
    python3 59681 student 1u CHR 136,1 0t0 4 /dev/pts/1
    python3 59681 student 2u CHR 136,1 0t0 4 /dev/pts/1
    python3 59681 student 3u IPv4 588386 0t0 UDP localhost:5000

    The last line displays the socket:

    python3 59681  student    3u  IPv4 588386      0t0     UDP localhost:5000

    Its type is written on the the 5th column: IPv4 because it's a network socket.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/server-copies/index.html b/Lab/IO/quiz/server-copies/index.html index 62505dc618..77bc699301 100644 --- a/Lab/IO/quiz/server-copies/index.html +++ b/Lab/IO/quiz/server-copies/index.html @@ -4,7 +4,7 @@ Client-Server Number of Copies | Operating Systems - + @@ -16,7 +16,7 @@ Following this step, the app will call send(), which will first copy the file to a buffer in the kernel. From this buffer, the kernel itself will copy the file to another buffer on the NIC (Network Interface Card). In total, there the file is copied 4 times, as outlined in the image below.

    Server Copies - Read-Send

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/stderr-fd/index.html b/Lab/IO/quiz/stderr-fd/index.html index 375cff291a..32bf7066f7 100644 --- a/Lab/IO/quiz/stderr-fd/index.html +++ b/Lab/IO/quiz/stderr-fd/index.html @@ -4,7 +4,7 @@ File Descriptor of `stderr` | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    File Descriptor of stderr

    Question Text

    Which file descriptor is associated by default to stderr?

    Question Answers

    • it varies from process to process

    • it varies from one Linux distribution to another

    • stderr has no associated file descriptor

    • 2
    • 0

    • 1

    Feedaback

    You would type ls 2> /dev/null to ignore ls's errors. This equates to redirecting stderr to /dev/null. The number 2 in 2> hints that stderr is by default associated with file descriptor 2.

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/strace-printf/index.html b/Lab/IO/quiz/strace-printf/index.html index cb8d181511..57acb7145d 100644 --- a/Lab/IO/quiz/strace-printf/index.html +++ b/Lab/IO/quiz/strace-printf/index.html @@ -4,13 +4,13 @@ `printf()` Under Strace | Operating Systems - +
    Skip to main content

    printf() Under Strace

    Question Text

    How many calls to write() does the code in support/buffering/printf_buffering.c do?

    Question Answers

    • none
    • 1
    • 6

    • 5

    Feedback

    Just run the binary under strace:

    student@os:/.../support/buffering$ strace -e write ./printf_buffering
    write(1, "Dovahkiin, Dovahkiin Naal ok zin"..., 169Dovahkiin, Dovahkiin Naal ok zin los vahriin Wah dein vokul mahfaeraak ahst vaal! Ahrk fin norok paal graan Fod nust hon zindro zaan Dovahkiin, fah hin kogaan mu draal! ) = 169
    +++ exited with 0 +++

    There's one call to write().

    - + \ No newline at end of file diff --git a/Lab/IO/quiz/syscalls-cp/index.html b/Lab/IO/quiz/syscalls-cp/index.html index c9a80bb0b0..b68bf93fa4 100644 --- a/Lab/IO/quiz/syscalls-cp/index.html +++ b/Lab/IO/quiz/syscalls-cp/index.html @@ -4,13 +4,13 @@ Syscalls Used by `cp` | Operating Systems - +
    Skip to main content

    Syscalls Used by cp

    Question Text

    What syscalls does cp use to copy files?

    Question Answers

    • mmap()
    • read() and write()
    • a combination of read() - write() and mmap()

    Feedback

    It suffices to use strace to see that cp uses read() and write().

    student@os:/.../support/file-mappings$ strace cp test-file.txt output.txt
    openat(AT_FDCWD, "test-file.txt", O_RDONLY) = 3
    fstat(3, {st_mode=S_IFREG|0664, st_size=1048576, ...}) = 0
    openat(AT_FDCWD, "output.txt", O_WRONLY|O_CREAT|O_EXCL, 0664) = 4
    fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
    [...]
    read(3, "@Y\344\0025\317\27\243\23\201:\27\342\356\240\345\331Nq\v/\36\244\200\301\247\3152\35WZ\337"..., 131072) = 131072
    write(4, "@Y\344\0025\317\27\243\23\201:\27\342\356\240\345\331Nq\v/\36\244\200\301\247\3152\35WZ\337"..., 131072) = 131072
    read(3, "\201\240J7x\275\257Z\343\334\307d<\321U\275\337\10\233j\222\313,##cQD\268e\324"..., 131072) = 131072
    write(4, "\201\240J7x\275\257Z\343\334\307d<\321U\275\337\10\233j\222\313,##cQD\268e\324"..., 131072) = 131072
    read(3, "\371\3244=\17\300L9\243\201\362\25\273\37\326\323\362\200\1T\310N\316\305\253\331\331Nt\346\3369"..., 131072) = 131072
    write(4, "\371\3244=\17\300L9\243\201\362\25\273\37\326\323\362\200\1T\310N\316\305\253\331\331Nt\346\3369"..., 131072) = 131072
    read(3, "\350\304\345f\16\305V\356\371\263?+\355{\16\235\344\310P4}\2043%\0052\345D\265\243t\354"..., 131072) = 131072
    write(4, "\350\304\345f\16\305V\356\371\263?+\355{\16\235\344\310P4}\2043%\0052\345D\265\243t\354"..., 131072) = 131072
    read(3, "\277\226\315\226\n\37\337;N*\211\352\254$\273\2\351\30a\254\ta\352R\25-\23\274\376zy\211"..., 131072) = 131072
    write(4, "\277\226\315\226\n\37\337;N*\211\352\254$\273\2\351\30a\254\ta\352R\25-\23\274\376zy\211"..., 131072) = 131072
    read(3, "}\245\356;\222\327\204\242u\26dy%\346\374\201ndT\226\233\3575\345\247\356\362\344\350\354\17\261"..., 131072) = 131072
    write(4, "}\245\356;\222\327\204\242u\26dy%\346\374\201ndT\226\233\3575\345\247\356\362\344\350\354\17\261"..., 131072) = 131072
    read(3, "\35\277\207\243~\355(i\351^\1\346\312V\232\204\32\230~\376\20\245\"\305\344d\304\304B\272\346\332"..., 131072) = 131072
    write(4, "\35\277\207\243~\355(i\351^\1\346\312V\232\204\32\230~\376\20\245\"\305\344d\304\304B\272\346\332"..., 131072) = 131072
    read(3, "\n)\334\275\331:R\236O\231\243\302\314\267\326\"\rY\262\21\374\305\275\3\332\23\345\16>\214\210\235"..., 131072) = 131072
    write(4, "\n)\334\275\331:R\236O\231\243\302\314\267\326\"\rY\262\21\374\305\275\3\332\23\345\16>\214\210\235"..., 131072) = 131072
    - + \ No newline at end of file diff --git a/Lab/IO/quiz/write-file-permissions/index.html b/Lab/IO/quiz/write-file-permissions/index.html index cc92ccad98..316222e3eb 100644 --- a/Lab/IO/quiz/write-file-permissions/index.html +++ b/Lab/IO/quiz/write-file-permissions/index.html @@ -4,7 +4,7 @@ `write_file.txt` Permissions | Operating Systems - + @@ -18,7 +18,7 @@ In fact, libc defines wrapper functions on top of all system calls and our code actually calls those wrappers, so our assumption is not far-fetched.

    To call open() correctly, the coulde would look something like this:

    open("write_file.txt", O_WRONLY | O_CREAT, 0644).

    0644 is the octal representation of rw-r--r--. The approximate Assembly code for this function call would look like this:

    mov rdi, path_to_file   ; first argument: path

    mov rsi, O_WRONLY
    or rsi, O_CREAT ; second argument: flags

    mov rdx, 0644 ; third argument: mode

    call open

    When we don't specifty a mode argument, the open() function simply takes this value from rdx as it was before the function call. This is an undefined behaviour because this register might have been modified either way by the program before calling open().

    - + \ No newline at end of file diff --git a/Lab/IO/redirections/index.html b/Lab/IO/redirections/index.html index eff605af9a..e28b6fe05c 100644 --- a/Lab/IO/redirections/index.html +++ b/Lab/IO/redirections/index.html @@ -4,7 +4,7 @@ Redirections | Operating Systems - + @@ -54,7 +54,7 @@ It is capable of fork()-ing itself and execvp()-ing commands, just like Bash. We can now extend it to allow redirecting stdout to a file.

    Use what you've learnt so far in this section to allow this mini-shell to redirect the output of its commands to files. Redirection is performed just like in bash via >.

    - + \ No newline at end of file diff --git a/Lab/IO/remote-io/index.html b/Lab/IO/remote-io/index.html index 98c6951696..70ceca17c0 100644 --- a/Lab/IO/remote-io/index.html +++ b/Lab/IO/remote-io/index.html @@ -4,7 +4,7 @@ Remote I/O | Operating Systems - + @@ -80,7 +80,7 @@ If everything is right, each sender should be able to communicate with each receiver.

  • Use the API you've just learned about to fill in the TODOs in support/receive-challenges/receive_net_dgram_socket.c.

    This is like receiver.py. For it to run properly, you should compile it using make, then run it and after that run send_net_dgram_socket. If you solved the challenge correctly, receive_net_dgram_socket should display the flag.

  • - + \ No newline at end of file diff --git a/Lab/IO/zero-copy/index.html b/Lab/IO/zero-copy/index.html index 8c6c42b2c9..a540bf62af 100644 --- a/Lab/IO/zero-copy/index.html +++ b/Lab/IO/zero-copy/index.html @@ -4,7 +4,7 @@ Zero-Copy | Operating Systems - + @@ -27,7 +27,7 @@ Yours might differ by quite a lot, as they depend on your disk, your NIC, your kernel, your Python version, the load on your system etc.

    student@os:/.../support/zero-copy$ python3 benchmark_client.py read-send
    Time taken: 7.175773588009179 seconds

    student@os:/.../support/zero-copy$ python3 benchmark_client.py sendfile
    Time taken: 3.71454380400246 seconds

    This is quite good! Using sendfile() halves the number of copies needed from 4 to 2. Thus, it makes sense for the running time to roughly halve as well.

    Quiz

    You can read a slightly more detailed article about zero-copy here.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/app-investigate/index.html b/Lab/Software Stack/app-investigate/index.html index 0cf6259118..51dfce81ab 100644 --- a/Lab/Software Stack/app-investigate/index.html +++ b/Lab/Software Stack/app-investigate/index.html @@ -4,7 +4,7 @@ App Investigation | Operating Systems - + @@ -15,7 +15,7 @@ Select a binary executable application and a scripted application from those listed above.

    1. Use ldd on the two applications. Notice the resulting messages and explain the results.

    2. Use ltrace and strace on the two applications. Follow the library calls and the system calls done by each application.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/arena/index.html b/Lab/Software Stack/arena/index.html index d3f61e6aa8..ba56f75379 100644 --- a/Lab/Software Stack/arena/index.html +++ b/Lab/Software Stack/arena/index.html @@ -4,7 +4,7 @@ Arena | Operating Systems - + @@ -49,7 +49,7 @@ The file command tells if the file passed as argument is a statically-linked executable. If you can't find one, install the busybox-static package.

  • Look into what busybox is and explain why it's custom to have it as statically-linked executable.

  • Run ldd, nm, strace, ltrace on a statically-linked application executable. Explain the results.

  • - + \ No newline at end of file diff --git a/Lab/Software Stack/basic-syscall/index.html b/Lab/Software Stack/basic-syscall/index.html index 625951f873..143ba54b46 100644 --- a/Lab/Software Stack/basic-syscall/index.html +++ b/Lab/Software Stack/basic-syscall/index.html @@ -4,7 +4,7 @@ Analyzing the Software Stack | Operating Systems - + @@ -27,7 +27,7 @@ For portability and maintainability, we require a higher level language, such as C. In order to use C, we need function wrappers around system calls.

    Practice

    Update the hello.asm and / or hello.s files to print both Hello, world! and Bye, world!. This means adding another write system call.

    Quiz

    - + \ No newline at end of file diff --git a/Lab/Software Stack/common-functions/index.html b/Lab/Software Stack/common-functions/index.html index 01ab2931ed..d598155e5a 100644 --- a/Lab/Software Stack/common-functions/index.html +++ b/Lab/Software Stack/common-functions/index.html @@ -4,7 +4,7 @@ Common Functions | Operating Systems - + @@ -27,7 +27,7 @@ The printf() function will no longer be called. This results in a single write system call.

    Using previously implemented functions allows us to more efficiently write new programs. These functions provide us with extensive features that we use in our programs.

    Quiz

    - + \ No newline at end of file diff --git a/Lab/Software Stack/high-level-lang/index.html b/Lab/Software Stack/high-level-lang/index.html index 7a0aa9d7ff..2e197a567e 100644 --- a/Lab/Software Stack/high-level-lang/index.html +++ b/Lab/Software Stack/high-level-lang/index.html @@ -4,7 +4,7 @@ High-Level Languages | Operating Systems - + @@ -23,7 +23,7 @@ Use ltrace and strace to compute the number of library calls and system calls. Use perf to measure the running time.

    Compare the values with those from the "Hello, World!"-printing programs in C and Python.

  • Create a "Hello, World!"-printing program in a programming language of your choice (other than C, Python and Go). Find the values above (library calls, system calls and running time).

  • Quiz

    - + \ No newline at end of file diff --git a/Lab/Software Stack/index.html b/Lab/Software Stack/index.html index 66ce933d55..5b6e9f8f12 100644 --- a/Lab/Software Stack/index.html +++ b/Lab/Software Stack/index.html @@ -4,13 +4,13 @@ Software Stack | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lab/Software Stack/libc/index.html b/Lab/Software Stack/libc/index.html index 36a86cc61e..fcdecac8a1 100644 --- a/Lab/Software Stack/libc/index.html +++ b/Lab/Software Stack/libc/index.html @@ -4,7 +4,7 @@ Libraries and libc | Operating Systems - + @@ -37,7 +37,7 @@ And for certain calls to malloc() / free() no syscall is happening. You'll find more about them in the Data chapter.

  • Create your own C program with calls to the standard C library in vendetta.c. Be as creative as you can about the types of functions being made.

  • Quiz

    - + \ No newline at end of file diff --git a/Lab/Software Stack/libcall-syscall/index.html b/Lab/Software Stack/libcall-syscall/index.html index 3f119be1a1..7fbb4259a6 100644 --- a/Lab/Software Stack/libcall-syscall/index.html +++ b/Lab/Software Stack/libcall-syscall/index.html @@ -4,7 +4,7 @@ Library calls vs system calls | Operating Systems - + @@ -19,7 +19,7 @@ To avoid this behaviour, you can force the lazy binding (based on which ltrace is constructed to work). An example can be found in support/libcall-syscall/Makefile, however for system binaries, such as ls or pwd, the only alternative is to add the -x "*" argument to force the command to trace all symbols in the symbol table:

    student@os:~$ ltrace -x "*" ls

    You can always choose what library functions ltrace is investigating, by replacing the wildcard with their name:

    student@os:~$ ltrace -x "malloc" -x "free" ls
    malloc@libc.so.6(5) = 0x55c42b2b8910
    free@libc.so.6(0x55c42b2b8910) = <void>
    malloc@libc.so.6(120) = 0x55c42b2b8480
    malloc@libc.so.6(12) = 0x55c42b2b8910
    malloc@libc.so.6(776) = 0x55c42b2b8930
    malloc@libc.so.6(112) = 0x55c42b2b8c40
    malloc@libc.so.6(1336) = 0x55c42b2b8cc0
    malloc@libc.so.6(216) = 0x55c42b2b9200
    malloc@libc.so.6(432) = 0x55c42b2b92e0
    malloc@libc.so.6(104) = 0x55c42b2b94a0
    malloc@libc.so.6(88) = 0x55c42b2b9510
    malloc@libc.so.6(120) = 0x55c42b2b9570
    [...]

    If you would like to know more about lazy binding, now binding or PLT entries, check out this blog post.

    Practice

    Enter the support/libcall-syscall/ folder and go through the practice items below.

    1. Check library calls and system calls for the call2.c file. Use ltrace and strace.

      Find explanations for the calls being made and the library call to system call mapping.

    Quiz

    - + \ No newline at end of file diff --git a/Lab/Software Stack/modern-sw-stack/index.html b/Lab/Software Stack/modern-sw-stack/index.html index 3f9275ab34..5266338465 100644 --- a/Lab/Software Stack/modern-sw-stack/index.html +++ b/Lab/Software Stack/modern-sw-stack/index.html @@ -4,7 +4,7 @@ Modern Software Stacks | Operating Systems - + @@ -19,7 +19,7 @@ Part of the API exposed by the standard C library is the standard C API, also called ANSI C or ISO C; this API is typically portable across all platforms (operating systems and hardware). This API, going beyond system call wrappers, has several advantages:

    - + \ No newline at end of file diff --git a/Lab/Software Stack/overview/index.html b/Lab/Software Stack/overview/index.html index 848e8b6dd8..38488b8a98 100644 --- a/Lab/Software Stack/overview/index.html +++ b/Lab/Software Stack/overview/index.html @@ -4,7 +4,7 @@ Software Stack | Operating Systems - + @@ -24,7 +24,7 @@ These generic interfaces "hides" possible differences in the even lower layers. This way, a software stack ensures portability across different other parts of software (and hardware as well). For example, the standard C library, that we will present shortly, ensures portability across different operating systems.

    Software Stack

    Quiz

    Contents

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/common-functions/index.html b/Lab/Software Stack/quiz/common-functions/index.html index 9479908971..4b074ca2af 100644 --- a/Lab/Software Stack/quiz/common-functions/index.html +++ b/Lab/Software Stack/quiz/common-functions/index.html @@ -4,14 +4,14 @@ Common Functions | Operating Systems - +
    Skip to main content

    Common Functions

    printf() System Call

    Question Text

    What system call does the printf() function invoke?

    Question Answers

    • read
    • write
    • exec

    • exit

    Feedback

    printf() invokes the write system call to print messages to standard output.

    strcpy() System Call

    Question Text

    What system call does the strcpy() function invoke?

    Question Answers

    • cpy

    • touch

    • memcpy

    • no system call

    Feedback

    strcpy() doesn't invoke system calls, because it doesn't require any feature that is only provided by the operating system

    printf() vs write

    Question Text

    What are features provided by printf() when compared to write? (choose 2 answers)

    Question Answers

    • buffering
    • outputs to standard output

    • may write to file

    • does output formatting
    • can work with binary data

    Feedback

    printf() can do buffering to reduce the number of system calls. Also, printf(), as it name suggests (the f suffix), does output formatting.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/high-level-lang/index.html b/Lab/Software Stack/quiz/high-level-lang/index.html index 2f16827dc6..7fce956c50 100644 --- a/Lab/Software Stack/quiz/high-level-lang/index.html +++ b/Lab/Software Stack/quiz/high-level-lang/index.html @@ -4,14 +4,14 @@ Python Tools | Operating Systems - +
    Skip to main content

    Python Tools

    Question Text

    A Python program is not a proper argument for ...

    Question Answers

    • ltrace

    • strace

    • rm

    • ldd

    Feedback

    Because a Python program is a script to be interpreted, it won't be usable by ldd. ldd is passed a binary executable to look for library dependencies.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/libc/index.html b/Lab/Software Stack/quiz/libc/index.html index d7c9cc5e3a..7a145e8a90 100644 --- a/Lab/Software Stack/quiz/libc/index.html +++ b/Lab/Software Stack/quiz/libc/index.html @@ -4,13 +4,13 @@ libc | Operating Systems - +
    Skip to main content

    libc

    malloc()

    Question Text

    What system calls are invoked by the malloc() library call for Linux libc? (choose 2 answers)

    Question Answers

    • brk
    • free

    • dup

    • mmap
    • copy

    Feedback

    Depending on the allocation size, malloc() invokes brk or mmap.

    Syscall Tool

    Question Text

    Which of following is not and advantage of using libc for programs?

    Question Answers

    • increased portability
    • reduced executable size
    • richer set of features

    • easier development

    Feedback

    When using libc, because we add a new software component, the size of the resulting executable increases.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/libcall-syscall/index.html b/Lab/Software Stack/quiz/libcall-syscall/index.html index 55480ca328..3d845acd7c 100644 --- a/Lab/Software Stack/quiz/libcall-syscall/index.html +++ b/Lab/Software Stack/quiz/libcall-syscall/index.html @@ -4,14 +4,14 @@ Libcall with Syscall | Operating Systems - +
    Skip to main content

    Libcall with Syscall

    Question Text

    Which of the following library calls will for sure invoke a system call?

    Question Answers

    • fopen()
    • fwrite()

    • printf()

    • strcpy()

    Feedback

    fopen() requires opening a file and access to the operating system (for filesystem access). The others may not require a system call (strcpy()) or may use buffering to delay the invocation of a system call (fwrite(), printf()).

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/libs/index.html b/Lab/Software Stack/quiz/libs/index.html index 675e877e00..83d5416036 100644 --- a/Lab/Software Stack/quiz/libs/index.html +++ b/Lab/Software Stack/quiz/libs/index.html @@ -4,14 +4,14 @@ libs | Operating Systems - +
    Skip to main content

    libs

    Static Executables

    Question Text

    Which of the following tools has no influence over statically-linked executables? (choose 2 answers)

    Question Answers

    • ltrace
    • strace

    • nm

    • ldd
    • rm

    Feedback

    ltrace and ldd are used to capture connections to dynamic libraries. They have no effect on statically-linked executables.

    Dynamic Libraries

    Question Text

    Which of the following is a dynamic library?

    Question Answers

    • libc.a
    • libc.so
    • libc.exe

    • libc.c

    Feedback

    The .so (shared object) extension is used for dynamic libraries in Linux.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/software/index.html b/Lab/Software Stack/quiz/software/index.html index 43dfabb1e9..a43fe8ce52 100644 --- a/Lab/Software Stack/quiz/software/index.html +++ b/Lab/Software Stack/quiz/software/index.html @@ -4,7 +4,7 @@ Software Properties | Operating Systems - + @@ -12,7 +12,7 @@
    Skip to main content

    Software Properties

    Question Text

    Which of the following is not an advantage of software when compared to hardware?

    Question Answers

    • reusability
    • performance
    • portability

    • flexibility

    Feedback

    Software is reusable and flexible, unlike physical hardware that's rigid and used-once. Software is also portable across different hardware (and software platforms). However, software relies on hardware for running, so software will never beat hardware in terms of sheer speed / performance.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/syscall-wrapper/index.html b/Lab/Software Stack/quiz/syscall-wrapper/index.html index a9d406e471..a890e500f7 100644 --- a/Lab/Software Stack/quiz/syscall-wrapper/index.html +++ b/Lab/Software Stack/quiz/syscall-wrapper/index.html @@ -4,13 +4,13 @@ Syscall Wrappers | Operating Systems - +
    Skip to main content

    Syscall Wrappers

    Question Text

    What language do we use to invoke system calls?

    Question Answers

    • assembly
    • C

    • C++

    • Go

    Feedback

    System calls require setting of registers that can only be done in assembly language.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/quiz/syscalls/index.html b/Lab/Software Stack/quiz/syscalls/index.html index ba4230594e..9786fc4d2a 100644 --- a/Lab/Software Stack/quiz/syscalls/index.html +++ b/Lab/Software Stack/quiz/syscalls/index.html @@ -4,13 +4,13 @@ Syscalls | Operating Systems - +
    Skip to main content

    Syscalls

    Syscall ID

    Question Text

    What register stores the system call ID on x86_64?

    Question Answers

    • RIP

    • RSP

    • RAX
    • RDX

    Feedback

    RAX is the register used for passing the syscall ID and the result code.

    Syscall Tool

    Question Text

    What tool do we use to capture system calls?

    Question Answers

    • strace
    • make

    • gcc

    • ./exec

    Feedback

    strace is used to trace system calls invoked by a running program.

    Syscall Numbers

    Question Text

    What is the approximate number of system call numbers in Linux?

    Question Answers

    • 3

    • 30

    • 300
    • 3000

    Feedback

    As show here, they're about 300 system calls in Linux.

    - + \ No newline at end of file diff --git a/Lab/Software Stack/static-dynamic/index.html b/Lab/Software Stack/static-dynamic/index.html index 07b0a60d41..b510162fb3 100644 --- a/Lab/Software Stack/static-dynamic/index.html +++ b/Lab/Software Stack/static-dynamic/index.html @@ -4,7 +4,7 @@ Statically-linked and Dynamically-linked Libraries | Operating Systems - + @@ -14,7 +14,7 @@ Let's build and run the two executables:

    student@os:~/.../lab/support/static-dynamic$ ls
    hello.c Makefile

    student@os:~/.../lab/support/static-dynamic$ make
    cc -Wall -c -o hello.o hello.c
    cc hello.o -o hello
    cc -static -o hello_static hello.o

    student@os:~/.../lab/support/static-dynamic$ ls -lh
    total 852K
    -rwxrwxr-x 1 razvan razvan 8.2K Aug 2 15:53 hello
    -rw-rw-r-- 1 razvan razvan 76 Aug 2 15:51 hello.c
    -rw-rw-r-- 1 razvan razvan 1.6K Aug 2 15:53 hello.o
    -rwxrwxr-x 1 razvan razvan 827K Aug 2 15:53 hello_static
    -rw-rw-r-- 1 razvan razvan 237 Aug 2 15:53 Makefile

    student@os:~/.../lab/support/static-dynamic$ ./hello
    Hello, World!

    student@os:~/.../lab/support/static-dynamic$ ./hello_static
    Hello, World!

    The two executables (hello and hello_static) behave similarly, despite having vastly different sizes (8.2K vs. 827K - 100 times larger).

    We use nm and ldd to catch differences between the two types of resulting executables:

    student@os:~/.../lab/support/static-dynamic$ ldd hello
    linux-vdso.so.1 (0x00007ffc8d9b2000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f10d1d88000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f10d237b000)

    student@os:~/.../lab/support/static-dynamic$ ldd hello_static
    not a dynamic executable

    student@os:~/.../lab/support/static-dynamic$ nm hello | wc -l
    33

    student@os:~/.../lab/support/static-dynamic$ nm hello_static | wc -l
    1674

    The dynamic executable references the dynamically-linked libc library (/lib/x86_64-linux-gnu/libc.so.6), while the statically-linked executable has no references. Also, given the statically-linked executable integrated entire parts of statically-linked libraries, there are many more symbols than in the case of a dynamically-linked executable (1674 vs. 33).

    We can use strace to see that there are differences in the preparatory system calls for each type of executables. For the dynamically-linked executable, the dynamically-linked library (/lib/x86_64-linux-gnu/libc.so.6) is opened during runtime:

    student@os:~/.../lab/support/static-dynamic$ strace ./hello
    execve("./hello", ["./hello"], 0x7ffc409c6640 /* 66 vars */) = 0
    brk(NULL) = 0x55a72eda6000
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=198014, ...}) = 0
    mmap(NULL, 198014, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f3136a41000
    close(3) = 0
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\35\2\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=2030928, ...}) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3136a3f000
    mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f3136458000
    mprotect(0x7f313663f000, 2097152, PROT_NONE) = 0
    mmap(0x7f313683f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f313683f000
    mmap(0x7f3136845000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f3136845000
    close(3) = 0
    arch_prctl(ARCH_SET_FS, 0x7f3136a404c0) = 0
    mprotect(0x7f313683f000, 16384, PROT_READ) = 0
    mprotect(0x55a72d1bb000, 4096, PROT_READ) = 0
    mprotect(0x7f3136a72000, 4096, PROT_READ) = 0
    munmap(0x7f3136a41000, 198014) = 0
    fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 18), ...}) = 0
    brk(NULL) = 0x55a72eda6000
    brk(0x55a72edc7000) = 0x55a72edc7000
    write(1, "Hello, World!\n", 14Hello, World!
    ) = 14
    exit_group(0) = ?
    +++ exited with 0 +++

    student@os:~/.../lab/support/static-dynamic$ strace ./hello_static
    execve("./hello_static", ["./hello_static"], 0x7ffc9fd45400 /* 66 vars */) = 0
    brk(NULL) = 0xff8000
    brk(0xff91c0) = 0xff91c0
    arch_prctl(ARCH_SET_FS, 0xff8880) = 0
    uname({sysname="Linux", nodename="yggdrasil", ...}) = 0
    readlink("/proc/self/exe", "/home/razvan/school/so/operating"..., 4096) = 116
    brk(0x101a1c0) = 0x101a1c0
    brk(0x101b000) = 0x101b000
    access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
    fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 18), ...}) = 0
    write(1, "Hello, World!\n", 14Hello, World!
    ) = 14
    exit_group(0) = ?
    +++ exited with 0 +++

    Similarly, we can investigate a system executable (/bin/ls) to see that indeed all referenced dynamically-linked libraries are opened (via the openat system call) at runtime:

    student@os:~/.../lab/support/static-dynamic$ ldd $(which ls)
    linux-vdso.so.1 (0x00007ffc3bdf3000)
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f092bd88000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f092b997000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f092b726000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f092b522000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f092c1d2000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f092b303000)

    student@os:~/.../lab/support/static-dynamic$ strace -e openat ls
    openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
    openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
    community docs _index.html search.md
    +++ exited with 0 +++

    Quiz

    - + \ No newline at end of file diff --git a/Lab/Software Stack/syscall-wrapper/index.html b/Lab/Software Stack/syscall-wrapper/index.html index 926a6a7b15..a3895816b2 100644 --- a/Lab/Software Stack/syscall-wrapper/index.html +++ b/Lab/Software Stack/syscall-wrapper/index.html @@ -4,7 +4,7 @@ System Call Wrappers | Operating Systems - + @@ -19,7 +19,7 @@ Make a call to the read system call to read data from standard input in a buffer. Then call write() to print data from that buffer.

    Note that the read system call returns the number of bytes read. Use that as the argument to the subsequent write call that prints read data.

    We can see that it's easier to have wrapper calls and write most of the code in C than in assembly language.

    Quiz

    - + \ No newline at end of file diff --git a/Lab/index.html b/Lab/index.html index 3c757d3387..b28f0dfafc 100644 --- a/Lab/index.html +++ b/Lab/index.html @@ -4,13 +4,13 @@ Lab | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lab/lab-setup/index.html b/Lab/lab-setup/index.html index 24d84d5cff..46726cd14b 100644 --- a/Lab/lab-setup/index.html +++ b/Lab/lab-setup/index.html @@ -4,14 +4,14 @@ Setting up the Lab Environment | Operating Systems - +
    Skip to main content

    Setting up the Lab Environment

    If you have already cloned the repository, make sure it is updated:

    student@os:~$ cd operating-systems

    student@os:~/operating-systems$ git pull --rebase

    The command may fail if you have uncommitted changes. If that is the case, stash your changes, retry, and pop the stash:

    student@os:~/operating-systems$ git stash

    student@os:~/operating-systems$ git pull --rebase

    student@os:~/operating-systems$ git stash pop

    If you haven't already cloned the repository, do so and then enter the repository:

    student@os:~$ git clone https://github.com/cs-pub-ro/operating-systems

    student@os:~$ cd operating-systems

    Navigate to a chapter's lab directory:

    student@os:~/operating-systems$ cd content/chapters/<chapter-name>/lab/

    The possible options are: software-stack, data, compute, io and app-interact.

    If you're using the OS-runner Docker container, you can use the following shortcuts:

    go-ss - changes directory to Software Stack lab

    go-data - changes directory to Data lab

    go-compute - changes directory to Compute lab

    go-io - changes directory to IO lab

    go-appInt - changes directory to App Interaction lab

    - + \ No newline at end of file diff --git a/Lecture/Application-Interaction/index.html b/Lecture/Application-Interaction/index.html index 8679c12893..fc2cac4843 100644 --- a/Lecture/Application-Interaction/index.html +++ b/Lecture/Application-Interaction/index.html @@ -4,13 +4,13 @@ Application-Interaction | Operating Systems - +
    Skip to main content

    Application-Interaction


    tip

    Focus the slides and press F for fullscreen viewing.

    - + \ No newline at end of file diff --git a/Lecture/Compute/index.html b/Lecture/Compute/index.html index c8f0210caa..82f57d9d99 100644 --- a/Lecture/Compute/index.html +++ b/Lecture/Compute/index.html @@ -4,13 +4,13 @@ Compute | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lecture/Data/index.html b/Lecture/Data/index.html index 2bd38bbcba..40429e4694 100644 --- a/Lecture/Data/index.html +++ b/Lecture/Data/index.html @@ -4,13 +4,13 @@ Data | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lecture/IO/index.html b/Lecture/IO/index.html index 193574f42f..277ce4696a 100644 --- a/Lecture/IO/index.html +++ b/Lecture/IO/index.html @@ -4,13 +4,13 @@ IO | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lecture/Software-Stack/index.html b/Lecture/Software-Stack/index.html index 3f69b7e401..182735676a 100644 --- a/Lecture/Software-Stack/index.html +++ b/Lecture/Software-Stack/index.html @@ -4,13 +4,13 @@ Software-Stack | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/Lecture/index.html b/Lecture/index.html index 0d688639b9..334a61bcf8 100644 --- a/Lecture/index.html +++ b/Lecture/index.html @@ -4,13 +4,13 @@ Lecture | Operating Systems - +
    Skip to main content
    - + \ No newline at end of file diff --git a/assets/js/935f2afb.a906aa4d.js b/assets/js/935f2afb.a906aa4d.js deleted file mode 100644 index 96c0e31c28..0000000000 --- a/assets/js/935f2afb.a906aa4d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkso=self.webpackChunkso||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"sidebar":[{"type":"link","label":"Introduction","href":"/operating-systems/","docId":"README"},{"type":"category","label":"Lecture","items":[{"type":"link","label":"Software Stack","href":"/operating-systems/Lecture/Software-Stack","docId":"Lecture/Software-Stack"},{"type":"link","label":"Data","href":"/operating-systems/Lecture/Data","docId":"Lecture/Data"},{"type":"link","label":"Compute","href":"/operating-systems/Lecture/Compute","docId":"Lecture/Compute"},{"type":"link","label":"IO","href":"/operating-systems/Lecture/IO","docId":"Lecture/IO"},{"type":"link","label":"Application Interaction","href":"/operating-systems/Lecture/Application-Interaction","docId":"Lecture/Application-Interaction"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lecture/"},{"type":"category","label":"Lab","items":[{"type":"link","label":"Setting up the Lab Environment","href":"/operating-systems/Lab/lab-setup","docId":"Lab/lab-setup"},{"type":"category","label":"Software Stack","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Software Stack/overview","docId":"Lab/Software Stack/overview"},{"type":"link","label":"Modern Software Stacks","href":"/operating-systems/Lab/Software Stack/modern-sw-stack","docId":"Lab/Software Stack/modern-sw-stack"},{"type":"link","label":"Basic System Calls","href":"/operating-systems/Lab/Software Stack/basic-syscall","docId":"Lab/Software Stack/basic-syscall"},{"type":"link","label":"System Call Wrapper","href":"/operating-systems/Lab/Software Stack/syscall-wrapper","docId":"Lab/Software Stack/syscall-wrapper"},{"type":"link","label":"Common Functions","href":"/operating-systems/Lab/Software Stack/common-functions","docId":"Lab/Software Stack/common-functions"},{"type":"link","label":"Libc","href":"/operating-systems/Lab/Software Stack/libc","docId":"Lab/Software Stack/libc"},{"type":"link","label":"Static-dynamic","href":"/operating-systems/Lab/Software Stack/static-dynamic","docId":"Lab/Software Stack/static-dynamic"},{"type":"link","label":"Libcall-Syscall","href":"/operating-systems/Lab/Software Stack/libcall-syscall","docId":"Lab/Software Stack/libcall-syscall"},{"type":"link","label":"High-Level Languages","href":"/operating-systems/Lab/Software Stack/high-level-lang","docId":"Lab/Software Stack/high-level-lang"},{"type":"link","label":"App Investigation","href":"/operating-systems/Lab/Software Stack/app-investigate","docId":"Lab/Software Stack/app-investigate"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Software Stack/arena","docId":"Lab/Software Stack/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Software Stack/"},{"type":"category","label":"Data","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Data/overview","docId":"Lab/Data/overview"},{"type":"link","label":"Working with Memory","href":"/operating-systems/Lab/Data/working-memory","docId":"Lab/Data/working-memory"},{"type":"link","label":"Process Memory","href":"/operating-systems/Lab/Data/process-memory","docId":"Lab/Data/process-memory"},{"type":"link","label":"Investigate Memory","href":"/operating-systems/Lab/Data/investigate-memory","docId":"Lab/Data/investigate-memory"},{"type":"link","label":"Memory Security","href":"/operating-systems/Lab/Data/memory-security","docId":"Lab/Data/memory-security"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Data/arena","docId":"Lab/Data/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Data/"},{"type":"category","label":"Compute","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Compute/overview","docId":"Lab/Compute/overview"},{"type":"link","label":"Hardware Perspective","href":"/operating-systems/Lab/Compute/hardware-perspective","docId":"Lab/Compute/hardware-perspective"},{"type":"link","label":"Processes","href":"/operating-systems/Lab/Compute/processes","docId":"Lab/Compute/processes"},{"type":"link","label":"Threads","href":"/operating-systems/Lab/Compute/threads","docId":"Lab/Compute/threads"},{"type":"link","label":"Processes-threads-apache2","href":"/operating-systems/Lab/Compute/processes-threads-apache2","docId":"Lab/Compute/processes-threads-apache2"},{"type":"link","label":"Copy-on-Write","href":"/operating-systems/Lab/Compute/copy-on-write","docId":"Lab/Compute/copy-on-write"},{"type":"link","label":"Synchronization","href":"/operating-systems/Lab/Compute/synchronization","docId":"Lab/Compute/synchronization"},{"type":"link","label":"User-Level Threads","href":"/operating-systems/Lab/Compute/user-level-threads","docId":"Lab/Compute/user-level-threads"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Compute/arena","docId":"Lab/Compute/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Compute/"},{"type":"category","label":"IO","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/IO/overview","docId":"Lab/IO/overview"},{"type":"link","label":"File Handlers","href":"/operating-systems/Lab/IO/file-handlers","docId":"Lab/IO/file-handlers"},{"type":"link","label":"File Descriptors","href":"/operating-systems/Lab/IO/file-descriptors","docId":"Lab/IO/file-descriptors"},{"type":"link","label":"Redirections","href":"/operating-systems/Lab/IO/redirections","docId":"Lab/IO/redirections"},{"type":"link","label":"Pipes","href":"/operating-systems/Lab/IO/pipes","docId":"Lab/IO/pipes"},{"type":"link","label":"Local IO in Action","href":"/operating-systems/Lab/IO/local-io-in-action","docId":"Lab/IO/local-io-in-action"},{"type":"link","label":"Remote IO","href":"/operating-systems/Lab/IO/remote-io","docId":"Lab/IO/remote-io"},{"type":"link","label":"Networking 101","href":"/operating-systems/Lab/IO/networking-101","docId":"Lab/IO/networking-101"},{"type":"link","label":"Client-Server Model","href":"/operating-systems/Lab/IO/client-server-model","docId":"Lab/IO/client-server-model"},{"type":"link","label":"Beyond Network Sockets","href":"/operating-systems/Lab/IO/beyond-network-sockets","docId":"Lab/IO/beyond-network-sockets"},{"type":"link","label":"File Mappings","href":"/operating-systems/Lab/IO/file-mappings","docId":"Lab/IO/file-mappings"},{"type":"link","label":"IO Internals","href":"/operating-systems/Lab/IO/io-internals","docId":"Lab/IO/io-internals"},{"type":"link","label":"Zero-Copy","href":"/operating-systems/Lab/IO/zero-copy","docId":"Lab/IO/zero-copy"},{"type":"link","label":"Asynchronous IO","href":"/operating-systems/Lab/IO/async-io","docId":"Lab/IO/async-io"},{"type":"link","label":"IO Multiplexing","href":"/operating-systems/Lab/IO/io-multiplexing","docId":"Lab/IO/io-multiplexing"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/IO/arena","docId":"Lab/IO/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/IO/"},{"type":"category","label":"Application Interaction","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Application Interaction/overview","docId":"Lab/Application Interaction/overview"},{"type":"link","label":"Time Server","href":"/operating-systems/Lab/Application Interaction/time-server","docId":"Lab/Application Interaction/time-server"},{"type":"link","label":"Password Cracker","href":"/operating-systems/Lab/Application Interaction/password-cracker","docId":"Lab/Application Interaction/password-cracker"},{"type":"link","label":"The X Window System","href":"/operating-systems/Lab/Application Interaction/x-window-system","docId":"Lab/Application Interaction/x-window-system"},{"type":"link","label":"D-Bus","href":"/operating-systems/Lab/Application Interaction/dbus","docId":"Lab/Application Interaction/dbus"},{"type":"link","label":"OS Cloud","href":"/operating-systems/Lab/Application Interaction/os-cloud","docId":"Lab/Application Interaction/os-cloud"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Application Interaction/arena","docId":"Lab/Application Interaction/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Application Interaction/"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/"},{"type":"category","label":"Assignments","items":[{"type":"link","label":"Mini Libc","href":"/operating-systems/Assignments/Mini Libc/","docId":"Assignments/Mini Libc/README"},{"type":"link","label":"Memory Allocator","href":"/operating-systems/Assignments/Memory Allocator/","docId":"Assignments/Memory Allocator/README"},{"type":"link","label":"Parallel Graph","href":"/operating-systems/Assignments/Parallel Graph/","docId":"Assignments/Parallel Graph/README"},{"type":"link","label":"Mini Shell","href":"/operating-systems/Assignments/Mini Shell/","docId":"Assignments/Mini Shell/README"},{"type":"link","label":"Asynchronous Web Server","href":"/operating-systems/Assignments/Asynchronous Web Server/","docId":"Assignments/Asynchronous Web Server/README"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Assignments/"},{"type":"link","label":"Rules and Grading","href":"/operating-systems/rules-and-grading","docId":"rules-and-grading"},{"type":"link","label":"Resources","href":"/operating-systems/resources","docId":"resources"}]},"docs":{"Assignments/Asynchronous Web Server/README":{"id":"Assignments/Asynchronous Web Server/README","title":"Asynchronous Web Server","description":"Objectives","sidebar":"sidebar"},"Assignments/Asynchronous Web Server/src/http-parser/README":{"id":"Assignments/Asynchronous Web Server/src/http-parser/README","title":"HTTP Parser","description":"This is a parser for HTTP messages written in C. It parses both requests and"},"Assignments/Memory Allocator/README":{"id":"Assignments/Memory Allocator/README","title":"Memory Allocator","description":"Objectives","sidebar":"sidebar"},"Assignments/Mini Libc/README":{"id":"Assignments/Mini Libc/README","title":"Mini-libc","description":"Objectives","sidebar":"sidebar"},"Assignments/Mini Shell/README":{"id":"Assignments/Mini Shell/README","title":"Minishell","description":"Objectives","sidebar":"sidebar"},"Assignments/Mini Shell/util/parser/README":{"id":"Assignments/Mini Shell/util/parser/README","title":"Parser","description":"The parser is made using Bison and Flex."},"Assignments/Parallel Graph/README":{"id":"Assignments/Parallel Graph/README","title":"Parallel Graph","description":"For this assignment we will implement a generic thread pool, which we will then use to traverse a graph and compute the sum of the elements contained by the nodes.","sidebar":"sidebar"},"Lab/Application Interaction/arena":{"id":"Lab/Application Interaction/arena","title":"Arena","description":"Oneko","sidebar":"sidebar"},"Lab/Application Interaction/dbus":{"id":"Lab/Application Interaction/dbus","title":"D-Bus","description":"D-Bus is an Inter-Process Communication (IPC) mechanism that is commonly present on Linux.","sidebar":"sidebar"},"Lab/Application Interaction/os-cloud":{"id":"Lab/Application Interaction/os-cloud","title":"OS Cloud","description":"In this section, we are going to build a \\"toy cloud\\" called OS Cloud.","sidebar":"sidebar"},"Lab/Application Interaction/overview":{"id":"Lab/Application Interaction/overview","title":"Application Interaction","description":"In this chapter, you will discover various mechanisms through which applications on a system can interact.","sidebar":"sidebar"},"Lab/Application Interaction/password-cracker":{"id":"Lab/Application Interaction/password-cracker","title":"Password Cracker","description":"In this example, we will solve the following problem: given the sha512 hash of a password, we want to obtain the password that generated the hash.","sidebar":"sidebar"},"Lab/Application Interaction/quiz/cgroups-vs-namespaces":{"id":"Lab/Application Interaction/quiz/cgroups-vs-namespaces","title":"Cgroups versus namespaces","description":"Question Text"},"Lab/Application Interaction/quiz/container-vs-vm":{"id":"Lab/Application Interaction/quiz/container-vs-vm","title":"Container versus VM","description":"Question Text"},"Lab/Application Interaction/quiz/time-server":{"id":"Lab/Application Interaction/quiz/time-server","title":"Time Server Protocol","description":"Question Text"},"Lab/Application Interaction/quiz/time-server-interop":{"id":"Lab/Application Interaction/quiz/time-server-interop","title":"Time Server Interoperability","description":"Question Text"},"Lab/Application Interaction/quiz/timer":{"id":"Lab/Application Interaction/quiz/timer","title":"Oneko Timer","description":"Question Text"},"Lab/Application Interaction/quiz/vm-creation":{"id":"Lab/Application Interaction/quiz/vm-creation","title":"VM Creation","description":"Question Text"},"Lab/Application Interaction/time-server":{"id":"Lab/Application Interaction/time-server","title":"Time Server","description":"Check out the code in support/time-server/server.c and support/time-server/client.c.","sidebar":"sidebar"},"Lab/Application Interaction/x-window-system":{"id":"Lab/Application Interaction/x-window-system","title":"The X Window System","description":"Unix-like systems that support a Graphical User Interface usually do this through the X Window System.","sidebar":"sidebar"},"Lab/Compute/arena":{"id":"Lab/Compute/arena","title":"Arena","description":"Threads and Processes: clone","sidebar":"sidebar"},"Lab/Compute/copy-on-write":{"id":"Lab/Compute/copy-on-write","title":"Copy-on-Write","description":"So far, you know that the parent and child process have separate virtual address spaces.","sidebar":"sidebar"},"Lab/Compute/hardware-perspective":{"id":"Lab/Compute/hardware-perspective","title":"Hardware Perspective","description":"The main criterion we use to rank CPUs is their computation power, i.e. their ability to crunch numbers and do math.","sidebar":"sidebar"},"Lab/Compute/overview":{"id":"Lab/Compute/overview","title":"Compute","description":"Contents","sidebar":"sidebar"},"Lab/Compute/processes":{"id":"Lab/Compute/processes","title":"Processes","description":"A process is simply a running program.","sidebar":"sidebar"},"Lab/Compute/processes-threads-apache2":{"id":"Lab/Compute/processes-threads-apache2","title":"Usage of Processes and Threads in `apache2`","description":"We\'ll take a look at how a real-world application - the apache2 HTTP server - makes use of processes and threads.","sidebar":"sidebar"},"Lab/Compute/quiz/apache2-strace":{"id":"Lab/Compute/quiz/apache2-strace","title":"`apache2` Document Root","description":"Question Text"},"Lab/Compute/quiz/cause-of-file-not-found-error":{"id":"Lab/Compute/quiz/cause-of-file-not-found-error","title":"Cause of `FileNotFoundError`","description":"Question Text"},"Lab/Compute/quiz/child-faults-after-write":{"id":"Lab/Compute/quiz/child-faults-after-write","title":"Child Faults After Write","description":"Question Text"},"Lab/Compute/quiz/coarse-vs-granular-critical-section":{"id":"Lab/Compute/quiz/coarse-vs-granular-critical-section","title":"Coarse vs Granular Critical Section","description":"Question Text"},"Lab/Compute/quiz/create-sleepy-process-ending":{"id":"Lab/Compute/quiz/create-sleepy-process-ending","title":"`create_sleepy` Process Ending","description":"Question Text"},"Lab/Compute/quiz/fiber-strace":{"id":"Lab/Compute/quiz/fiber-strace","title":"Fiber Strace","description":"Question Text"},"Lab/Compute/quiz/mini-shell-stops-after-command":{"id":"Lab/Compute/quiz/mini-shell-stops-after-command","title":"Mini-shell Stops After Command","description":"Question Text"},"Lab/Compute/quiz/mmap-cow-flag":{"id":"Lab/Compute/quiz/mmap-cow-flag","title":"Copy-on-write Flag for `mmap()`","description":"Question Text"},"Lab/Compute/quiz/notify-only-with-mutex":{"id":"Lab/Compute/quiz/notify-only-with-mutex","title":"Both Condition and Mutex","description":"Question Text"},"Lab/Compute/quiz/number-of-running-ults":{"id":"Lab/Compute/quiz/number-of-running-ults","title":"Number of RUNNING User-Level Threads","description":"Question Text"},"Lab/Compute/quiz/parent-faults-before-fork":{"id":"Lab/Compute/quiz/parent-faults-before-fork","title":"Parent Faults before `fork()`","description":"Question Text"},"Lab/Compute/quiz/parent-of-sleep-processes":{"id":"Lab/Compute/quiz/parent-of-sleep-processes","title":"Parent of `sleep` Processes","description":"Question Text"},"Lab/Compute/quiz/processes-speedup":{"id":"Lab/Compute/quiz/processes-speedup","title":"Processes Speedup","description":"Question Text"},"Lab/Compute/quiz/seg-fault-exit-code":{"id":"Lab/Compute/quiz/seg-fault-exit-code","title":"Seg Fault Exit Code","description":"Question Text"},"Lab/Compute/quiz/semaphore-equivalent":{"id":"Lab/Compute/quiz/semaphore-equivalent","title":"Semaphore Equivalent","description":"Question Text"},"Lab/Compute/quiz/sleeping-on-a-fiber":{"id":"Lab/Compute/quiz/sleeping-on-a-fiber","title":"Sleeping on a Fiber","description":"Question Text"},"Lab/Compute/quiz/state-of-new-ult":{"id":"Lab/Compute/quiz/state-of-new-ult","title":"State of new ULT","description":"Question Text"},"Lab/Compute/quiz/tcb-libult-unikraft":{"id":"Lab/Compute/quiz/tcb-libult-unikraft","title":"Similarities Between the TCBs of `libult` and Unikraft","description":"Question Text"},"Lab/Compute/quiz/thread-memory":{"id":"Lab/Compute/quiz/thread-memory","title":"Thread Memory","description":"Question Text"},"Lab/Compute/quiz/time-slice-value":{"id":"Lab/Compute/quiz/time-slice-value","title":"Time Slice Value","description":"Question Text"},"Lab/Compute/quiz/tls-synchronization":{"id":"Lab/Compute/quiz/tls-synchronization","title":"TLS Synchronization","description":"Question Text"},"Lab/Compute/quiz/tls-var-copies":{"id":"Lab/Compute/quiz/tls-var-copies","title":"TLS `var` Copies","description":"Question Text"},"Lab/Compute/quiz/type-of-scheduler-in-libult":{"id":"Lab/Compute/quiz/type-of-scheduler-in-libult","title":"Type of Scheduler in `libult.so`","description":"Question Text"},"Lab/Compute/quiz/ult-thread-ids":{"id":"Lab/Compute/quiz/ult-thread-ids","title":"ULT Thread IDs","description":"Question Text"},"Lab/Compute/quiz/who-calls-execve-parent":{"id":"Lab/Compute/quiz/who-calls-execve-parent","title":"Who Calls `execve` in the Log of the Parent Process?","description":"Question Text"},"Lab/Compute/quiz/why-use-completed-queue":{"id":"Lab/Compute/quiz/why-use-completed-queue","title":"The Need for a COMPLETED Queue","description":"Question Text"},"Lab/Compute/synchronization":{"id":"Lab/Compute/synchronization","title":"Synchronization","description":"So far, we\'ve used threads and processes without wondering how to \\"tell\\" them how to access shared data.","sidebar":"sidebar"},"Lab/Compute/threads":{"id":"Lab/Compute/threads","title":"Threads","description":"Spreading the Work Among Other Threads","sidebar":"sidebar"},"Lab/Compute/user-level-threads":{"id":"Lab/Compute/user-level-threads","title":"User-Level Threads","description":"User-level threads differ from the threads you are used to (kernel-level threads, those created by pthread_create).","sidebar":"sidebar"},"Lab/Data/arena":{"id":"Lab/Data/arena","title":"Arena","description":"Go through the practice items below to hone your skills in working with data and memory.","sidebar":"sidebar"},"Lab/Data/investigate-memory":{"id":"Lab/Data/investigate-memory","title":"Investigate Memory Actions","description":"Memory actions generally mean:","sidebar":"sidebar"},"Lab/Data/memory-security":{"id":"Lab/Data/memory-security","title":"Memory Security","description":"Memory security is one of the most important aspects in today\'s computer systems.","sidebar":"sidebar"},"Lab/Data/overview":{"id":"Lab/Data/overview","title":"Data","description":"Data represents information that is to be processed to produce a final result or more data.","sidebar":"sidebar"},"Lab/Data/process-memory":{"id":"Lab/Data/process-memory","title":"Process Memory","description":"Memory Regions","sidebar":"sidebar"},"Lab/Data/quiz/bypass-canary":{"id":"Lab/Data/quiz/bypass-canary","title":"Bypass Canary","description":"Question"},"Lab/Data/quiz/half-page":{"id":"Lab/Data/quiz/half-page","title":"Half Page","description":"Question Text"},"Lab/Data/quiz/malloc-brk":{"id":"Lab/Data/quiz/malloc-brk","title":"Malloc `brk()`","description":"Question Text"},"Lab/Data/quiz/malloc-mmap":{"id":"Lab/Data/quiz/malloc-mmap","title":"Malloc `mmap()`","description":"Question Text"},"Lab/Data/quiz/memory-access":{"id":"Lab/Data/quiz/memory-access","title":"Modify String","description":"Question Text"},"Lab/Data/quiz/memory-aslr":{"id":"Lab/Data/quiz/memory-aslr","title":"ASLR","description":"Question Text"},"Lab/Data/quiz/memory-granularity":{"id":"Lab/Data/quiz/memory-granularity","title":"Memory Granularity","description":"Question Text"},"Lab/Data/quiz/memory-leaks":{"id":"Lab/Data/quiz/memory-leaks","title":"Memory Leaks","description":"Question Text"},"Lab/Data/quiz/memory-regions-vars":{"id":"Lab/Data/quiz/memory-regions-vars","title":"Variables in memory regions","description":"Question Text"},"Lab/Data/quiz/memory-stack-protector":{"id":"Lab/Data/quiz/memory-stack-protector","title":"Stack Protector","description":"Question Text"},"Lab/Data/quiz/mmap-file":{"id":"Lab/Data/quiz/mmap-file","title":"`mmap()` file","description":"Question Text"},"Lab/Data/quiz/operators":{"id":"Lab/Data/quiz/operators","title":"Operator Overloading","description":"Question Text"},"Lab/Data/quiz/page-allocation":{"id":"Lab/Data/quiz/page-allocation","title":"Page Allocation","description":"Question Text"},"Lab/Data/quiz/stack-layout":{"id":"Lab/Data/quiz/stack-layout","title":"Stack layout","description":"Question Text"},"Lab/Data/quiz/string-buff-over":{"id":"Lab/Data/quiz/string-buff-over","title":"String Buffer Overflow","description":"Question Text"},"Lab/Data/quiz/string-strcpy":{"id":"Lab/Data/quiz/string-strcpy","title":"Strcpy Buffer Overflow","description":"Question Text"},"Lab/Data/quiz/valgrind-leaks":{"id":"Lab/Data/quiz/valgrind-leaks","title":"Valgrind Leaks","description":"Question Text"},"Lab/Data/working-memory":{"id":"Lab/Data/working-memory","title":"Working with Memory","description":"As previously stated, from a programmer\'s perspective, memory is abstracted into variables.","sidebar":"sidebar"},"Lab/IO/arena":{"id":"Lab/IO/arena","title":"Arena","description":"Open File Structure in the Kernel","sidebar":"sidebar"},"Lab/IO/async-io":{"id":"Lab/IO/async-io","title":"Asynchronous I/O","description":"When doing I/O, the major issue we are facing is that I/O operations are typically much slower than CPU operations.","sidebar":"sidebar"},"Lab/IO/beyond-network-sockets":{"id":"Lab/IO/beyond-network-sockets","title":"Beyond Network Sockets","description":"Up until this point, we first learned how to use the Berkeley Sockets API, then we learned about the client-server model, based on this API.","sidebar":"sidebar"},"Lab/IO/client-server-model":{"id":"Lab/IO/client-server-model","title":"Client-Server Model","description":"Up to now, we\'ve avoided code snippets using TCP.","sidebar":"sidebar"},"Lab/IO/file-descriptors":{"id":"Lab/IO/file-descriptors","title":"File Descriptors","description":"After running the code in the \\"File Handlers\\" section, you saw that open() returns a number.","sidebar":"sidebar"},"Lab/IO/file-handlers":{"id":"Lab/IO/file-handlers","title":"File Handling","description":"You\'ve most likely had to deal with files in the past.","sidebar":"sidebar"},"Lab/IO/file-mappings":{"id":"Lab/IO/file-mappings","title":"File Mappings","description":"Mapping a file to the VAS of a process is similar to how shared libraries are loaded into the same VAS.","sidebar":"sidebar"},"Lab/IO/io-internals":{"id":"Lab/IO/io-internals","title":"I/O Internals","description":"Now, we will take a short look at how the file descriptors you\'ve just learnt about are handled in libc.","sidebar":"sidebar"},"Lab/IO/io-multiplexing":{"id":"Lab/IO/io-multiplexing","title":"I/O Multiplexing","description":"I/O multiplexing is the ability to serve multiple I/O channels (or anything that can be referenced via a file descriptor / handle) simultaneously.","sidebar":"sidebar"},"Lab/IO/local-io-in-action":{"id":"Lab/IO/local-io-in-action","title":"Local I/O in Action","description":"Most of the time, file handling is a simple operation from the perspective of the application.","sidebar":"sidebar"},"Lab/IO/networking-101":{"id":"Lab/IO/networking-101","title":"Networking 101","description":"In this section, we will briefly explore how networking works in general, from the perspective of the application.","sidebar":"sidebar"},"Lab/IO/overview":{"id":"Lab/IO/overview","title":"I/O","description":"We know that a compute system is a collection of hardware and software that modifies data.","sidebar":"sidebar"},"Lab/IO/pipes":{"id":"Lab/IO/pipes","title":"Pipes","description":"When it comes to inter-process communication, so far we know that 2 different processes can mmap() the same file and use that as some sort of shared memory, but this requires writing data to the disk which is slow.","sidebar":"sidebar"},"Lab/IO/quiz/anonymous-pipes-limitation":{"id":"Lab/IO/quiz/anonymous-pipes-limitation","title":"Limitation of Anonymous Pipes","description":"Question Text"},"Lab/IO/quiz/bind-error-cause":{"id":"Lab/IO/quiz/bind-error-cause","title":"Cause of `bind()` Error","description":"Question Text"},"Lab/IO/quiz/client-server-sender-receiver":{"id":"Lab/IO/quiz/client-server-sender-receiver","title":"`sender.py` and `receiver.py` Client-Server Parallel","description":"Question Text"},"Lab/IO/quiz/deluge-tcp-udp":{"id":"Lab/IO/quiz/deluge-tcp-udp","title":"Deluge: TCP or UDP","description":"Question Text"},"Lab/IO/quiz/execve":{"id":"Lab/IO/quiz/execve","title":"Effect of `execve()` Syscall","description":"Question Text"},"Lab/IO/quiz/fewer-than-2-copies":{"id":"Lab/IO/quiz/fewer-than-2-copies","title":"Fewer than Two Copies","description":"Question Text"},"Lab/IO/quiz/file-handler-c":{"id":"Lab/IO/quiz/file-handler-c","title":"File handler in C","description":"Question Text"},"Lab/IO/quiz/firefox-tcp-udp":{"id":"Lab/IO/quiz/firefox-tcp-udp","title":"Firefox: TCP or UDP?","description":"Question Text"},"Lab/IO/quiz/flush-libc-buffer":{"id":"Lab/IO/quiz/flush-libc-buffer","title":"Flush Libc Buffer","description":"Question Text"},"Lab/IO/quiz/fopen-syscall":{"id":"Lab/IO/quiz/fopen-syscall","title":"Syscall Used by `fopen()`","description":"Question Text"},"Lab/IO/quiz/fopen-w":{"id":"Lab/IO/quiz/fopen-w","title":"open()` equivalent of `fopen(..., \\"w\\")","description":"Question Text"},"Lab/IO/quiz/local-io-errors":{"id":"Lab/IO/quiz/local-io-errors","title":"I/O Errors","description":"Question Text"},"Lab/IO/quiz/mmap-read-write-benchmark":{"id":"Lab/IO/quiz/mmap-read-write-benchmark","title":"`mmap()` vs `read()` and `write()` Benchmark","description":"Question Text"},"Lab/IO/quiz/o-trunc":{"id":"Lab/IO/quiz/o-trunc","title":"`O_TRUNC` Flag Behaviour","description":"Question Text"},"Lab/IO/quiz/pipe-ends":{"id":"Lab/IO/quiz/pipe-ends","title":"Pipe Ends","description":"Question Text"},"Lab/IO/quiz/prints-work-no-stdio":{"id":"Lab/IO/quiz/prints-work-no-stdio","title":"Prints Working after Closing `stdio`","description":"Question Text"},"Lab/IO/quiz/receiver-socket-fd":{"id":"Lab/IO/quiz/receiver-socket-fd","title":"Receiver Socked File Descriptor","description":"Question Text"},"Lab/IO/quiz/server-copies":{"id":"Lab/IO/quiz/server-copies","title":"Client-Server Number of Copies","description":"Question Text"},"Lab/IO/quiz/stderr-fd":{"id":"Lab/IO/quiz/stderr-fd","title":"File Descriptor of `stderr`","description":"Question Text"},"Lab/IO/quiz/strace-printf":{"id":"Lab/IO/quiz/strace-printf","title":"`printf()` Under Strace","description":"Question Text"},"Lab/IO/quiz/syscalls-cp":{"id":"Lab/IO/quiz/syscalls-cp","title":"Syscalls Used by `cp`","description":"Question Text"},"Lab/IO/quiz/write-file-permissions":{"id":"Lab/IO/quiz/write-file-permissions","title":"`write_file.txt` Permissions","description":"Question Text"},"Lab/IO/redirections":{"id":"Lab/IO/redirections","title":"Redirections","description":"In the File Descriptors section, we mentioned redirections such as ls > file.txt.","sidebar":"sidebar"},"Lab/IO/remote-io":{"id":"Lab/IO/remote-io","title":"Remote I/O","description":"In the previous sections, we started looking into how applications interact with the outside world.","sidebar":"sidebar"},"Lab/IO/zero-copy":{"id":"Lab/IO/zero-copy","title":"Zero-Copy","description":"Imagine a server that responds with files that it stores locally.","sidebar":"sidebar"},"Lab/lab-setup":{"id":"Lab/lab-setup","title":"Setting up the Lab Environment","description":"If you have already cloned the repository, make sure it is updated:","sidebar":"sidebar"},"Lab/Software Stack/app-investigate":{"id":"Lab/Software Stack/app-investigate","title":"App Investigation","description":"Let\'s spend some time investigating actual applications residing on the local system.","sidebar":"sidebar"},"Lab/Software Stack/arena":{"id":"Lab/Software Stack/arena","title":"Arena","description":"Go through the practice items below to hone your skills in working with layers of the software stack.","sidebar":"sidebar"},"Lab/Software Stack/basic-syscall":{"id":"Lab/Software Stack/basic-syscall","title":"Analyzing the Software Stack","description":"To get a better grasp on how the software stack works, let\'s do a bottom-up approach:","sidebar":"sidebar"},"Lab/Software Stack/common-functions":{"id":"Lab/Software Stack/common-functions","title":"Common Functions","description":"By using wrapper calls, we are able to write our programs in C.","sidebar":"sidebar"},"Lab/Software Stack/high-level-lang":{"id":"Lab/Software Stack/high-level-lang","title":"High-Level Languages","description":"Using the standard C library (libc) frees the programmer from the cumbersome steps of invoking system calls and reimplementing common features.","sidebar":"sidebar"},"Lab/Software Stack/libc":{"id":"Lab/Software Stack/libc","title":"Libraries and libc","description":"Once we have common functions implemented, we can reuse them at any time.","sidebar":"sidebar"},"Lab/Software Stack/libcall-syscall":{"id":"Lab/Software Stack/libcall-syscall","title":"Library calls vs system calls","description":"The standard C library has primarily two uses:","sidebar":"sidebar"},"Lab/Software Stack/modern-sw-stack":{"id":"Lab/Software Stack/modern-sw-stack","title":"Modern Software Stacks","description":"Most modern computing systems use a software stack such as the one in the figure below:","sidebar":"sidebar"},"Lab/Software Stack/overview":{"id":"Lab/Software Stack/overview","title":"Software Stack","description":"Software comprises of code and data that is loaded in memory and used by the CPU.","sidebar":"sidebar"},"Lab/Software Stack/quiz/common-functions":{"id":"Lab/Software Stack/quiz/common-functions","title":"Common Functions","description":"printf() System Call"},"Lab/Software Stack/quiz/high-level-lang":{"id":"Lab/Software Stack/quiz/high-level-lang","title":"Python Tools","description":"Question Text"},"Lab/Software Stack/quiz/libc":{"id":"Lab/Software Stack/quiz/libc","title":"libc","description":"malloc()"},"Lab/Software Stack/quiz/libcall-syscall":{"id":"Lab/Software Stack/quiz/libcall-syscall","title":"Libcall with Syscall","description":"Question Text"},"Lab/Software Stack/quiz/libs":{"id":"Lab/Software Stack/quiz/libs","title":"libs","description":"Static Executables"},"Lab/Software Stack/quiz/software":{"id":"Lab/Software Stack/quiz/software","title":"Software Properties","description":"Question Text"},"Lab/Software Stack/quiz/syscall-wrapper":{"id":"Lab/Software Stack/quiz/syscall-wrapper","title":"Syscall Wrappers","description":"Question Text"},"Lab/Software Stack/quiz/syscalls":{"id":"Lab/Software Stack/quiz/syscalls","title":"Syscalls","description":"Syscall ID"},"Lab/Software Stack/static-dynamic":{"id":"Lab/Software Stack/static-dynamic","title":"Statically-linked and Dynamically-linked Libraries","description":"Libraries can be statically-linked or dynamically-linked, creating statically-linked executables and dynamically-linked executables.","sidebar":"sidebar"},"Lab/Software Stack/syscall-wrapper":{"id":"Lab/Software Stack/syscall-wrapper","title":"System Call Wrappers","description":"The support/syscall-wrapper/ folder stores the implementation of a simple program written in C (main.c) that calls the write() and exit() functions.","sidebar":"sidebar"},"Lecture/Application-Interaction":{"id":"Lecture/Application-Interaction","title":"Application-Interaction","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/Compute":{"id":"Lecture/Compute","title":"Compute","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/Data":{"id":"Lecture/Data","title":"Data","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/IO":{"id":"Lecture/IO","title":"IO","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/Software-Stack":{"id":"Lecture/Software-Stack","title":"Software-Stack","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"README":{"id":"README","title":"Intro","description":"This is a landing page for your course.","sidebar":"sidebar"},"resources":{"id":"resources","title":"Resources and Useful Links","description":"Need to Know","sidebar":"sidebar"},"rules-and-grading":{"id":"rules-and-grading","title":"Rules and Grading","description":"Grading","sidebar":"sidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.f48ac3b3.js b/assets/js/935f2afb.f48ac3b3.js new file mode 100644 index 0000000000..9dad4ec2f6 --- /dev/null +++ b/assets/js/935f2afb.f48ac3b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkso=self.webpackChunkso||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"sidebar":[{"type":"link","label":"Introduction","href":"/operating-systems/","docId":"README"},{"type":"category","label":"Lecture","items":[{"type":"link","label":"Software Stack","href":"/operating-systems/Lecture/Software-Stack","docId":"Lecture/Software-Stack"},{"type":"link","label":"Data","href":"/operating-systems/Lecture/Data","docId":"Lecture/Data"},{"type":"link","label":"Compute","href":"/operating-systems/Lecture/Compute","docId":"Lecture/Compute"},{"type":"link","label":"IO","href":"/operating-systems/Lecture/IO","docId":"Lecture/IO"},{"type":"link","label":"Application Interaction","href":"/operating-systems/Lecture/Application-Interaction","docId":"Lecture/Application-Interaction"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lecture/"},{"type":"category","label":"Lab","items":[{"type":"link","label":"Setting up the Lab Environment","href":"/operating-systems/Lab/lab-setup","docId":"Lab/lab-setup"},{"type":"category","label":"Software Stack","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Software Stack/overview","docId":"Lab/Software Stack/overview"},{"type":"link","label":"Modern Software Stacks","href":"/operating-systems/Lab/Software Stack/modern-sw-stack","docId":"Lab/Software Stack/modern-sw-stack"},{"type":"link","label":"Basic System Calls","href":"/operating-systems/Lab/Software Stack/basic-syscall","docId":"Lab/Software Stack/basic-syscall"},{"type":"link","label":"System Call Wrapper","href":"/operating-systems/Lab/Software Stack/syscall-wrapper","docId":"Lab/Software Stack/syscall-wrapper"},{"type":"link","label":"Common Functions","href":"/operating-systems/Lab/Software Stack/common-functions","docId":"Lab/Software Stack/common-functions"},{"type":"link","label":"Libc","href":"/operating-systems/Lab/Software Stack/libc","docId":"Lab/Software Stack/libc"},{"type":"link","label":"Static-dynamic","href":"/operating-systems/Lab/Software Stack/static-dynamic","docId":"Lab/Software Stack/static-dynamic"},{"type":"link","label":"Libcall-Syscall","href":"/operating-systems/Lab/Software Stack/libcall-syscall","docId":"Lab/Software Stack/libcall-syscall"},{"type":"link","label":"High-Level Languages","href":"/operating-systems/Lab/Software Stack/high-level-lang","docId":"Lab/Software Stack/high-level-lang"},{"type":"link","label":"App Investigation","href":"/operating-systems/Lab/Software Stack/app-investigate","docId":"Lab/Software Stack/app-investigate"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Software Stack/arena","docId":"Lab/Software Stack/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Software Stack/"},{"type":"category","label":"Data","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Data/overview","docId":"Lab/Data/overview"},{"type":"link","label":"Working with Memory","href":"/operating-systems/Lab/Data/working-memory","docId":"Lab/Data/working-memory"},{"type":"link","label":"Process Memory","href":"/operating-systems/Lab/Data/process-memory","docId":"Lab/Data/process-memory"},{"type":"link","label":"Investigate Memory","href":"/operating-systems/Lab/Data/investigate-memory","docId":"Lab/Data/investigate-memory"},{"type":"link","label":"Memory Security","href":"/operating-systems/Lab/Data/memory-security","docId":"Lab/Data/memory-security"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Data/arena","docId":"Lab/Data/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Data/"},{"type":"category","label":"Compute","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Compute/overview","docId":"Lab/Compute/overview"},{"type":"link","label":"Hardware Perspective","href":"/operating-systems/Lab/Compute/hardware-perspective","docId":"Lab/Compute/hardware-perspective"},{"type":"link","label":"Processes","href":"/operating-systems/Lab/Compute/processes","docId":"Lab/Compute/processes"},{"type":"link","label":"Threads","href":"/operating-systems/Lab/Compute/threads","docId":"Lab/Compute/threads"},{"type":"link","label":"Processes-threads-apache2","href":"/operating-systems/Lab/Compute/processes-threads-apache2","docId":"Lab/Compute/processes-threads-apache2"},{"type":"link","label":"Copy-on-Write","href":"/operating-systems/Lab/Compute/copy-on-write","docId":"Lab/Compute/copy-on-write"},{"type":"link","label":"Synchronization","href":"/operating-systems/Lab/Compute/synchronization","docId":"Lab/Compute/synchronization"},{"type":"link","label":"User-Level Threads","href":"/operating-systems/Lab/Compute/user-level-threads","docId":"Lab/Compute/user-level-threads"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Compute/arena","docId":"Lab/Compute/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Compute/"},{"type":"category","label":"IO","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/IO/overview","docId":"Lab/IO/overview"},{"type":"link","label":"File Handlers","href":"/operating-systems/Lab/IO/file-handlers","docId":"Lab/IO/file-handlers"},{"type":"link","label":"File Descriptors","href":"/operating-systems/Lab/IO/file-descriptors","docId":"Lab/IO/file-descriptors"},{"type":"link","label":"Redirections","href":"/operating-systems/Lab/IO/redirections","docId":"Lab/IO/redirections"},{"type":"link","label":"Pipes","href":"/operating-systems/Lab/IO/pipes","docId":"Lab/IO/pipes"},{"type":"link","label":"Local IO in Action","href":"/operating-systems/Lab/IO/local-io-in-action","docId":"Lab/IO/local-io-in-action"},{"type":"link","label":"Remote IO","href":"/operating-systems/Lab/IO/remote-io","docId":"Lab/IO/remote-io"},{"type":"link","label":"Networking 101","href":"/operating-systems/Lab/IO/networking-101","docId":"Lab/IO/networking-101"},{"type":"link","label":"Client-Server Model","href":"/operating-systems/Lab/IO/client-server-model","docId":"Lab/IO/client-server-model"},{"type":"link","label":"Beyond Network Sockets","href":"/operating-systems/Lab/IO/beyond-network-sockets","docId":"Lab/IO/beyond-network-sockets"},{"type":"link","label":"File Mappings","href":"/operating-systems/Lab/IO/file-mappings","docId":"Lab/IO/file-mappings"},{"type":"link","label":"IO Internals","href":"/operating-systems/Lab/IO/io-internals","docId":"Lab/IO/io-internals"},{"type":"link","label":"Zero-Copy","href":"/operating-systems/Lab/IO/zero-copy","docId":"Lab/IO/zero-copy"},{"type":"link","label":"Asynchronous IO","href":"/operating-systems/Lab/IO/async-io","docId":"Lab/IO/async-io"},{"type":"link","label":"IO Multiplexing","href":"/operating-systems/Lab/IO/io-multiplexing","docId":"Lab/IO/io-multiplexing"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/IO/arena","docId":"Lab/IO/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/IO/"},{"type":"category","label":"Application Interaction","items":[{"type":"link","label":"Overview","href":"/operating-systems/Lab/Application Interaction/overview","docId":"Lab/Application Interaction/overview"},{"type":"link","label":"Time Server","href":"/operating-systems/Lab/Application Interaction/time-server","docId":"Lab/Application Interaction/time-server"},{"type":"link","label":"Password Cracker","href":"/operating-systems/Lab/Application Interaction/password-cracker","docId":"Lab/Application Interaction/password-cracker"},{"type":"link","label":"The X Window System","href":"/operating-systems/Lab/Application Interaction/x-window-system","docId":"Lab/Application Interaction/x-window-system"},{"type":"link","label":"D-Bus","href":"/operating-systems/Lab/Application Interaction/dbus","docId":"Lab/Application Interaction/dbus"},{"type":"link","label":"OS Cloud","href":"/operating-systems/Lab/Application Interaction/os-cloud","docId":"Lab/Application Interaction/os-cloud"},{"type":"link","label":"Arena","href":"/operating-systems/Lab/Application Interaction/arena","docId":"Lab/Application Interaction/arena"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/Application Interaction/"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Lab/"},{"type":"category","label":"Assignments","items":[{"type":"link","label":"Mini Libc","href":"/operating-systems/Assignments/Mini Libc/","docId":"Assignments/Mini Libc/README"},{"type":"link","label":"Memory Allocator","href":"/operating-systems/Assignments/Memory Allocator/","docId":"Assignments/Memory Allocator/README"},{"type":"link","label":"Parallel Graph","href":"/operating-systems/Assignments/Parallel Graph/","docId":"Assignments/Parallel Graph/README"},{"type":"link","label":"Mini Shell","href":"/operating-systems/Assignments/Mini Shell/","docId":"Assignments/Mini Shell/README"},{"type":"link","label":"Asynchronous Web Server","href":"/operating-systems/Assignments/Asynchronous Web Server/","docId":"Assignments/Asynchronous Web Server/README"}],"collapsed":true,"collapsible":true,"href":"/operating-systems/Assignments/"},{"type":"link","label":"Rules and Grading","href":"/operating-systems/rules-and-grading","docId":"rules-and-grading"},{"type":"link","label":"Resources","href":"/operating-systems/resources","docId":"resources"}]},"docs":{"Assignments/Asynchronous Web Server/README":{"id":"Assignments/Asynchronous Web Server/README","title":"Asynchronous Web Server","description":"Objectives","sidebar":"sidebar"},"Assignments/Asynchronous Web Server/src/http-parser/README":{"id":"Assignments/Asynchronous Web Server/src/http-parser/README","title":"HTTP Parser","description":"This is a parser for HTTP messages written in C. It parses both requests and"},"Assignments/Memory Allocator/README":{"id":"Assignments/Memory Allocator/README","title":"Memory Allocator","description":"Objectives","sidebar":"sidebar"},"Assignments/Mini Libc/README":{"id":"Assignments/Mini Libc/README","title":"Mini-libc","description":"Objectives","sidebar":"sidebar"},"Assignments/Mini Shell/README":{"id":"Assignments/Mini Shell/README","title":"Minishell","description":"Objectives","sidebar":"sidebar"},"Assignments/Mini Shell/util/parser/README":{"id":"Assignments/Mini Shell/util/parser/README","title":"Parser","description":"The parser is made using Bison and Flex."},"Assignments/Parallel Graph/README":{"id":"Assignments/Parallel Graph/README","title":"Parallel Graph","description":"Objectives","sidebar":"sidebar"},"Lab/Application Interaction/arena":{"id":"Lab/Application Interaction/arena","title":"Arena","description":"Oneko","sidebar":"sidebar"},"Lab/Application Interaction/dbus":{"id":"Lab/Application Interaction/dbus","title":"D-Bus","description":"D-Bus is an Inter-Process Communication (IPC) mechanism that is commonly present on Linux.","sidebar":"sidebar"},"Lab/Application Interaction/os-cloud":{"id":"Lab/Application Interaction/os-cloud","title":"OS Cloud","description":"In this section, we are going to build a \\"toy cloud\\" called OS Cloud.","sidebar":"sidebar"},"Lab/Application Interaction/overview":{"id":"Lab/Application Interaction/overview","title":"Application Interaction","description":"In this chapter, you will discover various mechanisms through which applications on a system can interact.","sidebar":"sidebar"},"Lab/Application Interaction/password-cracker":{"id":"Lab/Application Interaction/password-cracker","title":"Password Cracker","description":"In this example, we will solve the following problem: given the sha512 hash of a password, we want to obtain the password that generated the hash.","sidebar":"sidebar"},"Lab/Application Interaction/quiz/cgroups-vs-namespaces":{"id":"Lab/Application Interaction/quiz/cgroups-vs-namespaces","title":"Cgroups versus namespaces","description":"Question Text"},"Lab/Application Interaction/quiz/container-vs-vm":{"id":"Lab/Application Interaction/quiz/container-vs-vm","title":"Container versus VM","description":"Question Text"},"Lab/Application Interaction/quiz/time-server":{"id":"Lab/Application Interaction/quiz/time-server","title":"Time Server Protocol","description":"Question Text"},"Lab/Application Interaction/quiz/time-server-interop":{"id":"Lab/Application Interaction/quiz/time-server-interop","title":"Time Server Interoperability","description":"Question Text"},"Lab/Application Interaction/quiz/timer":{"id":"Lab/Application Interaction/quiz/timer","title":"Oneko Timer","description":"Question Text"},"Lab/Application Interaction/quiz/vm-creation":{"id":"Lab/Application Interaction/quiz/vm-creation","title":"VM Creation","description":"Question Text"},"Lab/Application Interaction/time-server":{"id":"Lab/Application Interaction/time-server","title":"Time Server","description":"Check out the code in support/time-server/server.c and support/time-server/client.c.","sidebar":"sidebar"},"Lab/Application Interaction/x-window-system":{"id":"Lab/Application Interaction/x-window-system","title":"The X Window System","description":"Unix-like systems that support a Graphical User Interface usually do this through the X Window System.","sidebar":"sidebar"},"Lab/Compute/arena":{"id":"Lab/Compute/arena","title":"Arena","description":"Threads and Processes: clone","sidebar":"sidebar"},"Lab/Compute/copy-on-write":{"id":"Lab/Compute/copy-on-write","title":"Copy-on-Write","description":"So far, you know that the parent and child process have separate virtual address spaces.","sidebar":"sidebar"},"Lab/Compute/hardware-perspective":{"id":"Lab/Compute/hardware-perspective","title":"Hardware Perspective","description":"The main criterion we use to rank CPUs is their computation power, i.e. their ability to crunch numbers and do math.","sidebar":"sidebar"},"Lab/Compute/overview":{"id":"Lab/Compute/overview","title":"Compute","description":"Contents","sidebar":"sidebar"},"Lab/Compute/processes":{"id":"Lab/Compute/processes","title":"Processes","description":"A process is simply a running program.","sidebar":"sidebar"},"Lab/Compute/processes-threads-apache2":{"id":"Lab/Compute/processes-threads-apache2","title":"Usage of Processes and Threads in `apache2`","description":"We\'ll take a look at how a real-world application - the apache2 HTTP server - makes use of processes and threads.","sidebar":"sidebar"},"Lab/Compute/quiz/apache2-strace":{"id":"Lab/Compute/quiz/apache2-strace","title":"`apache2` Document Root","description":"Question Text"},"Lab/Compute/quiz/cause-of-file-not-found-error":{"id":"Lab/Compute/quiz/cause-of-file-not-found-error","title":"Cause of `FileNotFoundError`","description":"Question Text"},"Lab/Compute/quiz/child-faults-after-write":{"id":"Lab/Compute/quiz/child-faults-after-write","title":"Child Faults After Write","description":"Question Text"},"Lab/Compute/quiz/coarse-vs-granular-critical-section":{"id":"Lab/Compute/quiz/coarse-vs-granular-critical-section","title":"Coarse vs Granular Critical Section","description":"Question Text"},"Lab/Compute/quiz/create-sleepy-process-ending":{"id":"Lab/Compute/quiz/create-sleepy-process-ending","title":"`create_sleepy` Process Ending","description":"Question Text"},"Lab/Compute/quiz/fiber-strace":{"id":"Lab/Compute/quiz/fiber-strace","title":"Fiber Strace","description":"Question Text"},"Lab/Compute/quiz/mini-shell-stops-after-command":{"id":"Lab/Compute/quiz/mini-shell-stops-after-command","title":"Mini-shell Stops After Command","description":"Question Text"},"Lab/Compute/quiz/mmap-cow-flag":{"id":"Lab/Compute/quiz/mmap-cow-flag","title":"Copy-on-write Flag for `mmap()`","description":"Question Text"},"Lab/Compute/quiz/notify-only-with-mutex":{"id":"Lab/Compute/quiz/notify-only-with-mutex","title":"Both Condition and Mutex","description":"Question Text"},"Lab/Compute/quiz/number-of-running-ults":{"id":"Lab/Compute/quiz/number-of-running-ults","title":"Number of RUNNING User-Level Threads","description":"Question Text"},"Lab/Compute/quiz/parent-faults-before-fork":{"id":"Lab/Compute/quiz/parent-faults-before-fork","title":"Parent Faults before `fork()`","description":"Question Text"},"Lab/Compute/quiz/parent-of-sleep-processes":{"id":"Lab/Compute/quiz/parent-of-sleep-processes","title":"Parent of `sleep` Processes","description":"Question Text"},"Lab/Compute/quiz/processes-speedup":{"id":"Lab/Compute/quiz/processes-speedup","title":"Processes Speedup","description":"Question Text"},"Lab/Compute/quiz/seg-fault-exit-code":{"id":"Lab/Compute/quiz/seg-fault-exit-code","title":"Seg Fault Exit Code","description":"Question Text"},"Lab/Compute/quiz/semaphore-equivalent":{"id":"Lab/Compute/quiz/semaphore-equivalent","title":"Semaphore Equivalent","description":"Question Text"},"Lab/Compute/quiz/sleeping-on-a-fiber":{"id":"Lab/Compute/quiz/sleeping-on-a-fiber","title":"Sleeping on a Fiber","description":"Question Text"},"Lab/Compute/quiz/state-of-new-ult":{"id":"Lab/Compute/quiz/state-of-new-ult","title":"State of new ULT","description":"Question Text"},"Lab/Compute/quiz/tcb-libult-unikraft":{"id":"Lab/Compute/quiz/tcb-libult-unikraft","title":"Similarities Between the TCBs of `libult` and Unikraft","description":"Question Text"},"Lab/Compute/quiz/thread-memory":{"id":"Lab/Compute/quiz/thread-memory","title":"Thread Memory","description":"Question Text"},"Lab/Compute/quiz/time-slice-value":{"id":"Lab/Compute/quiz/time-slice-value","title":"Time Slice Value","description":"Question Text"},"Lab/Compute/quiz/tls-synchronization":{"id":"Lab/Compute/quiz/tls-synchronization","title":"TLS Synchronization","description":"Question Text"},"Lab/Compute/quiz/tls-var-copies":{"id":"Lab/Compute/quiz/tls-var-copies","title":"TLS `var` Copies","description":"Question Text"},"Lab/Compute/quiz/type-of-scheduler-in-libult":{"id":"Lab/Compute/quiz/type-of-scheduler-in-libult","title":"Type of Scheduler in `libult.so`","description":"Question Text"},"Lab/Compute/quiz/ult-thread-ids":{"id":"Lab/Compute/quiz/ult-thread-ids","title":"ULT Thread IDs","description":"Question Text"},"Lab/Compute/quiz/who-calls-execve-parent":{"id":"Lab/Compute/quiz/who-calls-execve-parent","title":"Who Calls `execve` in the Log of the Parent Process?","description":"Question Text"},"Lab/Compute/quiz/why-use-completed-queue":{"id":"Lab/Compute/quiz/why-use-completed-queue","title":"The Need for a COMPLETED Queue","description":"Question Text"},"Lab/Compute/synchronization":{"id":"Lab/Compute/synchronization","title":"Synchronization","description":"So far, we\'ve used threads and processes without wondering how to \\"tell\\" them how to access shared data.","sidebar":"sidebar"},"Lab/Compute/threads":{"id":"Lab/Compute/threads","title":"Threads","description":"Spreading the Work Among Other Threads","sidebar":"sidebar"},"Lab/Compute/user-level-threads":{"id":"Lab/Compute/user-level-threads","title":"User-Level Threads","description":"User-level threads differ from the threads you are used to (kernel-level threads, those created by pthread_create).","sidebar":"sidebar"},"Lab/Data/arena":{"id":"Lab/Data/arena","title":"Arena","description":"Go through the practice items below to hone your skills in working with data and memory.","sidebar":"sidebar"},"Lab/Data/investigate-memory":{"id":"Lab/Data/investigate-memory","title":"Investigate Memory Actions","description":"Memory actions generally mean:","sidebar":"sidebar"},"Lab/Data/memory-security":{"id":"Lab/Data/memory-security","title":"Memory Security","description":"Memory security is one of the most important aspects in today\'s computer systems.","sidebar":"sidebar"},"Lab/Data/overview":{"id":"Lab/Data/overview","title":"Data","description":"Data represents information that is to be processed to produce a final result or more data.","sidebar":"sidebar"},"Lab/Data/process-memory":{"id":"Lab/Data/process-memory","title":"Process Memory","description":"Memory Regions","sidebar":"sidebar"},"Lab/Data/quiz/bypass-canary":{"id":"Lab/Data/quiz/bypass-canary","title":"Bypass Canary","description":"Question"},"Lab/Data/quiz/half-page":{"id":"Lab/Data/quiz/half-page","title":"Half Page","description":"Question Text"},"Lab/Data/quiz/malloc-brk":{"id":"Lab/Data/quiz/malloc-brk","title":"Malloc `brk()`","description":"Question Text"},"Lab/Data/quiz/malloc-mmap":{"id":"Lab/Data/quiz/malloc-mmap","title":"Malloc `mmap()`","description":"Question Text"},"Lab/Data/quiz/memory-access":{"id":"Lab/Data/quiz/memory-access","title":"Modify String","description":"Question Text"},"Lab/Data/quiz/memory-aslr":{"id":"Lab/Data/quiz/memory-aslr","title":"ASLR","description":"Question Text"},"Lab/Data/quiz/memory-granularity":{"id":"Lab/Data/quiz/memory-granularity","title":"Memory Granularity","description":"Question Text"},"Lab/Data/quiz/memory-leaks":{"id":"Lab/Data/quiz/memory-leaks","title":"Memory Leaks","description":"Question Text"},"Lab/Data/quiz/memory-regions-vars":{"id":"Lab/Data/quiz/memory-regions-vars","title":"Variables in memory regions","description":"Question Text"},"Lab/Data/quiz/memory-stack-protector":{"id":"Lab/Data/quiz/memory-stack-protector","title":"Stack Protector","description":"Question Text"},"Lab/Data/quiz/mmap-file":{"id":"Lab/Data/quiz/mmap-file","title":"`mmap()` file","description":"Question Text"},"Lab/Data/quiz/operators":{"id":"Lab/Data/quiz/operators","title":"Operator Overloading","description":"Question Text"},"Lab/Data/quiz/page-allocation":{"id":"Lab/Data/quiz/page-allocation","title":"Page Allocation","description":"Question Text"},"Lab/Data/quiz/stack-layout":{"id":"Lab/Data/quiz/stack-layout","title":"Stack layout","description":"Question Text"},"Lab/Data/quiz/string-buff-over":{"id":"Lab/Data/quiz/string-buff-over","title":"String Buffer Overflow","description":"Question Text"},"Lab/Data/quiz/string-strcpy":{"id":"Lab/Data/quiz/string-strcpy","title":"Strcpy Buffer Overflow","description":"Question Text"},"Lab/Data/quiz/valgrind-leaks":{"id":"Lab/Data/quiz/valgrind-leaks","title":"Valgrind Leaks","description":"Question Text"},"Lab/Data/working-memory":{"id":"Lab/Data/working-memory","title":"Working with Memory","description":"As previously stated, from a programmer\'s perspective, memory is abstracted into variables.","sidebar":"sidebar"},"Lab/IO/arena":{"id":"Lab/IO/arena","title":"Arena","description":"Open File Structure in the Kernel","sidebar":"sidebar"},"Lab/IO/async-io":{"id":"Lab/IO/async-io","title":"Asynchronous I/O","description":"When doing I/O, the major issue we are facing is that I/O operations are typically much slower than CPU operations.","sidebar":"sidebar"},"Lab/IO/beyond-network-sockets":{"id":"Lab/IO/beyond-network-sockets","title":"Beyond Network Sockets","description":"Up until this point, we first learned how to use the Berkeley Sockets API, then we learned about the client-server model, based on this API.","sidebar":"sidebar"},"Lab/IO/client-server-model":{"id":"Lab/IO/client-server-model","title":"Client-Server Model","description":"Up to now, we\'ve avoided code snippets using TCP.","sidebar":"sidebar"},"Lab/IO/file-descriptors":{"id":"Lab/IO/file-descriptors","title":"File Descriptors","description":"After running the code in the \\"File Handlers\\" section, you saw that open() returns a number.","sidebar":"sidebar"},"Lab/IO/file-handlers":{"id":"Lab/IO/file-handlers","title":"File Handling","description":"You\'ve most likely had to deal with files in the past.","sidebar":"sidebar"},"Lab/IO/file-mappings":{"id":"Lab/IO/file-mappings","title":"File Mappings","description":"Mapping a file to the VAS of a process is similar to how shared libraries are loaded into the same VAS.","sidebar":"sidebar"},"Lab/IO/io-internals":{"id":"Lab/IO/io-internals","title":"I/O Internals","description":"Now, we will take a short look at how the file descriptors you\'ve just learnt about are handled in libc.","sidebar":"sidebar"},"Lab/IO/io-multiplexing":{"id":"Lab/IO/io-multiplexing","title":"I/O Multiplexing","description":"I/O multiplexing is the ability to serve multiple I/O channels (or anything that can be referenced via a file descriptor / handle) simultaneously.","sidebar":"sidebar"},"Lab/IO/local-io-in-action":{"id":"Lab/IO/local-io-in-action","title":"Local I/O in Action","description":"Most of the time, file handling is a simple operation from the perspective of the application.","sidebar":"sidebar"},"Lab/IO/networking-101":{"id":"Lab/IO/networking-101","title":"Networking 101","description":"In this section, we will briefly explore how networking works in general, from the perspective of the application.","sidebar":"sidebar"},"Lab/IO/overview":{"id":"Lab/IO/overview","title":"I/O","description":"We know that a compute system is a collection of hardware and software that modifies data.","sidebar":"sidebar"},"Lab/IO/pipes":{"id":"Lab/IO/pipes","title":"Pipes","description":"When it comes to inter-process communication, so far we know that 2 different processes can mmap() the same file and use that as some sort of shared memory, but this requires writing data to the disk which is slow.","sidebar":"sidebar"},"Lab/IO/quiz/anonymous-pipes-limitation":{"id":"Lab/IO/quiz/anonymous-pipes-limitation","title":"Limitation of Anonymous Pipes","description":"Question Text"},"Lab/IO/quiz/bind-error-cause":{"id":"Lab/IO/quiz/bind-error-cause","title":"Cause of `bind()` Error","description":"Question Text"},"Lab/IO/quiz/client-server-sender-receiver":{"id":"Lab/IO/quiz/client-server-sender-receiver","title":"`sender.py` and `receiver.py` Client-Server Parallel","description":"Question Text"},"Lab/IO/quiz/deluge-tcp-udp":{"id":"Lab/IO/quiz/deluge-tcp-udp","title":"Deluge: TCP or UDP","description":"Question Text"},"Lab/IO/quiz/execve":{"id":"Lab/IO/quiz/execve","title":"Effect of `execve()` Syscall","description":"Question Text"},"Lab/IO/quiz/fewer-than-2-copies":{"id":"Lab/IO/quiz/fewer-than-2-copies","title":"Fewer than Two Copies","description":"Question Text"},"Lab/IO/quiz/file-handler-c":{"id":"Lab/IO/quiz/file-handler-c","title":"File handler in C","description":"Question Text"},"Lab/IO/quiz/firefox-tcp-udp":{"id":"Lab/IO/quiz/firefox-tcp-udp","title":"Firefox: TCP or UDP?","description":"Question Text"},"Lab/IO/quiz/flush-libc-buffer":{"id":"Lab/IO/quiz/flush-libc-buffer","title":"Flush Libc Buffer","description":"Question Text"},"Lab/IO/quiz/fopen-syscall":{"id":"Lab/IO/quiz/fopen-syscall","title":"Syscall Used by `fopen()`","description":"Question Text"},"Lab/IO/quiz/fopen-w":{"id":"Lab/IO/quiz/fopen-w","title":"open()` equivalent of `fopen(..., \\"w\\")","description":"Question Text"},"Lab/IO/quiz/local-io-errors":{"id":"Lab/IO/quiz/local-io-errors","title":"I/O Errors","description":"Question Text"},"Lab/IO/quiz/mmap-read-write-benchmark":{"id":"Lab/IO/quiz/mmap-read-write-benchmark","title":"`mmap()` vs `read()` and `write()` Benchmark","description":"Question Text"},"Lab/IO/quiz/o-trunc":{"id":"Lab/IO/quiz/o-trunc","title":"`O_TRUNC` Flag Behaviour","description":"Question Text"},"Lab/IO/quiz/pipe-ends":{"id":"Lab/IO/quiz/pipe-ends","title":"Pipe Ends","description":"Question Text"},"Lab/IO/quiz/prints-work-no-stdio":{"id":"Lab/IO/quiz/prints-work-no-stdio","title":"Prints Working after Closing `stdio`","description":"Question Text"},"Lab/IO/quiz/receiver-socket-fd":{"id":"Lab/IO/quiz/receiver-socket-fd","title":"Receiver Socked File Descriptor","description":"Question Text"},"Lab/IO/quiz/server-copies":{"id":"Lab/IO/quiz/server-copies","title":"Client-Server Number of Copies","description":"Question Text"},"Lab/IO/quiz/stderr-fd":{"id":"Lab/IO/quiz/stderr-fd","title":"File Descriptor of `stderr`","description":"Question Text"},"Lab/IO/quiz/strace-printf":{"id":"Lab/IO/quiz/strace-printf","title":"`printf()` Under Strace","description":"Question Text"},"Lab/IO/quiz/syscalls-cp":{"id":"Lab/IO/quiz/syscalls-cp","title":"Syscalls Used by `cp`","description":"Question Text"},"Lab/IO/quiz/write-file-permissions":{"id":"Lab/IO/quiz/write-file-permissions","title":"`write_file.txt` Permissions","description":"Question Text"},"Lab/IO/redirections":{"id":"Lab/IO/redirections","title":"Redirections","description":"In the File Descriptors section, we mentioned redirections such as ls > file.txt.","sidebar":"sidebar"},"Lab/IO/remote-io":{"id":"Lab/IO/remote-io","title":"Remote I/O","description":"In the previous sections, we started looking into how applications interact with the outside world.","sidebar":"sidebar"},"Lab/IO/zero-copy":{"id":"Lab/IO/zero-copy","title":"Zero-Copy","description":"Imagine a server that responds with files that it stores locally.","sidebar":"sidebar"},"Lab/lab-setup":{"id":"Lab/lab-setup","title":"Setting up the Lab Environment","description":"If you have already cloned the repository, make sure it is updated:","sidebar":"sidebar"},"Lab/Software Stack/app-investigate":{"id":"Lab/Software Stack/app-investigate","title":"App Investigation","description":"Let\'s spend some time investigating actual applications residing on the local system.","sidebar":"sidebar"},"Lab/Software Stack/arena":{"id":"Lab/Software Stack/arena","title":"Arena","description":"Go through the practice items below to hone your skills in working with layers of the software stack.","sidebar":"sidebar"},"Lab/Software Stack/basic-syscall":{"id":"Lab/Software Stack/basic-syscall","title":"Analyzing the Software Stack","description":"To get a better grasp on how the software stack works, let\'s do a bottom-up approach:","sidebar":"sidebar"},"Lab/Software Stack/common-functions":{"id":"Lab/Software Stack/common-functions","title":"Common Functions","description":"By using wrapper calls, we are able to write our programs in C.","sidebar":"sidebar"},"Lab/Software Stack/high-level-lang":{"id":"Lab/Software Stack/high-level-lang","title":"High-Level Languages","description":"Using the standard C library (libc) frees the programmer from the cumbersome steps of invoking system calls and reimplementing common features.","sidebar":"sidebar"},"Lab/Software Stack/libc":{"id":"Lab/Software Stack/libc","title":"Libraries and libc","description":"Once we have common functions implemented, we can reuse them at any time.","sidebar":"sidebar"},"Lab/Software Stack/libcall-syscall":{"id":"Lab/Software Stack/libcall-syscall","title":"Library calls vs system calls","description":"The standard C library has primarily two uses:","sidebar":"sidebar"},"Lab/Software Stack/modern-sw-stack":{"id":"Lab/Software Stack/modern-sw-stack","title":"Modern Software Stacks","description":"Most modern computing systems use a software stack such as the one in the figure below:","sidebar":"sidebar"},"Lab/Software Stack/overview":{"id":"Lab/Software Stack/overview","title":"Software Stack","description":"Software comprises of code and data that is loaded in memory and used by the CPU.","sidebar":"sidebar"},"Lab/Software Stack/quiz/common-functions":{"id":"Lab/Software Stack/quiz/common-functions","title":"Common Functions","description":"printf() System Call"},"Lab/Software Stack/quiz/high-level-lang":{"id":"Lab/Software Stack/quiz/high-level-lang","title":"Python Tools","description":"Question Text"},"Lab/Software Stack/quiz/libc":{"id":"Lab/Software Stack/quiz/libc","title":"libc","description":"malloc()"},"Lab/Software Stack/quiz/libcall-syscall":{"id":"Lab/Software Stack/quiz/libcall-syscall","title":"Libcall with Syscall","description":"Question Text"},"Lab/Software Stack/quiz/libs":{"id":"Lab/Software Stack/quiz/libs","title":"libs","description":"Static Executables"},"Lab/Software Stack/quiz/software":{"id":"Lab/Software Stack/quiz/software","title":"Software Properties","description":"Question Text"},"Lab/Software Stack/quiz/syscall-wrapper":{"id":"Lab/Software Stack/quiz/syscall-wrapper","title":"Syscall Wrappers","description":"Question Text"},"Lab/Software Stack/quiz/syscalls":{"id":"Lab/Software Stack/quiz/syscalls","title":"Syscalls","description":"Syscall ID"},"Lab/Software Stack/static-dynamic":{"id":"Lab/Software Stack/static-dynamic","title":"Statically-linked and Dynamically-linked Libraries","description":"Libraries can be statically-linked or dynamically-linked, creating statically-linked executables and dynamically-linked executables.","sidebar":"sidebar"},"Lab/Software Stack/syscall-wrapper":{"id":"Lab/Software Stack/syscall-wrapper","title":"System Call Wrappers","description":"The support/syscall-wrapper/ folder stores the implementation of a simple program written in C (main.c) that calls the write() and exit() functions.","sidebar":"sidebar"},"Lecture/Application-Interaction":{"id":"Lecture/Application-Interaction","title":"Application-Interaction","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/Compute":{"id":"Lecture/Compute","title":"Compute","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/Data":{"id":"Lecture/Data","title":"Data","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/IO":{"id":"Lecture/IO","title":"IO","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"Lecture/Software-Stack":{"id":"Lecture/Software-Stack","title":"Software-Stack","description":"Focus the slides and press F for fullscreen viewing.","sidebar":"sidebar"},"README":{"id":"README","title":"Intro","description":"This is a landing page for your course.","sidebar":"sidebar"},"resources":{"id":"resources","title":"Resources and Useful Links","description":"Need to Know","sidebar":"sidebar"},"rules-and-grading":{"id":"rules-and-grading","title":"Rules and Grading","description":"Grading","sidebar":"sidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/b5c587af.ba3613c2.js b/assets/js/b5c587af.ba3613c2.js deleted file mode 100644 index 2bf311ebfa..0000000000 --- a/assets/js/b5c587af.ba3613c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkso=self.webpackChunkso||[]).push([[8028],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),h=p(n),c=r,m=h["".concat(s,".").concat(c)]||h[c]||u[c]||i;return n?a.createElement(m,l(l({ref:t},d),{},{components:n})):a.createElement(m,l({ref:t},d))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,l=new Array(i);l[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[h]="string"==typeof e?e:r,l[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var a=n(7462),r=(n(7294),n(3905));const i={},l="Parallel Graph",o={unversionedId:"Assignments/Parallel Graph/README",id:"Assignments/Parallel Graph/README",title:"Parallel Graph",description:"For this assignment we will implement a generic thread pool, which we will then use to traverse a graph and compute the sum of the elements contained by the nodes.",source:"@site/docs/Assignments/Parallel Graph/README.md",sourceDirName:"Assignments/Parallel Graph",slug:"/Assignments/Parallel Graph/",permalink:"/operating-systems/Assignments/Parallel Graph/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Memory Allocator",permalink:"/operating-systems/Assignments/Memory Allocator/"},next:{title:"Minishell",permalink:"/operating-systems/Assignments/Mini Shell/"}},s={},p=[{value:"Thread Pool Description",id:"thread-pool-description",level:2},{value:"Graph Traversal",id:"graph-traversal",level:2},{value:"Synchronization",id:"synchronization",level:2},{value:"Input Files",id:"input-files",level:2},{value:"Data Structures",id:"data-structures",level:2},{value:"Graph",id:"graph",level:3},{value:"List",id:"list",level:3},{value:"Thread pool",id:"thread-pool",level:3},{value:"Infrastructure",id:"infrastructure",level:2},{value:"Compilation",id:"compilation",level:3},{value:"Testing",id:"testing",level:3},{value:"Checker",id:"checker",level:3},{value:"Grading",id:"grading",level:2},{value:"Deployment",id:"deployment",level:2}],d={toc:p},h="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(h,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"parallel-graph"},"Parallel Graph"),(0,r.kt)("p",null,"For this assignment we will implement a generic thread pool, which we will then use to traverse a graph and compute the sum of the elements contained by the nodes.\nYou will be provided with a serial implementation of the graph traversal and with most of the data structures needed to implement the thread pool.\nYour job is to write the thread pool routines and then use the thread pool to traverse the graph."),(0,r.kt)("h2",{id:"thread-pool-description"},"Thread Pool Description"),(0,r.kt)("p",null,"A thread pool contains a given number of active threads that simply wait to be given specific tasks.\nThe threads are created when the thread pool is created they poll a task queue until a task is available.\nOnce tasks are put in the task queue, the threads start running the task.\nA thread pool creates N threads when the thread pool is created and does not destroy (join) them throughout the lifetime of the thread pool.\nThat way, the penalty of creating and destroying threads ad hoc is avoided.\nAs such, you must implement the following functions (marked with ",(0,r.kt)("inlineCode",{parentName:"p"},"TODO")," in the provided skeleton):"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"task_create"),": creates an ",(0,r.kt)("inlineCode",{parentName:"li"},"os_task_t")," that will be put in the task queue - a task consists of a function pointer and an argument."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"add_task_in_queue"),": adds a given task in the thread pool's task queue."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"get_task"),": get a task from the thread pool's task queue."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"threadpool_create"),": allocate and initialize a new thread pool."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"thread_loop_function"),": all the threads in the thread pool will execute this function - they all wait until a task is available in the task queue; once they grab a task they simply invoke the function that was provided to ",(0,r.kt)("inlineCode",{parentName:"li"},"task_create"),"."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"threadpool_stop"),": stop all the threads from execution.")),(0,r.kt)("p",null,"Notice that the thread pool is completely independent from any given application.\nAny function can be registered in the task queue."),(0,r.kt)("h2",{id:"graph-traversal"},"Graph Traversal"),(0,r.kt)("p",null,"Once you have implemented the thread pool, you need to test it by using it for computing the sum of all the nodes of a graph.\nA serial implementation for this algorithm is provided in ",(0,r.kt)("inlineCode",{parentName:"p"},"skep/serial.c"),"\nTo make use of the thread pool, you will need to create tasks that will be put in the task queue.\nA task consists of 2 steps:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"adding the current node value to the overall sum."),(0,r.kt)("li",{parentName:"ul"},"creating tasks and adding them to the task queue for the neighbouring nodes.")),(0,r.kt)("p",null,"Since the threads are polling the task queue indefinitely, you need to find a condition for the threads to stop once the graph has been traversed completely.\nThis condition should be implemented in a function that is passed to ",(0,r.kt)("inlineCode",{parentName:"p"},"threadpool_stop"),".\n",(0,r.kt)("inlineCode",{parentName:"p"},"threadpool_stop")," then needs to wait for the condition to be satisfied and then joins all the threads."),(0,r.kt)("h2",{id:"synchronization"},"Synchronization"),(0,r.kt)("p",null,"For synchronization you can use mutexes, semaphores, spinlocks, condition variables - anything that grinds your gear.\nHowever, you are not allowed to use hacks such as ",(0,r.kt)("inlineCode",{parentName:"p"},"sleep"),", ",(0,r.kt)("inlineCode",{parentName:"p"},"printf")," synchronization or adding superfluous computation."),(0,r.kt)("h2",{id:"input-files"},"Input Files"),(0,r.kt)("p",null,"Reading the graphs from the input files is being taken care of the functions implemented in ",(0,r.kt)("inlineCode",{parentName:"p"},"src/os_graph.c"),".\nA graph is represented in input files as follows:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"first line contains 2 integers N and M: N - number of nodes, M - numbed or edges"),(0,r.kt)("li",{parentName:"ul"},"second line contains N integer numbers - the values of the nodes"),(0,r.kt)("li",{parentName:"ul"},"the next M lines contain each 2 integers that represent the source and the destination of an edge")),(0,r.kt)("h2",{id:"data-structures"},"Data Structures"),(0,r.kt)("h3",{id:"graph"},"Graph"),(0,r.kt)("p",null,"A graph is represented internally as an ",(0,r.kt)("inlineCode",{parentName:"p"},"os_graph_t")," (see ",(0,r.kt)("inlineCode",{parentName:"p"},"src/os_graph.h"),")."),(0,r.kt)("h3",{id:"list"},"List"),(0,r.kt)("p",null,"A list is represented internally as an ",(0,r.kt)("inlineCode",{parentName:"p"},"os_queue_t")," (see ",(0,r.kt)("inlineCode",{parentName:"p"},"src/os_list.h"),").\nYou will use this list to implement the task queue."),(0,r.kt)("h3",{id:"thread-pool"},"Thread pool"),(0,r.kt)("p",null,"A thread pool is represented internally as an ",(0,r.kt)("inlineCode",{parentName:"p"},"os_threadpool_t")," (see ",(0,r.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.h"),")\nThe thread pool contains information about the task queue and the threads."),(0,r.kt)("p",null,"You are not allowed to modify these data structures.\nHowever, you can create other data structures that leverage these ones."),(0,r.kt)("h2",{id:"infrastructure"},"Infrastructure"),(0,r.kt)("h3",{id:"compilation"},"Compilation"),(0,r.kt)("p",null,"To compile both the serial and the parallel version, enter the ",(0,r.kt)("inlineCode",{parentName:"p"},"src/")," directory and run:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"make\n")),(0,r.kt)("p",null,"That will create the ",(0,r.kt)("inlineCode",{parentName:"p"},"serial")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"parallel")," binaries/"),(0,r.kt)("h3",{id:"testing"},"Testing"),(0,r.kt)("p",null,"Input tests cases are located in ",(0,r.kt)("inlineCode",{parentName:"p"},"tests/in/"),".\nThe parallel and the serial version should provide the same results for the same input test case."),(0,r.kt)("p",null,"If you want manually run a single test, use commands such as below while in the ",(0,r.kt)("inlineCode",{parentName:"p"},"src/")," directory:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"$./parallel ../tests/in/test5.in\n-11\n\n$ ./serial ../tests/in/test5.in\n-11\n")),(0,r.kt)("h3",{id:"checker"},"Checker"),(0,r.kt)("p",null,"The testing is automated and performed with the ",(0,r.kt)("inlineCode",{parentName:"p"},"checker.py")," script from the ",(0,r.kt)("inlineCode",{parentName:"p"},"tests/")," directory.\nIt's easiest to use the ",(0,r.kt)("inlineCode",{parentName:"p"},"Makefile")," to run the tests:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"$ make check\n[...]\nSRC_PATH=../src python checker.py\ntest1.in ....................... passed ... 4.5\ntest2.in ....................... passed ... 4.5\ntest3.in ....................... passed ... 4.5\ntest4.in ....................... passed ... 4.5\ntest5.in ....................... passed ... 4.5\ntest6.in ....................... passed ... 4.5\ntest7.in ....................... passed ... 4.5\ntest8.in ....................... passed ... 4.5\ntest9.in ....................... passed ... 4.5\ntest10.in ....................... passed ... 4.5\ntest11.in ....................... passed ... 4.5\ntest12.in ....................... passed ... 4.5\ntest13.in ....................... passed ... 4.5\ntest14.in ....................... passed ... 4.5\ntest15.in ....................... passed ... 4.5\ntest16.in ....................... passed ... 4.5\ntest17.in ....................... passed ... 4.5\ntest18.in ....................... passed ... 4.5\ntest19.in ....................... passed ... 4.5\ntest20.in ....................... passed ... 4.5\n\nTotal: 90/100\n")),(0,r.kt)("p",null,"It's recommended that you use the ",(0,r.kt)("a",{parentName:"p",href:"README.checker.md#local-checker"},"local Docker-based checker"),".\nYou would use the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-console"},"./local.sh checker\n")),(0,r.kt)("p",null,"to run the checker in a Docker-based environment that is identical to the one used for the official assignment evaluation."),(0,r.kt)("h2",{id:"grading"},"Grading"),(0,r.kt)("p",null,"The grade that the checker outputs is not the final grade.\nYour homework will be manually inspected and may suffer from penalties ranging from 1 to 100 points depending on the severity of the hack, including, but not limited to:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"using a single mutex at the beginning of the traversal"),(0,r.kt)("li",{parentName:"ul"},"not using the thread pool to solve the homework"),(0,r.kt)("li",{parentName:"ul"},"inefficient usage of synchronization"),(0,r.kt)("li",{parentName:"ul"},"incorrect graph traversal")),(0,r.kt)("h2",{id:"deployment"},"Deployment"),(0,r.kt)("p",null,"Your implementation needs to be contained in the ",(0,r.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.c")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"src/os_parallel.c")," files.\nAny other files that you are using will not be taken into account.\nAny modifications that you are doing to the other files in the ",(0,r.kt)("inlineCode",{parentName:"p"},"src/")," directory will not be taken into account."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b5c587af.bfed2af8.js b/assets/js/b5c587af.bfed2af8.js new file mode 100644 index 0000000000..da8c52c95e --- /dev/null +++ b/assets/js/b5c587af.bfed2af8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkso=self.webpackChunkso||[]).push([[8028],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var o=a.createContext({}),p=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d=function(e){var t=p(e.components);return a.createElement(o.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,o=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=p(n),c=i,m=u["".concat(o,".").concat(c)]||u[c]||h[c]||r;return n?a.createElement(m,l(l({ref:t},d),{},{components:n})):a.createElement(m,l({ref:t},d))}));function m(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,l=new Array(r);l[0]=c;var s={};for(var o in t)hasOwnProperty.call(t,o)&&(s[o]=t[o]);s.originalType=e,s[u]="string"==typeof e?e:i,l[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>p});var a=n(7462),i=(n(7294),n(3905));const r={},l="Parallel Graph",s={unversionedId:"Assignments/Parallel Graph/README",id:"Assignments/Parallel Graph/README",title:"Parallel Graph",description:"Objectives",source:"@site/docs/Assignments/Parallel Graph/README.md",sourceDirName:"Assignments/Parallel Graph",slug:"/Assignments/Parallel Graph/",permalink:"/operating-systems/Assignments/Parallel Graph/",draft:!1,tags:[],version:"current",frontMatter:{},sidebar:"sidebar",previous:{title:"Memory Allocator",permalink:"/operating-systems/Assignments/Memory Allocator/"},next:{title:"Minishell",permalink:"/operating-systems/Assignments/Mini Shell/"}},o={},p=[{value:"Objectives",id:"objectives",level:2},{value:"Statement",id:"statement",level:2},{value:"Support Code",id:"support-code",level:2},{value:"Implementation",id:"implementation",level:2},{value:"Thread Pool Description",id:"thread-pool-description",level:3},{value:"Graph Traversal",id:"graph-traversal",level:3},{value:"Synchronization",id:"synchronization",level:3},{value:"Input Files",id:"input-files",level:3},{value:"Data Structures",id:"data-structures",level:3},{value:"Graph",id:"graph",level:4},{value:"List",id:"list",level:4},{value:"Thread Pool",id:"thread-pool",level:4},{value:"Requirements",id:"requirements",level:3},{value:"Operations",id:"operations",level:2},{value:"Building",id:"building",level:3},{value:"Testing and Grading",id:"testing-and-grading",level:2},{value:"Running the Checker",id:"running-the-checker",level:3},{value:"Running the Linters",id:"running-the-linters",level:3},{value:"Fine-Grained Testing",id:"fine-grained-testing",level:3}],d={toc:p},u="wrapper";function h(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"parallel-graph"},"Parallel Graph"),(0,i.kt)("h2",{id:"objectives"},"Objectives"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Learn how to design and implement parallel programs"),(0,i.kt)("li",{parentName:"ul"},"Gain skills in using synchronization primitives for parallel programs"),(0,i.kt)("li",{parentName:"ul"},"Get a better understanding of the POSIX threading and synchronization API"),(0,i.kt)("li",{parentName:"ul"},"Gain insight on the differences between serial and parallel programs")),(0,i.kt)("h2",{id:"statement"},"Statement"),(0,i.kt)("p",null,"Implement a generic thread pool, then use it to traverse a graph and compute the sum of the elements contained by the nodes.\nYou will be provided with a serial implementation of the graph traversal and with most of the data structures needed to implement the thread pool.\nYour job is to write the thread pool routines and then use the thread pool to traverse the graph."),(0,i.kt)("h2",{id:"support-code"},"Support Code"),(0,i.kt)("p",null,"The support code consists of the directories:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"src/")," is the skeleton parallel graph implementation.\nYou will have to implement missing parts marked as ",(0,i.kt)("inlineCode",{parentName:"p"},"TODO")," items.")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"utils/")," utility files (used for debugging & logging)")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("p",{parentName:"li"},(0,i.kt)("inlineCode",{parentName:"p"},"tests/")," are tests used to validate (and grade) the assignment."))),(0,i.kt)("h2",{id:"implementation"},"Implementation"),(0,i.kt)("h3",{id:"thread-pool-description"},"Thread Pool Description"),(0,i.kt)("p",null,"A thread pool contains a given number of active threads that simply wait to be given specific tasks.\nThe threads are created when the thread pool is created.\nEach thread continuously polls the task queue for available tasks.\nOnce tasks are put in the task queue, the threads poll tasks, and start running them.\nA thread pool creates ",(0,i.kt)("strong",{parentName:"p"},"N")," threads upon its creation and does not destroy (join) them throughout its lifetime.\nThat way, the penalty of creating and destroying threads ad-hoc is avoided.\nAs such, you must implement the following functions (marked with ",(0,i.kt)("inlineCode",{parentName:"p"},"TODO")," in the provided skeleton, in ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.c"),"):"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"enqueue_task()"),": Enqueue task to the shared task queue.\nUse synchronization."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"dequeue_task()"),": Dequeue task from the shared task queue.\nUse synchronization."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"wait_for_completion()"),": Wait for all worker threads.\nUse synchronization."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"create_threadpool()"),": Create a new thread pool."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"destroy_threadpool()"),": Destroy a thread pool.\nAssume all threads have been joined.")),(0,i.kt)("p",null,"You must also update the ",(0,i.kt)("inlineCode",{parentName:"p"},"os_threadpool_t")," structure in ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.h")," with the required bits for synchronizing the parallel implementation."),(0,i.kt)("p",null,"Notice that the thread pool is completely independent of any given application.\nAny function can be registered in the task queue."),(0,i.kt)("p",null,"Since the threads are polling the task queue indefinitely, you need to define a condition for them to stop once the graph has been traversed completely.\nThat is, the condition used by the ",(0,i.kt)("inlineCode",{parentName:"p"},"wait_for_completion()")," function.\nThe recommended way is to note when no threads have any more work to do.\nSince no thread is doing any work, no other task will be created."),(0,i.kt)("h3",{id:"graph-traversal"},"Graph Traversal"),(0,i.kt)("p",null,"Once you have implemented the thread pool, you need to test it by doing a parallel traversal of all connected nodes in a graph.\nA serial implementation for this algorithm is provided in ",(0,i.kt)("inlineCode",{parentName:"p"},"src/serial.c"),".\nTo make use of the thread pool, you will need to create tasks that will be put in the task queue.\nA task consists of 2 steps:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Add the current node value to the overall sum."),(0,i.kt)("li",{parentName:"ol"},"Create tasks and add them to the task queue for the neighbouring nodes.")),(0,i.kt)("p",null,"Implement this in the ",(0,i.kt)("inlineCode",{parentName:"p"},"src/parallel.c")," (see the ",(0,i.kt)("inlineCode",{parentName:"p"},"TODO")," items).\nYou must implement the parallel and synchronized version of the ",(0,i.kt)("inlineCode",{parentName:"p"},"process_node()")," function, also used in the serial implementation."),(0,i.kt)("h3",{id:"synchronization"},"Synchronization"),(0,i.kt)("p",null,"For synchronization you can use mutexes, semaphores, spinlocks, condition variables - anything that grinds your gear.\nHowever, you are not allowed to use hacks such as ",(0,i.kt)("inlineCode",{parentName:"p"},"sleep()"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"printf()")," synchronization or adding superfluous computation."),(0,i.kt)("h3",{id:"input-files"},"Input Files"),(0,i.kt)("p",null,"Reading the graphs from the input files is being taken care of the functions implemented in ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_graph.c"),".\nA graph is represented in input files as follows:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"First line contains 2 integers ",(0,i.kt)("inlineCode",{parentName:"li"},"N")," and ",(0,i.kt)("inlineCode",{parentName:"li"},"M"),": ",(0,i.kt)("inlineCode",{parentName:"li"},"N")," - number of nodes, ",(0,i.kt)("inlineCode",{parentName:"li"},"M")," - numbed or edges"),(0,i.kt)("li",{parentName:"ul"},"Second line contains ",(0,i.kt)("inlineCode",{parentName:"li"},"N")," integer numbers - the values of the nodes."),(0,i.kt)("li",{parentName:"ul"},"The next ",(0,i.kt)("inlineCode",{parentName:"li"},"M")," lines contain each 2 integers that represent the source and the destination of an edge.")),(0,i.kt)("h3",{id:"data-structures"},"Data Structures"),(0,i.kt)("h4",{id:"graph"},"Graph"),(0,i.kt)("p",null,"A graph is represented internally by the ",(0,i.kt)("inlineCode",{parentName:"p"},"os_graph_t")," structure (see ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_graph.h"),")."),(0,i.kt)("h4",{id:"list"},"List"),(0,i.kt)("p",null,"A list is represented internally by the ",(0,i.kt)("inlineCode",{parentName:"p"},"os_queue_t")," structure (see ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_list.h"),").\nYou will use this list to implement the task queue."),(0,i.kt)("h4",{id:"thread-pool"},"Thread Pool"),(0,i.kt)("p",null,"A thread pool is represented internally by the ",(0,i.kt)("inlineCode",{parentName:"p"},"os_threadpool_t")," structure (see ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.h"),").\nThe thread pool contains information about the task queue and the threads."),(0,i.kt)("h3",{id:"requirements"},"Requirements"),(0,i.kt)("p",null,"Your implementation needs to be contained in the ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.c"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"src/os_threadpool.h")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"src/parallel.c")," files.\nAny other files that you are using will not be taken into account.\nAny modifications that you are doing to the other files in the ",(0,i.kt)("inlineCode",{parentName:"p"},"src/")," directory will not be taken into account."),(0,i.kt)("h2",{id:"operations"},"Operations"),(0,i.kt)("h3",{id:"building"},"Building"),(0,i.kt)("p",null,"To build both the serial and the parallel versions, run ",(0,i.kt)("inlineCode",{parentName:"p"},"make")," in the ",(0,i.kt)("inlineCode",{parentName:"p"},"src/")," directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"student@so:~/.../content/assignments/parallel-graph$ cd src/\n\nstudent@so:~/.../assignments/parallel-graph/src$ make\n")),(0,i.kt)("p",null,"That will create the ",(0,i.kt)("inlineCode",{parentName:"p"},"serial")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"parallel")," binaries."),(0,i.kt)("h2",{id:"testing-and-grading"},"Testing and Grading"),(0,i.kt)("p",null,"Testing is automated.\nTests are located in the ",(0,i.kt)("inlineCode",{parentName:"p"},"tests/")," directory."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"student@so:~/.../assignments/parallel-graph/tests$ ls -F\nMakefile checker.py grade.sh@ in/\n")),(0,i.kt)("p",null,"To test and grade your assignment solution, enter the ",(0,i.kt)("inlineCode",{parentName:"p"},"tests/")," directory and run ",(0,i.kt)("inlineCode",{parentName:"p"},"grade.sh"),".\nNote that this requires linters being available.\nThe easiest is to use a Docker-based setup with everything installed and configured.\nWhen using ",(0,i.kt)("inlineCode",{parentName:"p"},"grade.sh")," you will get grades for checking correctness (maximum ",(0,i.kt)("inlineCode",{parentName:"p"},"90")," points) and for coding style (maxim ",(0,i.kt)("inlineCode",{parentName:"p"},"10")," points).\nA successful run will provide you an output ending with:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"### GRADE\n\n\nChecker: 90/ 90\nStyle: 10/ 10\nTotal: 100/100\n\n\n### STYLE SUMMARY\n\n\n")),(0,i.kt)("h3",{id:"running-the-checker"},"Running the Checker"),(0,i.kt)("p",null,"To run only the checker, use the ",(0,i.kt)("inlineCode",{parentName:"p"},"make check")," command in the ",(0,i.kt)("inlineCode",{parentName:"p"},"tests/")," directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"student@so:~/.../assignments/parallel-graph/tests$ make check\n[...]\nSRC_PATH=../src python checker.py\nmake[1]: Entering directory '...'\nrm -f *~\n[...]\nTODO\ntest1.in ....................... failed ... 0.0\ntest2.in ....................... failed ... 0.0\ntest3.in ....................... failed ... 0.0\n[...]\n\nTotal: 0/100\n")),(0,i.kt)("p",null,"Obviously, all tests will fail, as there is no implementation."),(0,i.kt)("p",null,"Each test is worth a number of points.\nThe maximum grade is ",(0,i.kt)("inlineCode",{parentName:"p"},"90"),"."),(0,i.kt)("p",null,"A successful run will show the output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"student@so:~/.../assignments/parallel-graph/tests$ make check\n[...]\nSRC_PATH=../src python checker.py\ntest1.in ....................... passed ... 4.5\ntest2.in ....................... passed ... 4.5\ntest3.in ....................... passed ... 4.5\ntest4.in ....................... passed ... 4.5\ntest5.in ....................... passed ... 4.5\ntest6.in ....................... passed ... 4.5\ntest7.in ....................... passed ... 4.5\ntest8.in ....................... passed ... 4.5\ntest9.in ....................... passed ... 4.5\ntest10.in ....................... passed ... 4.5\ntest11.in ....................... passed ... 4.5\ntest12.in ....................... passed ... 4.5\ntest13.in ....................... passed ... 4.5\ntest14.in ....................... passed ... 4.5\ntest15.in ....................... passed ... 4.5\ntest16.in ....................... passed ... 4.5\ntest17.in ....................... passed ... 4.5\ntest18.in ....................... passed ... 4.5\ntest19.in ....................... passed ... 4.5\ntest20.in ....................... passed ... 4.5\n\nTotal: 90/100\n")),(0,i.kt)("h3",{id:"running-the-linters"},"Running the Linters"),(0,i.kt)("p",null,"To run the linters, use the ",(0,i.kt)("inlineCode",{parentName:"p"},"make lint")," command in the ",(0,i.kt)("inlineCode",{parentName:"p"},"tests/")," directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"student@so:~/.../assignments/parallel-graph/tests$ make lint\n[...]\ncd .. && checkpatch.pl -f checker/*.sh tests/*.sh\n[...]\ncd .. && cpplint --recursive src/ tests/ checker/\n[...]\ncd .. && shellcheck checker/*.sh tests/*.sh\n")),(0,i.kt)("p",null,"Note that the linters have to be installed on your system: ",(0,i.kt)("a",{parentName:"p",href:"https://.com/torvalds/linux/blob/master/scripts/checkpatch.pl"},(0,i.kt)("inlineCode",{parentName:"a"},"checkpatch.pl")),", ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/cpplint/cpplint"},(0,i.kt)("inlineCode",{parentName:"a"},"cpplint")),", ",(0,i.kt)("a",{parentName:"p",href:"https://www.shellcheck.net/"},(0,i.kt)("inlineCode",{parentName:"a"},"shellcheck")),".\nThey also need to have certain configuration options.\nIt's easiest to run them in a Docker-based setup with everything configured."),(0,i.kt)("h3",{id:"fine-grained-testing"},"Fine-Grained Testing"),(0,i.kt)("p",null,"Input tests cases are located in ",(0,i.kt)("inlineCode",{parentName:"p"},"tests/in/"),".\nIf you want to run a single test, use commands such as below while in the ",(0,i.kt)("inlineCode",{parentName:"p"},"src/")," directory:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-console"},"$./parallel ../tests/in/test5.in\n-38\n\n$ ./serial ../tests/in/test5.in\n-38\n")),(0,i.kt)("p",null,"Results provided by the serial and parallel implementation must be the same for the test to successfully pass."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.ccc549b8.js b/assets/js/runtime~main.d2300de6.js similarity index 98% rename from assets/js/runtime~main.ccc549b8.js rename to assets/js/runtime~main.d2300de6.js index 529490b21c..6c575f1a57 100644 --- a/assets/js/runtime~main.ccc549b8.js +++ b/assets/js/runtime~main.d2300de6.js @@ -1 +1 @@ -(()=>{"use strict";var e,c,a,d,b={},f={};function t(e){var c=f[e];if(void 0!==c)return c.exports;var a=f[e]={id:e,loaded:!1,exports:{}};return b[e].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}t.m=b,t.c=f,e=[],t.O=(c,a,d,b)=>{if(!a){var f=1/0;for(i=0;i=b)&&Object.keys(t.O).every((e=>t.O[e](a[o])))?a.splice(o--,1):(r=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[a,d,b]},t.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return t.d(c,{a:c}),c},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,t.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var b=Object.create(null);t.r(b);var f={};c=c||[null,a({}),a([]),a(a)];for(var r=2&d&&e;"object"==typeof r&&!~c.indexOf(r);r=a(r))Object.getOwnPropertyNames(r).forEach((c=>f[c]=()=>e[c]));return f.default=()=>e,t.d(b,f),b},t.d=(e,c)=>{for(var a in c)t.o(c,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:c[a]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce(((c,a)=>(t.f[a](e,c),c)),[])),t.u=e=>"assets/js/"+({13:"463aadd7",24:"6b326dfe",53:"935f2afb",180:"c7d5d005",213:"c92640ae",214:"03dc0c9b",373:"f808e6c0",488:"96a31749",556:"577dcf4c",675:"98c71577",820:"7f023807",842:"95637cbd",895:"f8a820d6",937:"4e29cae1",983:"04d8a21d",1018:"0277d735",1101:"b407248a",1118:"fbc1cab8",1157:"91ac0728",1265:"f54b55c1",1329:"997e6ee2",1445:"e34aa1dc",1482:"c4d6228b",1487:"2330fd66",1625:"fbacb3d5",1746:"60905a9d",1758:"8de34314",1765:"374a2386",1771:"d2f41667",1786:"918b3e21",1901:"3c30233f",1967:"0fa0bebd",2055:"18331331",2161:"3d15bb58",2202:"14ee73ae",2232:"e4b3f4c8",2279:"1dccb566",2417:"c2609098",2456:"ac5c3a27",2472:"d309dd16",2590:"bd909c58",2661:"2e030903",2713:"8f35a413",2736:"d2954435",2764:"1ef36804",2798:"d92a3c43",2815:"0438abee",2827:"8ca589d3",2829:"a4b6fafb",2838:"6e6dee7f",2845:"2828cd91",3004:"f6eb4965",3063:"32839693",3068:"0c19000f",3085:"1f391b9e",3126:"e46ccb2a",3320:"a7bc80c4",3334:"eae0e5d1",3425:"a315d4d8",3470:"6e95b748",3540:"2c270c24",3675:"31a6b50d",3711:"a8d01eab",3742:"68eeb637",3788:"a0ac5395",3807:"b95e0710",3851:"ab4aa734",3866:"fdef1607",3867:"4931bb70",3920:"d509b9f5",4006:"2bde47d5",4126:"487d1817",4148:"89d3ad7d",4207:"59897f9f",4222:"81b85611",4272:"1548d5c7",4346:"cc8fb1fa",4350:"692011d4",4379:"1ffc5c5f",4426:"5d7f8186",4461:"59ad4d8f",4470:"ade537b6",4471:"a210c167",4823:"d754500f",4841:"473ad4cf",4881:"3e3393a3",4980:"56fa2c9d",5139:"15f618ea",5220:"6e77dc18",5330:"34746f8c",5399:"2cea7b84",5430:"625a19b4",5475:"7e98c1d8",5616:"1b1148a8",5737:"144ccec8",5782:"0275a3b2",5899:"232c749b",6074:"8209a29d",6078:"5ebe6805",6387:"ed8bb14c",6397:"65ab3714",6429:"62a2c47b",6492:"aecc3d85",6512:"94458749",6632:"14580385",6723:"8ec866b0",6901:"5e10bb01",7089:"924f80ad",7156:"65687b6f",7327:"3e478533",7383:"ca6b73ec",7387:"d6e5c209",7414:"393be207",7674:"8d5b82ca",7841:"a191e07d",7914:"09e11287",7915:"1891e676",7918:"17896441",7986:"87bfa638",8028:"b5c587af",8051:"926d7fb7",8211:"0f890721",8245:"4c341edc",8311:"9f880d5b",8322:"5894dc17",8351:"392776e2",8411:"267b5415",8421:"23374ca6",8446:"e0921ae2",8448:"50ed9da3",8459:"5c4ba3bf",8482:"cbc996c5",8631:"007cf997",8650:"3e17b32d",8684:"f4dcab90",8788:"9f99d3fc",8986:"2641b427",9041:"0bbd68f9",9052:"ddc3a2ab",9085:"ce181f15",9095:"ce0d7f6c",9152:"1e0b7734",9173:"70ad9ac2",9197:"e88d4a6f",9386:"fecbe7cc",9514:"1be78505",9667:"fc7881a9",9671:"35edd654",9701:"5b157b4b",9724:"4c165629",9735:"c54826dc",9817:"14eb3368",9829:"ba943973",9836:"9dd394c3",9837:"092edce8",9856:"49cee3f0",9859:"432299a8",9944:"928d0c11",9984:"6bda9475",9995:"97fe4cb3"}[e]||e)+"."+{13:"0dfc7bdc",24:"a9207055",53:"a906aa4d",180:"3c93fb0a",213:"1c2f5c73",214:"139425d4",373:"d050e3ae",488:"33f414fc",556:"66ffefe5",675:"7f3cfddf",820:"3a328b33",842:"aeba6ee5",895:"66bae94b",937:"7ea0fff0",983:"a230438d",1018:"a515a3fb",1101:"4283d58b",1118:"c8f5edbe",1157:"a1141dd4",1265:"e5827ab1",1329:"10ca65f0",1445:"8720aa1d",1482:"a37f2d34",1487:"92c84e6d",1625:"550957d1",1746:"dffe0c14",1758:"39294952",1765:"e9f1f856",1771:"7f38cb71",1786:"ccfe750c",1901:"ecfeebad",1967:"af4a8962",2055:"91bdb813",2161:"488e46c4",2202:"f3e2d97e",2232:"3b3a3133",2279:"da3fde37",2417:"eef38f14",2456:"8b2f5200",2472:"7aa9c095",2590:"b0fd30e8",2661:"d0799204",2666:"5efb0c03",2713:"dc45e977",2736:"7d16022f",2764:"f824c9fe",2798:"d7a2ac2e",2815:"c857951b",2827:"15fbe012",2829:"aa7624fc",2838:"e6189627",2845:"80318335",3004:"9b048d4d",3063:"cfb24c63",3068:"a29eccf9",3085:"b2d53f92",3126:"35945294",3320:"be76a8d5",3334:"1005984d",3425:"f6863615",3470:"12ce4711",3540:"7422d550",3675:"8220302b",3711:"957b75db",3742:"7099ceab",3788:"ca3371f5",3807:"30ae32cf",3851:"704cae74",3866:"2f9ef3d6",3867:"4ad92363",3920:"f97ca1f5",4006:"64c23d10",4126:"b3e30c20",4148:"7617e4f3",4207:"5e9ca6e0",4222:"988ae966",4272:"005d8abe",4346:"36caae60",4350:"d0f1c3e1",4379:"29c404a6",4426:"f9eec9d2",4461:"68672233",4470:"d7d432bf",4471:"4d2662ea",4823:"a448253a",4841:"a77bcd95",4881:"e347d07c",4972:"d4c24351",4980:"073ea839",5139:"49df88b1",5220:"b77bc1f4",5330:"6055689b",5399:"9aa32d6b",5430:"e4013065",5475:"cd2c3621",5616:"95362fdc",5737:"6c5c8e28",5782:"0080b9a8",5899:"838a030c",6074:"ad2a45ab",6078:"50f6f728",6387:"4e29ff54",6397:"4a96658a",6429:"346e1842",6492:"26f75de3",6512:"8afa4e2d",6632:"942bd181",6723:"59658b02",6901:"2a9b0ba3",7089:"d35435fe",7156:"a1f1a664",7327:"e58aa823",7383:"decd0f30",7387:"c32a7c7b",7414:"23719e8d",7674:"b2e711cd",7841:"7bbcfa1b",7914:"4422e942",7915:"bb6c576c",7918:"4e93f2ea",7986:"59222c58",8028:"ba3613c2",8051:"0a5b1fec",8211:"480c5381",8245:"a1c47887",8311:"9bc7ed44",8322:"cdbac989",8351:"210fab17",8411:"772e4045",8421:"220f92d7",8446:"90e0f478",8448:"757d4379",8459:"f75b3b62",8482:"7456f430",8631:"e11c2a45",8650:"ade25cd0",8684:"160db296",8788:"5c6cfaae",8986:"caa70af6",9041:"6c612561",9052:"330d3a21",9085:"9ae0cf98",9095:"8a66ec5b",9152:"0e45e049",9173:"9678f58f",9197:"59d4cc0c",9386:"6f55203e",9514:"f8b9d3b1",9667:"f46a5817",9671:"d35ecfaf",9701:"74e53c4b",9724:"cab912ff",9735:"81f86ec9",9817:"f8efd3cc",9829:"1c4dae75",9836:"fdb09471",9837:"6d3ecf57",9856:"a2154631",9859:"e846720a",9944:"8d1e960e",9984:"40a0019e",9995:"b0dc0e62"}[e]+".js",t.miniCssF=e=>{},t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),t.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),d={},t.l=(e,c,a,b)=>{if(d[e])d[e].push(c);else{var f,r;if(void 0!==a)for(var o=document.getElementsByTagName("script"),n=0;n{f.onerror=f.onload=null,clearTimeout(l);var b=d[e];if(delete d[e],f.parentNode&&f.parentNode.removeChild(f),b&&b.forEach((e=>e(a))),c)return c(a)},l=setTimeout(u.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=u.bind(null,f.onerror),f.onload=u.bind(null,f.onload),r&&document.head.appendChild(f)}},t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.p="/operating-systems/",t.gca=function(e){return e={14580385:"6632",17896441:"7918",18331331:"2055",32839693:"3063",94458749:"6512","463aadd7":"13","6b326dfe":"24","935f2afb":"53",c7d5d005:"180",c92640ae:"213","03dc0c9b":"214",f808e6c0:"373","96a31749":"488","577dcf4c":"556","98c71577":"675","7f023807":"820","95637cbd":"842",f8a820d6:"895","4e29cae1":"937","04d8a21d":"983","0277d735":"1018",b407248a:"1101",fbc1cab8:"1118","91ac0728":"1157",f54b55c1:"1265","997e6ee2":"1329",e34aa1dc:"1445",c4d6228b:"1482","2330fd66":"1487",fbacb3d5:"1625","60905a9d":"1746","8de34314":"1758","374a2386":"1765",d2f41667:"1771","918b3e21":"1786","3c30233f":"1901","0fa0bebd":"1967","3d15bb58":"2161","14ee73ae":"2202",e4b3f4c8:"2232","1dccb566":"2279",c2609098:"2417",ac5c3a27:"2456",d309dd16:"2472",bd909c58:"2590","2e030903":"2661","8f35a413":"2713",d2954435:"2736","1ef36804":"2764",d92a3c43:"2798","0438abee":"2815","8ca589d3":"2827",a4b6fafb:"2829","6e6dee7f":"2838","2828cd91":"2845",f6eb4965:"3004","0c19000f":"3068","1f391b9e":"3085",e46ccb2a:"3126",a7bc80c4:"3320",eae0e5d1:"3334",a315d4d8:"3425","6e95b748":"3470","2c270c24":"3540","31a6b50d":"3675",a8d01eab:"3711","68eeb637":"3742",a0ac5395:"3788",b95e0710:"3807",ab4aa734:"3851",fdef1607:"3866","4931bb70":"3867",d509b9f5:"3920","2bde47d5":"4006","487d1817":"4126","89d3ad7d":"4148","59897f9f":"4207","81b85611":"4222","1548d5c7":"4272",cc8fb1fa:"4346","692011d4":"4350","1ffc5c5f":"4379","5d7f8186":"4426","59ad4d8f":"4461",ade537b6:"4470",a210c167:"4471",d754500f:"4823","473ad4cf":"4841","3e3393a3":"4881","56fa2c9d":"4980","15f618ea":"5139","6e77dc18":"5220","34746f8c":"5330","2cea7b84":"5399","625a19b4":"5430","7e98c1d8":"5475","1b1148a8":"5616","144ccec8":"5737","0275a3b2":"5782","232c749b":"5899","8209a29d":"6074","5ebe6805":"6078",ed8bb14c:"6387","65ab3714":"6397","62a2c47b":"6429",aecc3d85:"6492","8ec866b0":"6723","5e10bb01":"6901","924f80ad":"7089","65687b6f":"7156","3e478533":"7327",ca6b73ec:"7383",d6e5c209:"7387","393be207":"7414","8d5b82ca":"7674",a191e07d:"7841","09e11287":"7914","1891e676":"7915","87bfa638":"7986",b5c587af:"8028","926d7fb7":"8051","0f890721":"8211","4c341edc":"8245","9f880d5b":"8311","5894dc17":"8322","392776e2":"8351","267b5415":"8411","23374ca6":"8421",e0921ae2:"8446","50ed9da3":"8448","5c4ba3bf":"8459",cbc996c5:"8482","007cf997":"8631","3e17b32d":"8650",f4dcab90:"8684","9f99d3fc":"8788","2641b427":"8986","0bbd68f9":"9041",ddc3a2ab:"9052",ce181f15:"9085",ce0d7f6c:"9095","1e0b7734":"9152","70ad9ac2":"9173",e88d4a6f:"9197",fecbe7cc:"9386","1be78505":"9514",fc7881a9:"9667","35edd654":"9671","5b157b4b":"9701","4c165629":"9724",c54826dc:"9735","14eb3368":"9817",ba943973:"9829","9dd394c3":"9836","092edce8":"9837","49cee3f0":"9856","432299a8":"9859","928d0c11":"9944","6bda9475":"9984","97fe4cb3":"9995"}[e]||e,t.p+t.u(e)},(()=>{var e={1303:0,532:0};t.f.j=(c,a)=>{var d=t.o(e,c)?e[c]:void 0;if(0!==d)if(d)a.push(d[2]);else if(/^(1303|532)$/.test(c))e[c]=0;else{var b=new Promise(((a,b)=>d=e[c]=[a,b]));a.push(d[2]=b);var f=t.p+t.u(c),r=new Error;t.l(f,(a=>{if(t.o(e,c)&&(0!==(d=e[c])&&(e[c]=void 0),d)){var b=a&&("load"===a.type?"missing":a.type),f=a&&a.target&&a.target.src;r.message="Loading chunk "+c+" failed.\n("+b+": "+f+")",r.name="ChunkLoadError",r.type=b,r.request=f,d[1](r)}}),"chunk-"+c,c)}},t.O.j=c=>0===e[c];var c=(c,a)=>{var d,b,f=a[0],r=a[1],o=a[2],n=0;if(f.some((c=>0!==e[c]))){for(d in r)t.o(r,d)&&(t.m[d]=r[d]);if(o)var i=o(t)}for(c&&c(a);n{"use strict";var e,c,a,d,b={},f={};function t(e){var c=f[e];if(void 0!==c)return c.exports;var a=f[e]={id:e,loaded:!1,exports:{}};return b[e].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}t.m=b,t.c=f,e=[],t.O=(c,a,d,b)=>{if(!a){var f=1/0;for(i=0;i=b)&&Object.keys(t.O).every((e=>t.O[e](a[o])))?a.splice(o--,1):(r=!1,b0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[a,d,b]},t.n=e=>{var c=e&&e.__esModule?()=>e.default:()=>e;return t.d(c,{a:c}),c},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,t.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var b=Object.create(null);t.r(b);var f={};c=c||[null,a({}),a([]),a(a)];for(var r=2&d&&e;"object"==typeof r&&!~c.indexOf(r);r=a(r))Object.getOwnPropertyNames(r).forEach((c=>f[c]=()=>e[c]));return f.default=()=>e,t.d(b,f),b},t.d=(e,c)=>{for(var a in c)t.o(c,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:c[a]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce(((c,a)=>(t.f[a](e,c),c)),[])),t.u=e=>"assets/js/"+({13:"463aadd7",24:"6b326dfe",53:"935f2afb",180:"c7d5d005",213:"c92640ae",214:"03dc0c9b",373:"f808e6c0",488:"96a31749",556:"577dcf4c",675:"98c71577",820:"7f023807",842:"95637cbd",895:"f8a820d6",937:"4e29cae1",983:"04d8a21d",1018:"0277d735",1101:"b407248a",1118:"fbc1cab8",1157:"91ac0728",1265:"f54b55c1",1329:"997e6ee2",1445:"e34aa1dc",1482:"c4d6228b",1487:"2330fd66",1625:"fbacb3d5",1746:"60905a9d",1758:"8de34314",1765:"374a2386",1771:"d2f41667",1786:"918b3e21",1901:"3c30233f",1967:"0fa0bebd",2055:"18331331",2161:"3d15bb58",2202:"14ee73ae",2232:"e4b3f4c8",2279:"1dccb566",2417:"c2609098",2456:"ac5c3a27",2472:"d309dd16",2590:"bd909c58",2661:"2e030903",2713:"8f35a413",2736:"d2954435",2764:"1ef36804",2798:"d92a3c43",2815:"0438abee",2827:"8ca589d3",2829:"a4b6fafb",2838:"6e6dee7f",2845:"2828cd91",3004:"f6eb4965",3063:"32839693",3068:"0c19000f",3085:"1f391b9e",3126:"e46ccb2a",3320:"a7bc80c4",3334:"eae0e5d1",3425:"a315d4d8",3470:"6e95b748",3540:"2c270c24",3675:"31a6b50d",3711:"a8d01eab",3742:"68eeb637",3788:"a0ac5395",3807:"b95e0710",3851:"ab4aa734",3866:"fdef1607",3867:"4931bb70",3920:"d509b9f5",4006:"2bde47d5",4126:"487d1817",4148:"89d3ad7d",4207:"59897f9f",4222:"81b85611",4272:"1548d5c7",4346:"cc8fb1fa",4350:"692011d4",4379:"1ffc5c5f",4426:"5d7f8186",4461:"59ad4d8f",4470:"ade537b6",4471:"a210c167",4823:"d754500f",4841:"473ad4cf",4881:"3e3393a3",4980:"56fa2c9d",5139:"15f618ea",5220:"6e77dc18",5330:"34746f8c",5399:"2cea7b84",5430:"625a19b4",5475:"7e98c1d8",5616:"1b1148a8",5737:"144ccec8",5782:"0275a3b2",5899:"232c749b",6074:"8209a29d",6078:"5ebe6805",6387:"ed8bb14c",6397:"65ab3714",6429:"62a2c47b",6492:"aecc3d85",6512:"94458749",6632:"14580385",6723:"8ec866b0",6901:"5e10bb01",7089:"924f80ad",7156:"65687b6f",7327:"3e478533",7383:"ca6b73ec",7387:"d6e5c209",7414:"393be207",7674:"8d5b82ca",7841:"a191e07d",7914:"09e11287",7915:"1891e676",7918:"17896441",7986:"87bfa638",8028:"b5c587af",8051:"926d7fb7",8211:"0f890721",8245:"4c341edc",8311:"9f880d5b",8322:"5894dc17",8351:"392776e2",8411:"267b5415",8421:"23374ca6",8446:"e0921ae2",8448:"50ed9da3",8459:"5c4ba3bf",8482:"cbc996c5",8631:"007cf997",8650:"3e17b32d",8684:"f4dcab90",8788:"9f99d3fc",8986:"2641b427",9041:"0bbd68f9",9052:"ddc3a2ab",9085:"ce181f15",9095:"ce0d7f6c",9152:"1e0b7734",9173:"70ad9ac2",9197:"e88d4a6f",9386:"fecbe7cc",9514:"1be78505",9667:"fc7881a9",9671:"35edd654",9701:"5b157b4b",9724:"4c165629",9735:"c54826dc",9817:"14eb3368",9829:"ba943973",9836:"9dd394c3",9837:"092edce8",9856:"49cee3f0",9859:"432299a8",9944:"928d0c11",9984:"6bda9475",9995:"97fe4cb3"}[e]||e)+"."+{13:"0dfc7bdc",24:"a9207055",53:"f48ac3b3",180:"3c93fb0a",213:"1c2f5c73",214:"139425d4",373:"d050e3ae",488:"33f414fc",556:"66ffefe5",675:"7f3cfddf",820:"3a328b33",842:"aeba6ee5",895:"66bae94b",937:"7ea0fff0",983:"a230438d",1018:"a515a3fb",1101:"4283d58b",1118:"c8f5edbe",1157:"a1141dd4",1265:"e5827ab1",1329:"10ca65f0",1445:"8720aa1d",1482:"a37f2d34",1487:"92c84e6d",1625:"550957d1",1746:"dffe0c14",1758:"39294952",1765:"e9f1f856",1771:"7f38cb71",1786:"ccfe750c",1901:"ecfeebad",1967:"af4a8962",2055:"91bdb813",2161:"488e46c4",2202:"f3e2d97e",2232:"3b3a3133",2279:"da3fde37",2417:"eef38f14",2456:"8b2f5200",2472:"7aa9c095",2590:"b0fd30e8",2661:"d0799204",2666:"5efb0c03",2713:"dc45e977",2736:"7d16022f",2764:"f824c9fe",2798:"d7a2ac2e",2815:"c857951b",2827:"15fbe012",2829:"aa7624fc",2838:"e6189627",2845:"80318335",3004:"9b048d4d",3063:"cfb24c63",3068:"a29eccf9",3085:"b2d53f92",3126:"35945294",3320:"be76a8d5",3334:"1005984d",3425:"f6863615",3470:"12ce4711",3540:"7422d550",3675:"8220302b",3711:"957b75db",3742:"7099ceab",3788:"ca3371f5",3807:"30ae32cf",3851:"704cae74",3866:"2f9ef3d6",3867:"4ad92363",3920:"f97ca1f5",4006:"64c23d10",4126:"b3e30c20",4148:"7617e4f3",4207:"5e9ca6e0",4222:"988ae966",4272:"005d8abe",4346:"36caae60",4350:"d0f1c3e1",4379:"29c404a6",4426:"f9eec9d2",4461:"68672233",4470:"d7d432bf",4471:"4d2662ea",4823:"a448253a",4841:"a77bcd95",4881:"e347d07c",4972:"d4c24351",4980:"073ea839",5139:"49df88b1",5220:"b77bc1f4",5330:"6055689b",5399:"9aa32d6b",5430:"e4013065",5475:"cd2c3621",5616:"95362fdc",5737:"6c5c8e28",5782:"0080b9a8",5899:"838a030c",6074:"ad2a45ab",6078:"50f6f728",6387:"4e29ff54",6397:"4a96658a",6429:"346e1842",6492:"26f75de3",6512:"8afa4e2d",6632:"942bd181",6723:"59658b02",6901:"2a9b0ba3",7089:"d35435fe",7156:"a1f1a664",7327:"e58aa823",7383:"decd0f30",7387:"c32a7c7b",7414:"23719e8d",7674:"b2e711cd",7841:"7bbcfa1b",7914:"4422e942",7915:"bb6c576c",7918:"4e93f2ea",7986:"59222c58",8028:"bfed2af8",8051:"0a5b1fec",8211:"480c5381",8245:"a1c47887",8311:"9bc7ed44",8322:"cdbac989",8351:"210fab17",8411:"772e4045",8421:"220f92d7",8446:"90e0f478",8448:"757d4379",8459:"f75b3b62",8482:"7456f430",8631:"e11c2a45",8650:"ade25cd0",8684:"160db296",8788:"5c6cfaae",8986:"caa70af6",9041:"6c612561",9052:"330d3a21",9085:"9ae0cf98",9095:"8a66ec5b",9152:"0e45e049",9173:"9678f58f",9197:"59d4cc0c",9386:"6f55203e",9514:"f8b9d3b1",9667:"f46a5817",9671:"d35ecfaf",9701:"74e53c4b",9724:"cab912ff",9735:"81f86ec9",9817:"f8efd3cc",9829:"1c4dae75",9836:"fdb09471",9837:"6d3ecf57",9856:"a2154631",9859:"e846720a",9944:"8d1e960e",9984:"40a0019e",9995:"b0dc0e62"}[e]+".js",t.miniCssF=e=>{},t.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),t.o=(e,c)=>Object.prototype.hasOwnProperty.call(e,c),d={},t.l=(e,c,a,b)=>{if(d[e])d[e].push(c);else{var f,r;if(void 0!==a)for(var o=document.getElementsByTagName("script"),n=0;n{f.onerror=f.onload=null,clearTimeout(l);var b=d[e];if(delete d[e],f.parentNode&&f.parentNode.removeChild(f),b&&b.forEach((e=>e(a))),c)return c(a)},l=setTimeout(u.bind(null,void 0,{type:"timeout",target:f}),12e4);f.onerror=u.bind(null,f.onerror),f.onload=u.bind(null,f.onload),r&&document.head.appendChild(f)}},t.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.p="/operating-systems/",t.gca=function(e){return e={14580385:"6632",17896441:"7918",18331331:"2055",32839693:"3063",94458749:"6512","463aadd7":"13","6b326dfe":"24","935f2afb":"53",c7d5d005:"180",c92640ae:"213","03dc0c9b":"214",f808e6c0:"373","96a31749":"488","577dcf4c":"556","98c71577":"675","7f023807":"820","95637cbd":"842",f8a820d6:"895","4e29cae1":"937","04d8a21d":"983","0277d735":"1018",b407248a:"1101",fbc1cab8:"1118","91ac0728":"1157",f54b55c1:"1265","997e6ee2":"1329",e34aa1dc:"1445",c4d6228b:"1482","2330fd66":"1487",fbacb3d5:"1625","60905a9d":"1746","8de34314":"1758","374a2386":"1765",d2f41667:"1771","918b3e21":"1786","3c30233f":"1901","0fa0bebd":"1967","3d15bb58":"2161","14ee73ae":"2202",e4b3f4c8:"2232","1dccb566":"2279",c2609098:"2417",ac5c3a27:"2456",d309dd16:"2472",bd909c58:"2590","2e030903":"2661","8f35a413":"2713",d2954435:"2736","1ef36804":"2764",d92a3c43:"2798","0438abee":"2815","8ca589d3":"2827",a4b6fafb:"2829","6e6dee7f":"2838","2828cd91":"2845",f6eb4965:"3004","0c19000f":"3068","1f391b9e":"3085",e46ccb2a:"3126",a7bc80c4:"3320",eae0e5d1:"3334",a315d4d8:"3425","6e95b748":"3470","2c270c24":"3540","31a6b50d":"3675",a8d01eab:"3711","68eeb637":"3742",a0ac5395:"3788",b95e0710:"3807",ab4aa734:"3851",fdef1607:"3866","4931bb70":"3867",d509b9f5:"3920","2bde47d5":"4006","487d1817":"4126","89d3ad7d":"4148","59897f9f":"4207","81b85611":"4222","1548d5c7":"4272",cc8fb1fa:"4346","692011d4":"4350","1ffc5c5f":"4379","5d7f8186":"4426","59ad4d8f":"4461",ade537b6:"4470",a210c167:"4471",d754500f:"4823","473ad4cf":"4841","3e3393a3":"4881","56fa2c9d":"4980","15f618ea":"5139","6e77dc18":"5220","34746f8c":"5330","2cea7b84":"5399","625a19b4":"5430","7e98c1d8":"5475","1b1148a8":"5616","144ccec8":"5737","0275a3b2":"5782","232c749b":"5899","8209a29d":"6074","5ebe6805":"6078",ed8bb14c:"6387","65ab3714":"6397","62a2c47b":"6429",aecc3d85:"6492","8ec866b0":"6723","5e10bb01":"6901","924f80ad":"7089","65687b6f":"7156","3e478533":"7327",ca6b73ec:"7383",d6e5c209:"7387","393be207":"7414","8d5b82ca":"7674",a191e07d:"7841","09e11287":"7914","1891e676":"7915","87bfa638":"7986",b5c587af:"8028","926d7fb7":"8051","0f890721":"8211","4c341edc":"8245","9f880d5b":"8311","5894dc17":"8322","392776e2":"8351","267b5415":"8411","23374ca6":"8421",e0921ae2:"8446","50ed9da3":"8448","5c4ba3bf":"8459",cbc996c5:"8482","007cf997":"8631","3e17b32d":"8650",f4dcab90:"8684","9f99d3fc":"8788","2641b427":"8986","0bbd68f9":"9041",ddc3a2ab:"9052",ce181f15:"9085",ce0d7f6c:"9095","1e0b7734":"9152","70ad9ac2":"9173",e88d4a6f:"9197",fecbe7cc:"9386","1be78505":"9514",fc7881a9:"9667","35edd654":"9671","5b157b4b":"9701","4c165629":"9724",c54826dc:"9735","14eb3368":"9817",ba943973:"9829","9dd394c3":"9836","092edce8":"9837","49cee3f0":"9856","432299a8":"9859","928d0c11":"9944","6bda9475":"9984","97fe4cb3":"9995"}[e]||e,t.p+t.u(e)},(()=>{var e={1303:0,532:0};t.f.j=(c,a)=>{var d=t.o(e,c)?e[c]:void 0;if(0!==d)if(d)a.push(d[2]);else if(/^(1303|532)$/.test(c))e[c]=0;else{var b=new Promise(((a,b)=>d=e[c]=[a,b]));a.push(d[2]=b);var f=t.p+t.u(c),r=new Error;t.l(f,(a=>{if(t.o(e,c)&&(0!==(d=e[c])&&(e[c]=void 0),d)){var b=a&&("load"===a.type?"missing":a.type),f=a&&a.target&&a.target.src;r.message="Loading chunk "+c+" failed.\n("+b+": "+f+")",r.name="ChunkLoadError",r.type=b,r.request=f,d[1](r)}}),"chunk-"+c,c)}},t.O.j=c=>0===e[c];var c=(c,a)=>{var d,b,f=a[0],r=a[1],o=a[2],n=0;if(f.some((c=>0!==e[c]))){for(d in r)t.o(r,d)&&(t.m[d]=r[d]);if(o)var i=o(t)}for(c&&c(a);n Intro | Operating Systems - +

    Intro

    This is a landing page for your course.

    Here you will add infomation about your course that a student might want to know at first glance.

    - + \ No newline at end of file diff --git a/markdown-page/index.html b/markdown-page/index.html index d6439a2e41..b4c07007b1 100644 --- a/markdown-page/index.html +++ b/markdown-page/index.html @@ -4,13 +4,13 @@ Markdown page example | Operating Systems - +

    Markdown page example

    You don't need React to write simple standalone pages.

    - + \ No newline at end of file diff --git a/resources/index.html b/resources/index.html index 3cdd910b95..49d017a463 100644 --- a/resources/index.html +++ b/resources/index.html @@ -4,7 +4,7 @@ Resources and Useful Links | Operating Systems - + @@ -16,7 +16,7 @@ Follow the instructions on the official websites for installation.

    UTM (macOS >= 11)

    If you are using an M1 Apple system, you will not be able to run the virtual machine using VirtualBox or VMware. You will need to use UTM, along with a .qcow2 image. You will need to log in using your UPB account.

    After you install UTM and download and unzip the archive, you can import it using the Open existing VM option in UTM.

    You can also follow the instructions for running the VM using qemu.

    - + \ No newline at end of file diff --git a/rules-and-grading/index.html b/rules-and-grading/index.html index d6b150643e..48e5cfb94e 100644 --- a/rules-and-grading/index.html +++ b/rules-and-grading/index.html @@ -4,7 +4,7 @@ Rules and Grading | Operating Systems - + @@ -77,7 +77,7 @@ You cannot retain the grades for lecture components (lecture tests and exam).
  • Students interested in preserving their grades should respond on the designated Moodle thread by Tuesday, October 31, 2023, 23:00.
  • The rules and grading system for students retaking the course are the same as for students in the current year (lecture tests + exam, assignments, etc.).
  • Students retaking the course can participate in any lab session as long as there are available slots. Like other students, the attendance list becomes fixed starting from the third week.
  • Students retaking the course can participate in any lecture, lecture test, and exam, regardless of the series to which they belonged.
  • By default, the grades for the 2023-2024 academic year will be reset on October 1, 2024. If you do not graduate from the course in the 2023-2024 academic year, you will need to retake it in the 2024-2025 academic year, with the possibility of retaining some components, as detailed above.

    - + \ No newline at end of file