zephyr/samples/philosophers
Gerard Marull-Paretas 260deccb6e doc: use :kconfig:option: domain role
Kconfig options now belong to the Kconfig domain, therefore, the
:kconfig:option: role needs to be used.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-03-02 09:28:37 +01:00
..
src kconfig: Rename the TEST_EXTRA stack size option to align with the rest 2022-02-22 08:23:05 -05:00
CMakeLists.txt
README.rst doc: use :kconfig:option: domain role 2022-03-02 09:28:37 +01:00
prj.conf
prj_tickless.conf
sample.yaml samples: fix wrong extra_args definitions 2022-01-04 17:15:06 -05:00

README.rst

.. _dining-philosophers-sample:

Dining Philosophers
###################

Overview
********

An implementation of a solution to the Dining Philosophers problem (a classic
multi-thread synchronization problem).  This particular implementation
demonstrates the usage of multiple preemptible and cooperative threads of
differing priorities, as well as dynamic mutexes and thread sleeping.

The philosopher always tries to get the lowest fork first (f1 then f2).  When
done, he will give back the forks in the reverse order (f2 then f1).  If he
gets two forks, he is EATING.  Otherwise, he is THINKING. Transitional states
are shown as well, such as STARVING when the philosopher is hungry but the
forks are not available, and HOLDING ONE FORK when a philosopher is waiting
for the second fork to be available.

Each Philosopher will randomly alternate between the EATING and THINKING state.

It is possible to run the demo in coop-only or preempt-only mode. To achieve
this, set these values for CONFIG_NUM_COOP_PRIORITIES and
CONFIG_NUM_PREEMPT_PRIORITIES in prj.conf:

preempt-only:

  CONFIG_NUM_PREEMPT_PRIORITIES 6
  CONFIG_NUM_COOP_PRIORITIES 0

coop-only:

  CONFIG_NUM_PREEMPT_PRIORITIES 0
  CONFIG_NUM_COOP_PRIORITIES 6

In these cases, the philosopher threads will run with priorities 0 to 5
(preempt-only) and -7 to -2 (coop-only).

Building and Running
********************

This project outputs to the console.  It can be built and executed
on QEMU as follows:

.. zephyr-app-commands::
   :zephyr-app: samples/philosophers
   :host-os: unix
   :board: qemu_x86
   :goals: run
   :compact:

Sample Output
=============

.. code-block:: console

   Philosopher 0 [P: 3]  HOLDING ONE FORK
   Philosopher 1 [P: 2]  HOLDING ONE FORK
   Philosopher 2 [P: 1]  EATING  [ 1900 ms ]
   Philosopher 3 [P: 0]  THINKING [ 2500 ms ]
   Philosopher 4 [C:-1]  THINKING [ 2200 ms ]
   Philosopher 5 [C:-2]  THINKING [ 1700 ms ]

Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`.

Debug Threads
*************

The philosophers sample by default enables :kconfig:option:`CONFIG_DEBUG_THREAD_INFO`.
This allows tools like OpenOCD and J-link to inspect thread data using
``info threads``.

.. zephyr-app-commands::
   :zephyr-app: samples/philosophers
   :host-os: unix
   :board: <board_name>
   :goals: debug
   :compact:


OpenOCD Sample Output
=====================

.. code-block:: console

   Thread 1 received signal SIGINT, Interrupt.
   [Switching to Thread 537003160]
   arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107
   107		cpsie	i
   (gdb) i threads
     Id   Target Id                                                  Frame
   * 1    Thread 537003160 (Name: idle 00, prio:40,useropts:1)       arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107
   Info : Getting thread 537002984 reg list
     2    Thread 537002984 (Name: Philosopher 5, prio:-2,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95
   Info : Getting thread 537002808 reg list
     3    Thread 537002808 (Name: Philosopher 4, prio:-1,useropts:4) 0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95
   Info : Getting thread 537002632 reg list
     4    Thread 537002632 (Name: Philosopher 3, prio:0,useropts:4)  0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95
   Info : Getting thread 537002456 reg list
     5    Thread 537002456 (Name: Philosopher 2, prio:1,useropts:4)  0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95
   Info : Getting thread 537002280 reg list
     6    Thread 537002280 (Name: Philosopher 1, prio:2,useropts:4)  0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95
   Info : Getting thread 537002104 reg list
     7    Thread 537002104 (Name: Philosopher 0, prio:3,useropts:4)  0x08001404 in arch_irq_unlock (key=0) at zephyr/mainline/zephyr/include/arch/arm/aarch32/asm_inline_gcc.h:95

.. code-block:: console

   Philosopher 0 [P: 3]        STARVING
   Philosopher 1 [P: 2]    HOLDING ONE FORK
   Philosopher 2 [P: 1]   EATING  [  400 ms ]
   Philosopher 3 [P: 0]  THINKING [  525 ms ]
   Philosopher 4 [C:-1]    HOLDING ONE FORK
   Philosopher 5 [C:-2]   EATING  [  625 ms ]


J-Link Sample Output
====================

.. code-block:: console

   Thread 2 received signal SIGTRAP, Trace/breakpoint trap.
   [Switching to Thread 537920592]
   arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107
   107		cpsie	i
   (gdb) i threads
     Id   Target Id                                           Frame
   * 2    Thread 537920592 (idle 00 UNKNOWN PRIO 40)          arch_cpu_idle () at zephyr/mainline/zephyr/arch/arm/core/aarch32/cpu_idle.S:107
     3    Thread 537919536 (Philosopher 0 PENDING PRIO 3)     arch_swap (key=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53
     4    Thread 537919712 (Philosopher 1 SUSPENDED PRIO 2)   arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53
     5    Thread 537919888 (Philosopher 2 SUSPENDED PRIO 1)   arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53
     6    Thread 537920064 (Philosopher 3 SUSPENDED PRIO 0)   arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53
     7    Thread 537920240 (Philosopher 4 PENDING PRIO 255)   arch_swap (key=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53
     8    Thread 537920416 (Philosopher 5 SUSPENDED PRIO 254) arch_swap (key=key@entry=0) at zephyr/mainline/zephyr/arch/arm/core/aarch32/swap.c:53

.. code-block:: console

   Philosopher 0 [P: 3]        STARVING
   Philosopher 1 [P: 2]   EATING  [  475 ms ]
   Philosopher 2 [P: 1]  THINKING [  700 ms ]
   Philosopher 3 [P: 0]  THINKING [  525 ms ]
   Philosopher 4 [C:-1]    HOLDING ONE FORK
   Philosopher 5 [C:-2]   EATING  [  625 ms ]