Loading...
Searching...
No Matches
Pthread Support

L4Re supports the standard pthread library functionality. Therefore L4Re itself does not contain any documentation for pthreads itself. Please refer to the standard pthread documentation instead.

The L4Re specific parts will be described herein.

- Include pthread-l4.h header file:

  #include <pthread-l4.h>

- Return the local thread capability of a pthread thread:

  Use `pthread_l4_cap(pthread_t t)` to get the capability index of the pthread t.

  For example:

  pthread_l4_cap(pthread_self());

- Setting the L4 priority of an L4 thread works with a special scheduling policy (other policies do not affect the L4 thread priority):

  pthread_t t;
  pthread_attr_t a;
  struct sched_param sp;
  pthread_attr_init(&a);
  sp.sched_priority = l4_priority;
  pthread_attr_setschedpolicy(&a, SCHED_L4);
  pthread_attr_setschedparam(&a, &sp);
  pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
  if (pthread_create(&t, &a, pthread_func, NULL))
  // failure...
  pthread_attr_destroy(&a);

- You can prevent your pthread from running immediately after the call to `pthread_create`(..) by adding `PTHREAD_L4_ATTR_NO_START` to the `create_flags` of the pthread attributes. To finally start the thread you need to call `scheduler()->run_thread()` passing the capability of the pthread and scheduling parameters.

  pthread_t t;
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  attr.create_flags |= PTHREAD_L4_ATTR_NO_START;
  if (pthread_create(&t, &attr, pthread_func, nullptr))
  // failure...
  pthread_attr_destroy(&attr);
  // do stuff
  auto ret = L4Re::Env::env()->scheduler()->run_thread(pthread_l4_cap(t),
  l4_sched_param(2));
  if (l4_error(ret))
  // failure...
  L4Re::Env::scheduler
  L4::Cap< L4::Scheduler > scheduler() const noexcept
  Get the scheduler capability for the task.
  Definition env:275
  L4Re::Env::env
  static Env const * env() noexcept
  Returns the initial environment for the current task.
  Definition env:96
  l4_error
  long l4_error(l4_msgtag_t tag) L4_NOTHROW
  Get IPC error code if any or message tag label otherwise for an IPC call.
  Definition ipc.h:646
  l4_sched_param
  l4_sched_param_t l4_sched_param(unsigned prio, l4_umword_t quantum=0) L4_NOTHROW
  Construct scheduler parameter.
  Definition scheduler.h:289

#### Constraints on pthread_t, user-land capability slot, and kernel thread-object

- pthread_l4_cap() is guaranteed to return the valid capability slot of the pthread (A) until pthread_join() or pthread_detach() is invoked on (A)'s pthread_t.

- pthread_l4_cap() exposes internal state of the pthread management, take the necessary precautions as you would for any shared data in concurrent environments. If you use pthread_l4_cap() guarding against concurrency issues is your duty.

- There is no guarantee that a valid capability slot points to a present capability.

- Example

  It is possible to obtain a valid thread capability slot and for l4_task_cap_valid() to return the capability as not present. The following example showcases a possible sequence of events.

  // Assume: void some_func(void *)
  pthread_t pthread = nullptr;
  pthread_create(&pthread, nullptr, some_func, nullptr);
  // pthread running some_func()
  l4_cap_idx_t cap_idx = pthread_l4_cap(pthread);
  l4_is_valid_cap(cap_idx); // ---> true
  long valid = l4_task_cap_valid(L4RE_THIS_TASK_CAP, cap_idx).label());
  // valid == 1 --> capability object is present (refers to a kernel object).
  // some_func() exits
  cap_idx = pthread_l4_cap(pthread);
  l4_is_valid_cap(cap_idx); // ---> true
  valid = l4_task_cap_valid(L4RE_THIS_TASK_CAP, cap_idx).label());
  // valid == 0 --> capability object is not present (refers to no kernel object).
  pthread_join(pthread, nullptr); // invalidates the cap slot and frees
  // the pthread's data structures
  // using cap_idx here is undefined behavior.
  l4_cap_idx_t
  unsigned long l4_cap_idx_t
  Capability selector type.
  Definition types.h:336
  l4_is_valid_cap
  unsigned l4_is_valid_cap(l4_cap_idx_t c) L4_NOTHROW
  Test if a capability selector is a valid selector.
  Definition types.h:393
  l4_task_cap_valid
  l4_msgtag_t l4_task_cap_valid(l4_cap_idx_t task, l4_cap_idx_t cap) L4_NOTHROW
  Check whether a capability is present (refers to an object).
  Definition task.h:484
  l4_msgtag_t::label
  long label() const L4_NOTHROW
  Get the protocol value.
  Definition types.h:158