| .. _common_contexts: |
| |
| Execution Context Services |
| ########################## |
| |
| Concepts |
| ******** |
| |
| Every kernel execution context has an associated *type* that indicates whether |
| the context is a task, a fiber, or the kernel's interrupt handling context. |
| |
| All task and fiber contexts have a unique *thread identifier* value used to |
| uniquely identify them. Each task and fiber can also support a 32-bit *thread |
| custom data* value. This value is accessible only by the task or fiber itself, |
| and may be used by the application for any purpose. The default custom data |
| value for a task or fiber is zero. |
| |
| .. note:: |
| The custom data value is not available to ISRs because these operate |
| only within the shared kernel interrupt handling context. |
| |
| The kernel permits a task or a fiber to perform a ``busy wait``, thus delaying |
| its processing for a specified time period. Such a delay occurs without |
| requiring the kernel to perform context switching, as it typically does with |
| timer and timeout services. |
| |
| |
| Purpose |
| ******* |
| |
| Use kernel execution context services when writing code that should |
| operate differently when it is executed by different contexts. |
| |
| Use the ``busy wait`` service when the required delay is too short to |
| warrant context switching to another task or fiber. The ``busy wait`` |
| service may also be used when performing a delay as part of the |
| nanokernel's background task in a nanokernel-only system; this task is |
| not allowed to voluntarily relinquish the CPU. |
| |
| |
| Usage |
| ***** |
| |
| Configuring Custom Data Support |
| =============================== |
| |
| Use the :option:`THREAD_CUSTOM_DATA` configuration option |
| to enable support for thread custom data. By default, custom data |
| support is disabled. |
| |
| |
| Example: Performing Execution Context-Specific Processing |
| ========================================================= |
| |
| This code shows how a routine can use a thread's custom data value |
| to limit the number of times a thread may call the routine. Note that |
| counting is not performed when the routine is called by an ISR; ISRs |
| do not have a custom data value. |
| |
| .. note:: |
| Obviously, only a single routine can use this technique |
| since it monopolizes the use of the custom data value. |
| |
| .. code-block:: c |
| |
| #define CALL_LIMIT 7 |
| |
| int call_tracking_routine(void) |
| { |
| uint32_t call_count; |
| |
| if (sys_execution_context_type_get() != NANO_CTX_ISR) { |
| call_count = (uint32_t)sys_thread_custom_data_get(); |
| if (call_count == CALL_LIMIT) |
| return -1; |
| call_count++; |
| sys_thread_custom_data_set((void *)call_count); |
| } |
| |
| /* do rest of routine's processing */ |
| ... |
| } |
| |
| APIs |
| **** |
| |
| The following kernel execution context APIs are common to both |
| :file:`microkernel.h` and :file:`nanokernel.h`: |
| |
| |
| :c:func:`sys_thread_self_get()` |
| Gets thread identifier of currently executing task or fiber. |
| |
| :c:func:`sys_execution_context_type_get()` |
| Gets type of currently executing context (i.e. task, fiber, or ISR). |
| |
| :c:func:`sys_thread_custom_data_set()` |
| Writes custom data for currently executing task or fiber. |
| |
| :c:func:`sys_thread_custom_data_get()` |
| Reads custom data for currently executing task or fiber. |