Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2016 Wind River Systems, Inc. |
| 3 | * |
David B. Kinder | ac74d8b | 2017-01-18 17:01:01 -0800 | [diff] [blame] | 4 | * SPDX-License-Identifier: Apache-2.0 |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 5 | */ |
| 6 | |
Stephanos Ioannidis | 2d74604 | 2019-10-25 00:08:21 +0900 | [diff] [blame] | 7 | /* |
| 8 | * The purpose of this file is to provide essential/minimal kernel structure |
| 9 | * definitions, so that they can be used without including kernel.h. |
| 10 | * |
| 11 | * The following rules must be observed: |
| 12 | * 1. kernel_structs.h shall not depend on kernel.h both directly and |
| 13 | * indirectly (i.e. it shall not include any header files that include |
| 14 | * kernel.h in their dependency chain). |
| 15 | * 2. kernel.h shall imply kernel_structs.h, such that it shall not be |
| 16 | * necessary to include kernel_structs.h explicitly when kernel.h is |
| 17 | * included. |
| 18 | */ |
| 19 | |
Flavio Ceolin | a7fffa9 | 2018-09-13 15:06:35 -0700 | [diff] [blame] | 20 | #ifndef ZEPHYR_KERNEL_INCLUDE_KERNEL_STRUCTS_H_ |
| 21 | #define ZEPHYR_KERNEL_INCLUDE_KERNEL_STRUCTS_H_ |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 22 | |
Benjamin Walsh | dfa7ce5 | 2017-01-22 17:06:05 -0500 | [diff] [blame] | 23 | #if !defined(_ASMLANGUAGE) |
Andy Ross | 0dd83b8 | 2020-04-03 10:01:03 -0700 | [diff] [blame] | 24 | #include <sys/atomic.h> |
Stephanos Ioannidis | 2d74604 | 2019-10-25 00:08:21 +0900 | [diff] [blame] | 25 | #include <zephyr/types.h> |
Anas Nashif | 8b3f36c | 2021-06-14 17:04:04 -0400 | [diff] [blame] | 26 | #include <kernel/sched_priq.h> |
Anas Nashif | ee9dd1a | 2019-06-26 10:33:41 -0400 | [diff] [blame] | 27 | #include <sys/dlist.h> |
Anas Nashif | a2fd7d7 | 2019-06-26 10:33:55 -0400 | [diff] [blame] | 28 | #include <sys/util.h> |
Andy Ross | 0dd83b8 | 2020-04-03 10:01:03 -0700 | [diff] [blame] | 29 | #include <sys/sys_heap.h> |
Nicolas Pitre | f97d129 | 2021-04-15 16:27:45 -0400 | [diff] [blame] | 30 | #include <arch/structs.h> |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 31 | #endif |
| 32 | |
Marcin Zwierz | 4cae9b8 | 2021-06-09 08:06:35 +0200 | [diff] [blame] | 33 | #ifdef __cplusplus |
| 34 | extern "C" { |
| 35 | #endif |
| 36 | |
Andy Ross | 8ac9c08 | 2017-12-08 17:38:12 -0800 | [diff] [blame] | 37 | #define K_NUM_PRIORITIES \ |
| 38 | (CONFIG_NUM_COOP_PRIORITIES + CONFIG_NUM_PREEMPT_PRIORITIES + 1) |
| 39 | |
| 40 | #define K_NUM_PRIO_BITMAPS ((K_NUM_PRIORITIES + 31) >> 5) |
| 41 | |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 42 | /* |
Benjamin Walsh | ed240f2 | 2017-01-22 13:05:08 -0500 | [diff] [blame] | 43 | * Bitmask definitions for the struct k_thread.thread_state field. |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 44 | * |
| 45 | * Must be before kerneL_arch_data.h because it might need them to be already |
| 46 | * defined. |
| 47 | */ |
| 48 | |
Benjamin Walsh | f955476 | 2016-12-21 15:38:54 -0500 | [diff] [blame] | 49 | /* states: common uses low bits, arch-specific use high bits */ |
| 50 | |
Benjamin Walsh | 867f8ee | 2017-01-22 11:51:25 -0500 | [diff] [blame] | 51 | /* Not a real thread */ |
Flavio Ceolin | 8aec087 | 2018-08-15 11:52:00 -0700 | [diff] [blame] | 52 | #define _THREAD_DUMMY (BIT(0)) |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 53 | |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 54 | /* Thread is waiting on an object */ |
Flavio Ceolin | 8aec087 | 2018-08-15 11:52:00 -0700 | [diff] [blame] | 55 | #define _THREAD_PENDING (BIT(1)) |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 56 | |
| 57 | /* Thread has not yet started */ |
Flavio Ceolin | 8aec087 | 2018-08-15 11:52:00 -0700 | [diff] [blame] | 58 | #define _THREAD_PRESTART (BIT(2)) |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 59 | |
| 60 | /* Thread has terminated */ |
Flavio Ceolin | 8aec087 | 2018-08-15 11:52:00 -0700 | [diff] [blame] | 61 | #define _THREAD_DEAD (BIT(3)) |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 62 | |
| 63 | /* Thread is suspended */ |
Flavio Ceolin | 8aec087 | 2018-08-15 11:52:00 -0700 | [diff] [blame] | 64 | #define _THREAD_SUSPENDED (BIT(4)) |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 65 | |
Andrew Boie | f5a7e1a | 2020-09-02 09:20:38 -0700 | [diff] [blame] | 66 | /* Thread is being aborted */ |
Andy Ross | 42ed12a | 2019-02-19 16:03:39 -0800 | [diff] [blame] | 67 | #define _THREAD_ABORTING (BIT(5)) |
| 68 | |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 69 | /* Thread is present in the ready queue */ |
Andy Ross | e06ba70 | 2020-01-14 06:26:10 -0800 | [diff] [blame] | 70 | #define _THREAD_QUEUED (BIT(7)) |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 71 | |
Benjamin Walsh | f955476 | 2016-12-21 15:38:54 -0500 | [diff] [blame] | 72 | /* end - states */ |
| 73 | |
Andrew Boie | 5dcb279 | 2017-05-11 13:29:15 -0700 | [diff] [blame] | 74 | #ifdef CONFIG_STACK_SENTINEL |
| 75 | /* Magic value in lowest bytes of the stack */ |
| 76 | #define STACK_SENTINEL 0xF0F0F0F0 |
| 77 | #endif |
Benjamin Walsh | f955476 | 2016-12-21 15:38:54 -0500 | [diff] [blame] | 78 | |
Benjamin Walsh | 168695c | 2016-12-21 16:00:35 -0500 | [diff] [blame] | 79 | /* lowest value of _thread_base.preempt at which a thread is non-preemptible */ |
Aastha Grover | 83b9f69 | 2020-08-20 16:47:11 -0700 | [diff] [blame] | 80 | #define _NON_PREEMPT_THRESHOLD 0x0080U |
Benjamin Walsh | 168695c | 2016-12-21 16:00:35 -0500 | [diff] [blame] | 81 | |
| 82 | /* highest value of _thread_base.preempt at which a thread is preemptible */ |
Aastha Grover | 83b9f69 | 2020-08-20 16:47:11 -0700 | [diff] [blame] | 83 | #define _PREEMPT_THRESHOLD (_NON_PREEMPT_THRESHOLD - 1U) |
Benjamin Walsh | b2974a6 | 2016-11-24 14:08:08 -0500 | [diff] [blame] | 84 | |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 85 | #if !defined(_ASMLANGUAGE) |
| 86 | |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 87 | struct _ready_q { |
Andy Ross | 2724fd1 | 2018-01-29 14:55:20 -0800 | [diff] [blame] | 88 | #ifndef CONFIG_SMP |
Benjamin Walsh | 04ed860 | 2016-12-21 14:36:43 -0500 | [diff] [blame] | 89 | /* always contains next thread to run: cannot be NULL */ |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 90 | struct k_thread *cache; |
Andy Ross | 2724fd1 | 2018-01-29 14:55:20 -0800 | [diff] [blame] | 91 | #endif |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 92 | |
Andy Ross | 9f06a35 | 2018-06-28 10:38:14 -0700 | [diff] [blame] | 93 | #if defined(CONFIG_SCHED_DUMB) |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 94 | sys_dlist_t runq; |
Andy Ross | 9f06a35 | 2018-06-28 10:38:14 -0700 | [diff] [blame] | 95 | #elif defined(CONFIG_SCHED_SCALABLE) |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 96 | struct _priq_rb runq; |
Andy Ross | 9f06a35 | 2018-06-28 10:38:14 -0700 | [diff] [blame] | 97 | #elif defined(CONFIG_SCHED_MULTIQ) |
| 98 | struct _priq_mq runq; |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 99 | #endif |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 100 | }; |
| 101 | |
Benjamin Walsh | 88b3691 | 2016-12-02 10:37:27 -0500 | [diff] [blame] | 102 | typedef struct _ready_q _ready_q_t; |
| 103 | |
Andy Ross | e694656 | 2018-01-25 16:39:35 -0800 | [diff] [blame] | 104 | struct _cpu { |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 105 | /* nested interrupt count */ |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 106 | uint32_t nested; |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 107 | |
| 108 | /* interrupt stack pointer base */ |
| 109 | char *irq_stack; |
| 110 | |
| 111 | /* currently scheduled thread */ |
| 112 | struct k_thread *current; |
Andy Ross | 2724fd1 | 2018-01-29 14:55:20 -0800 | [diff] [blame] | 113 | |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 114 | /* one assigned idle thread per CPU */ |
| 115 | struct k_thread *idle_thread; |
| 116 | |
Andy Ross | 11a050b | 2019-11-13 09:41:52 -0800 | [diff] [blame] | 117 | #if (CONFIG_NUM_METAIRQ_PRIORITIES > 0) && (CONFIG_NUM_COOP_PRIORITIES > 0) |
| 118 | /* Coop thread preempted by current metairq, or NULL */ |
| 119 | struct k_thread *metairq_preempted; |
| 120 | #endif |
| 121 | |
Andy Ross | 9098a45 | 2018-09-25 10:56:09 -0700 | [diff] [blame] | 122 | #ifdef CONFIG_TIMESLICING |
| 123 | /* number of ticks remaining in current time slice */ |
| 124 | int slice_ticks; |
| 125 | #endif |
| 126 | |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 127 | uint8_t id; |
Andy Ross | eace1df | 2018-05-30 11:23:02 -0700 | [diff] [blame] | 128 | |
| 129 | #ifdef CONFIG_SMP |
| 130 | /* True when _current is allowed to context switch */ |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 131 | uint8_t swap_ok; |
Andy Ross | eace1df | 2018-05-30 11:23:02 -0700 | [diff] [blame] | 132 | #endif |
Nicolas Pitre | f97d129 | 2021-04-15 16:27:45 -0400 | [diff] [blame] | 133 | |
| 134 | /* Per CPU architecture specifics */ |
| 135 | struct _cpu_arch arch; |
Andy Ross | e694656 | 2018-01-25 16:39:35 -0800 | [diff] [blame] | 136 | }; |
| 137 | |
| 138 | typedef struct _cpu _cpu_t; |
| 139 | |
Flavio Ceolin | a406b88 | 2018-11-01 17:50:02 -0700 | [diff] [blame] | 140 | struct z_kernel { |
Andrew Boie | a203d21 | 2020-03-16 10:18:03 -0700 | [diff] [blame] | 141 | struct _cpu cpus[CONFIG_MP_NUM_CPUS]; |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 142 | |
| 143 | #ifdef CONFIG_SYS_CLOCK_EXISTS |
| 144 | /* queue of timeouts */ |
| 145 | sys_dlist_t timeout_q; |
| 146 | #endif |
| 147 | |
Anas Nashif | dd931f9 | 2020-09-01 18:31:40 -0400 | [diff] [blame] | 148 | #ifdef CONFIG_PM |
Kumar Gala | a1b77fd | 2020-05-27 11:26:57 -0500 | [diff] [blame] | 149 | int32_t idle; /* Number of ticks for kernel idling */ |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 150 | #endif |
| 151 | |
| 152 | /* |
| 153 | * ready queue: can be big, keep after small fields, since some |
Benjamin Walsh | ba26678 | 2016-11-14 10:17:30 -0500 | [diff] [blame] | 154 | * assembly (e.g. ARC) are limited in the encoding of the offset |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 155 | */ |
| 156 | struct _ready_q ready_q; |
| 157 | |
Stephanos Ioannidis | aaf9320 | 2020-05-03 18:03:19 +0900 | [diff] [blame] | 158 | #ifdef CONFIG_FPU_SHARING |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 159 | /* |
| 160 | * A 'current_sse' field does not exist in addition to the 'current_fp' |
| 161 | * field since it's not possible to divide the IA-32 non-integer |
| 162 | * registers into 2 distinct blocks owned by differing threads. In |
| 163 | * other words, given that the 'fxnsave/fxrstor' instructions |
| 164 | * save/restore both the X87 FPU and XMM registers, it's not possible |
| 165 | * for a thread to only "own" the XMM registers. |
| 166 | */ |
| 167 | |
Anas Nashif | 780324b | 2017-10-29 07:10:22 -0400 | [diff] [blame] | 168 | /* thread that owns the FP regs */ |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 169 | struct k_thread *current_fp; |
| 170 | #endif |
| 171 | |
| 172 | #if defined(CONFIG_THREAD_MONITOR) |
Anas Nashif | 780324b | 2017-10-29 07:10:22 -0400 | [diff] [blame] | 173 | struct k_thread *threads; /* singly linked list of ALL threads */ |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 174 | #endif |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 175 | }; |
| 176 | |
Flavio Ceolin | a406b88 | 2018-11-01 17:50:02 -0700 | [diff] [blame] | 177 | typedef struct z_kernel _kernel_t; |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 178 | |
Flavio Ceolin | a406b88 | 2018-11-01 17:50:02 -0700 | [diff] [blame] | 179 | extern struct z_kernel _kernel; |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 180 | |
Andy Ross | e694656 | 2018-01-25 16:39:35 -0800 | [diff] [blame] | 181 | #ifdef CONFIG_SMP |
Andy Ross | eefd3da | 2020-02-06 13:39:52 -0800 | [diff] [blame] | 182 | |
| 183 | /* True if the current context can be preempted and migrated to |
| 184 | * another SMP CPU. |
| 185 | */ |
| 186 | bool z_smp_cpu_mobile(void); |
| 187 | |
| 188 | #define _current_cpu ({ __ASSERT_NO_MSG(!z_smp_cpu_mobile()); \ |
| 189 | arch_curr_cpu(); }) |
Andrew Boie | f07df42 | 2020-11-06 13:11:12 -0800 | [diff] [blame] | 190 | #define _current z_current_get() |
Andy Ross | eefd3da | 2020-02-06 13:39:52 -0800 | [diff] [blame] | 191 | |
Andy Ross | e694656 | 2018-01-25 16:39:35 -0800 | [diff] [blame] | 192 | #else |
Andy Ross | 1acd8c2 | 2018-05-03 14:51:49 -0700 | [diff] [blame] | 193 | #define _current_cpu (&_kernel.cpus[0]) |
Andrew Boie | a203d21 | 2020-03-16 10:18:03 -0700 | [diff] [blame] | 194 | #define _current _kernel.cpus[0].current |
Andy Ross | e694656 | 2018-01-25 16:39:35 -0800 | [diff] [blame] | 195 | #endif |
| 196 | |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 197 | #define _timeout_q _kernel.timeout_q |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 198 | |
Andy Ross | 41220d2 | 2020-03-31 09:17:09 -0700 | [diff] [blame] | 199 | /* kernel wait queue record */ |
| 200 | |
| 201 | #ifdef CONFIG_WAITQ_SCALABLE |
| 202 | |
| 203 | typedef struct { |
| 204 | struct _priq_rb waitq; |
| 205 | } _wait_q_t; |
| 206 | |
| 207 | extern bool z_priq_rb_lessthan(struct rbnode *a, struct rbnode *b); |
| 208 | |
| 209 | #define Z_WAIT_Q_INIT(wait_q) { { { .lessthan_fn = z_priq_rb_lessthan } } } |
| 210 | |
| 211 | #else |
| 212 | |
| 213 | typedef struct { |
| 214 | sys_dlist_t waitq; |
| 215 | } _wait_q_t; |
| 216 | |
| 217 | #define Z_WAIT_Q_INIT(wait_q) { SYS_DLIST_STATIC_INIT(&(wait_q)->waitq) } |
| 218 | |
| 219 | #endif |
| 220 | |
| 221 | /* kernel timeout record */ |
| 222 | |
| 223 | struct _timeout; |
| 224 | typedef void (*_timeout_func_t)(struct _timeout *t); |
| 225 | |
| 226 | struct _timeout { |
| 227 | sys_dnode_t node; |
Andy Ross | 41220d2 | 2020-03-31 09:17:09 -0700 | [diff] [blame] | 228 | _timeout_func_t fn; |
Andy Ross | 150e18d | 2020-06-17 08:56:40 -0700 | [diff] [blame] | 229 | #ifdef CONFIG_TIMEOUT_64BIT |
| 230 | /* Can't use k_ticks_t for header dependency reasons */ |
Peter Bigot | 5f0991d | 2020-09-03 14:30:04 -0500 | [diff] [blame] | 231 | int64_t dticks; |
Andy Ross | 150e18d | 2020-06-17 08:56:40 -0700 | [diff] [blame] | 232 | #else |
Peter Bigot | 5f0991d | 2020-09-03 14:30:04 -0500 | [diff] [blame] | 233 | int32_t dticks; |
Andy Ross | 150e18d | 2020-06-17 08:56:40 -0700 | [diff] [blame] | 234 | #endif |
Andy Ross | 41220d2 | 2020-03-31 09:17:09 -0700 | [diff] [blame] | 235 | }; |
| 236 | |
Marcin Zwierz | 4cae9b8 | 2021-06-09 08:06:35 +0200 | [diff] [blame] | 237 | #ifdef __cplusplus |
| 238 | } |
| 239 | #endif |
| 240 | |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 241 | #endif /* _ASMLANGUAGE */ |
| 242 | |
Flavio Ceolin | a7fffa9 | 2018-09-13 15:06:35 -0700 | [diff] [blame] | 243 | #endif /* ZEPHYR_KERNEL_INCLUDE_KERNEL_STRUCTS_H_ */ |