## POSIX Threads (5.6.)

Today we will continue with exploring DiOS internals. To remind us what we have
learned so far, let's investigate the known structure of DiOS:


                +---------------------------+
                |                           |
                |           DiOS            |
                |                           |
                +---------------------------+
                |         libraries:        |
                |           ????            |
                |                           |
                +---------------------------+
                |                           |
                |       config stack:       |
                |       - scheduler         |
                |       - fault handler     |
                |         ...               |
                |                           |
                |       - dios task         |
                |         + TLS             |
                |                           |
                +---------------------------+

                +---------------------------+
                |                           |
                |           DiVM            |
                |                           |
                |   - __vm_choose(...)      |
                |   - __vm_obj_make(...)    |
                |     __vm_obj_free(...)    |
                |   - __vm_test_crit(...)   |
                |     __vm_test_loop(...)   |
                |   - __vm_suspend(...)     |
                |   - __vm_cancel(...)      |
                |                           |
                +---------------------------+

We will now start to examine userspace libraries. The pthread library is one
of the essentials. DIVINE ships its own version, because it needs to integrate
it with DiOS scheduler.

## TLS

Basic data-types for thread support are defined in `dios/include/sys/thread.h`.
You can find there a definition of a thread internal data `_PThread`, thread
local storage `_PThreadTLS` and also a definition of thread handlers
`_PThreadHandlers`. The userspace thread definition is located in
`include/pthread.h`. DiOS recognizes threads as tasks in the scheduler, thread
data and metadata are stored in the __dios_tls structure.

## Initialization

Thread initialization code is in `libc/pthread/pthread-init.cpp`. A general
thread is created in the usual way via `pthread_create` defined in
`libc/pthread/pthred-core.cpp`. A thread is started as a new __dios_task which
we need to assign a thread. This happens in __pthred_entry. The __pthread_entry
function associates thread with a new task and executes the thread entry
function. Finally the thread is killed either by detaching or by join (except
main function). After thread cleanup ends, the corresponding task is terminated
with `__dios_suicide`.

## Main thread

The main thread is created differently. During boot, DiOS has to assign the
current task to the main thread. This happens in two steps. First, during the
setup of a scheduler, we create a main task that executes `__dios_start` which
calls `__execute_main` in the first run of scheduler.  Before main is called,
we initialize pthread library (__pthread_initialize). In `__pthread_initialize`
DiOS allocates TLS for main thread and initializes its flags and sets the
current task to execute this thread.

Pthread functions need to be executed atomically. This is because an interrupt
in the middle of such function might leave the thread in an undefined state. To
prevent undefined behavior pthread functions contain a __dios::FencedInterruptMask
which ensures atomic execution.

## Excursion to the start of pthread

Try to run simulator a check when pthread is created/rescheduled.

divine sim test/pthread/div/thread-exits.cpp

1. __boot               config/common.hpp
2. __dios_boot          config/common.hpp
3. __dios::boot         sys/boot.hpp

   ...

4. Scheduler::setup     sys/sched_base.hpp
  - creates task __dios_start (main)

5. run scheduler

6. __execute_main       libc/sys/start.cpp

7. __pthread_initialize libc/sys/start.cpp
    - __init_thread
    - __dios_reschedule

8. main
    - ptread_create
        - pthread_init
    - pthread_join

The implementation of pthread_join is located in `dios/libc/pthread-core.cpp`.
Join wait for the result of the thread and subsequently it releases and kills
the thread task (see `include/sys/thread.h`).

Waiting mechanism is located in `include/sys/thread.h`. TODO

The rest of the pthread function definitions reside in `dios/libc/pthread/*`.
Whereas function declarations with data-types definitions are located in
`dios/include/pthread.h`

## Synchronization primitives


### Mutex

Mutex implementation is located `libc/pthread/pthread-mutex.cpp`.
Generally, errors related to locking are announced as:

```
    __dios_fault( _VM_Fault::_VM_F_Locking, "message" );
```

As fault DiOS announces:
 1. the detection of deadlock (see below),
 2. destruction of a locked mutex,
 3. double-lock of nonrecursive mutex,
 4. unlocking of unlocked mutex,
 5. unlocking of mutex by another thread.

An interesting detail in the implementation is in `pthread_mutex_timedlock`
whete time is simulated via nondeterminism.

Exercise: try to create a fault and then suppress it with ignore.

### Barrier see `libpthread/pthread-barrier.cpp`

### CondVar see `libc/pthread/pthread-cond.cpp`

The signaling on a conditional variable is implemented in
`include/sys/thread.h`, where the thread to be waken is nondeterministically
chosen.

### RWLock see `libpthread/pthread-rwlock.cpp`

## Deadlock

DiOS performs deadlock detection on a lock of a mutex (see
`libc/pthread/pthread-mutex.cpp`). A deadlock is signaled as a _VM_F_Locking
fault. It may occur when:
 1. threads form a cyclic dependency,
 2. a thread waits for a resource that is held by a deadlocked thread,
 3. a thread waits for a resource held by a death thread.
