\chapter{Threads and Tasks}

The \texttt{task} server will provide the ability to create tasks and
threads, and to destroy them.

\begin{comment}
  In L4, only threads in the privileged address space (the rootserver)
  are allowed to manipulate threads and address spaces (using the
  \textsc{ThreadControl} and \textsc{SpaceControl} system calls).  The
  \texttt{task} server will use the system call wrappers provided by
  the rootserver, see section \ref{rootserver} on page
  \pageref{rootserver}.
\end{comment}

The \texttt{task} server provides three different capability types.

\paragraph{Task control capabilities}
If a new task is created, it is always associated with a task control
capability.  The task control capability can be used to create and
destroy threads in the task, and destroy the task itself.  So the task
control capability gives the owner of a task control over it.  Task
control capabilities have the side effect that the task ID of this
task is not reused, as long as the task control capability is not
released.  Thus, having a task control capability affects the global
namespace of task IDs.  If a task is destroyed, task death
notifications are sent to holders of task control capabilities for
that task.

\begin{comment}
  A task is also implicitely destroyed when the last task control
  capability reference is released.
\end{comment}

\paragraph{Task info capabilities}
\label{taskinfocap}
Any task can create task info capabilities for other tasks.  Such task
info capabilities are used mainly in the IPC system (see section
\ref{ipc} on page \pageref{ipc}).  Task info capabilities have the
side effect that the task ID of this task is not reused, as long as
the task info capability is not released.  Thus, having a task info
capability affects the global namespace of task IDs.  If a task is
destroyed, task death notifications are sent to holders of task info
capabilities for that task.

\begin{comment}
  Because of that, holding task info capabilities must be restricted
  somehow.  Several strategies can be taken:

  \begin{itemize}
  \item Task death notifications can be monitored.  If there is no
    acknowdgement within a certain time period, the \texttt{task}
    server could be allowed to reuse the task ID anyway.  This is not
    a good strategy because it can considerably weaken the security of
    the system (capabilities might be leaked to tasks which reuse such
    a task ID reclaimed by force).
  \item The proc server can show dead task IDs which are not released
    yet, in analogy to the zombie processes in Unix.  It can also make
    available the list of tasks which prevent reusing the task ID, to
    allow users or the system administrator to clean up manually.
  \item Quotas can be used to punish users which do not acknowledge
    task death timely.  For example, if the number of tasks the user
    is allowed to create is restricted, the task info caps that the
    user holds for dead tasks could be counted toward that limit.
  \item Any task could be restricted to as many task ID references as
    there are live tasks in the system, plus some slack.  That would
    prevent the task from creating new task info caps if it does not
    release old ones from death tasks.  The slack would be provided to
    not unnecessarily slow down a task that processes task death
    notifications asynchronously to making connections with new tasks.
  \end{itemize}
  
  In particular the last two approaches should proof to be effective
  in providing an incentive for tasks to release task info caps they
  do not need anymore.
\end{comment}

\paragraph{Task manager capability}
A task is a relatively simple object, compared to a full blown POSIX
process, for example.  As the \texttt{task} server is enforced system
code, the Hurd does not impose POSIX process semantics in the task
server.  Instead, POSIX process semantics are implemented in a
different server, the proc server (see also section \ref{proc} on page
\pageref{proc}).  To allow the \texttt{proc} server to do its work, it
needs to be able to get the task control capability for any task, and
gather other statistics about them.  Furthermore, there must be the
possibility to install quota mechanisms and other monitoring systems.
The \texttt{task} server provides a task manager capability, that
allows the holder of that capability to control the behaviour of the
\texttt{task} server and get access to the information and objects it
provides.

\begin{comment}
  For example, the task manager capability could be used to install a
  policy capability that is used by the \texttt{task} server to make
  upcalls to a policy server whenever a new task or thread is created.
  The policy server could then indicate if the creation of the task or
  thread is allowed by that user.  For this to work, the \texttt{task}
  server itself does not need to know about the concept of a user, or
  the policies that the policy server implements.
  
  Now that I am writing this, I realize that without any further
  support by the \texttt{task} server, the policy server would be
  restricted to the task and thread ID of the caller (or rather the
  task control capability used) to make its decision.  A more
  capability oriented approach would then not be possible.  This
  requires more thought.
  
  The whole task manager interface is not written yet.
\end{comment}

When creating a new task, the \texttt{task} server allocates a new
task ID for it.  The task ID will be used as the version field of the
thread ID of all threads created in the task.  This allows the
recipient of a message to verify the sender's task ID efficiently and
easily.

\begin{comment}
  The version field is 14 bit on 32-bit architectures, and 32 bit on
  64 bit architectures.  Because the lower six bits must not be all
  zero (to make global thread IDs different from local thread IDs),
  the number of available task IDs is $2^{14} - 2^6$ resp. $2^{32} -
  2^6$.
  
  If several systems are running in parallel on the same host, they
  might share thread IDs by encoding the system ID in the upper bits
  of the thread number.
\end{comment}

Task IDs will be reused only if there are no task control or info
capabilities for that task ID held by any task in the system.  To
support bootstrapping an IPC connection (see section
\ref{ipcbootstrap} on page \pageref{ipcbootstrap}), the \texttt{task}
server will delay reusing a task ID as long as possible.

\begin{comment}
  This is similar to how PIDs are generated in Unix.  Although it is
  attempted to keep PIDs small for ease of use, PIDs are not reused
  immediately.  Instead, the PID is incremented up to a certain
  maximum number, and only then smaller PID values are reused again.
  
  As task IDs are not a user interface, there is no need to keep them
  small.  The whole available range can be used to delay reusing a
  task ID as long as possible.
\end{comment}

When creating a new task, the \texttt{task} server also has to create
the initial thread.  This thread will be inactive.  Once the creation
and activation of the initial thread has been requested by the user,
it will be activated.  When the user requests to destroy the last
thread in a task, the \texttt{task} server makes that thread inactive
again.

\begin{comment}
  In L4, an address space can only be implicitely created (resp.
  destroyed) with the first (resp. last) thread in that address space.
\end{comment}

Some operations, like starting and stopping threads in a task, can not
be supported by the task server, but have to be implemented locally in
each task because of the minimality of L4.  If external control over
the threads in a task at this level is required, the debugger
interface might be used (see section \ref{debug} on page
\pageref{debug}).


\section{Accounting}

We want to allow the users of the system to use the \texttt{task}
server directly, and ignore other task management facilities like the
\texttt{proc} server.  However, the system administrator still needs
to be able to identify the user who created such anonymous tasks.

For this, a simple accounting mechanism is provided by the task
server.  An identifier can be set for a task by the task manager
capability, which is inherited at task creation time from the parent
task.  This accounting ID can not be changed without the task manager
capability.

The \texttt{proc} server sets the accounting ID to the process ID
(PID) of the task whenever a task registers itself with the
\texttt{proc} server.  This means that all tasks which do not register
themself with the \texttt{proc} server will be grouped together with
the first parent task that did.  This allows to easily kill all
unregistered tasks together with its registered parent.

The \texttt{task} server does not interpret or use the accounting ID
in any way.


\section{Proxy Task Server}
\label{proxytaskserver}

The \texttt{task} server can be safely proxied, and the users of such
a proxy task server can use it like the real \texttt{task} server,
even though capabilities work a bit differently for the \texttt{task}
server than for other servers.

The problem exists because the proxy task server would hold the real
task info capabilities for the task info capabilities that it provides
to the proxied task.  So if the proxy task server dies, all such task
info capabilities would be released, and the tasks using the proxy
task server would become insecure and open to attacks by imposters.

However, this is not really a problem, because the proxy task server
will also provide proxy objects for all task control capabilities.  So
it will be the only task which holds task control capabilities for the
tasks that use it.  When the proxy task server dies, all tasks that
were created with it will be destroyed when these tak control
capabilities are released.  The proxy task server is a vital system
component for the tasks that use it, just as the real \texttt{task}
server is a vital system component for the whole system.


\section{Scheduling}

The task server is the natural place to implement a simple, initial
scheduler for the Hurd.  A first version can at least collect some
information about the cpu time of a task and its threads.  Later a
proper scheduler has to be written that also has SMP support.

The scheduler should run at a higher priority than normal threads.

\begin{comment}
  This might require that the whole task server must run at a higher
  priority, which makes sense anyway.
  
  Not much thought has been given to the scheduler so far.  This is
  work that still needs to be done.
\end{comment}

There is no way to get at the ``system time'' in L4, it is assumed
that no time is spent in the kernel (which is mostly true).  So system
time will always be reported as $0.00$, or $0.01$.


