1 /*
2 * Copyright (c) 2010-2015 Wind River Systems, Inc.
3 * Copyright (c) 2017 Oticon A/S
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /**
9 * @file
10 * @brief Thread support primitives
11 *
12 * This module provides core thread related primitives for the POSIX
13 * architecture
14 */
15
16 #include <zephyr/toolchain.h>
17 #include <zephyr/kernel_structs.h>
18 #include <ksched.h>
19
20 #include "posix_core.h"
21 #include <zephyr/arch/posix/posix_soc_if.h>
22
23 /* Note that in this arch we cheat quite a bit: we use as stack a normal
24 * pthreads stack and therefore we ignore the stack size
25 */
arch_new_thread(struct k_thread * thread,k_thread_stack_t * stack,char * stack_ptr,k_thread_entry_t entry,void * p1,void * p2,void * p3)26 void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack,
27 char *stack_ptr, k_thread_entry_t entry,
28 void *p1, void *p2, void *p3)
29 {
30
31 posix_thread_status_t *thread_status;
32
33 /* We store it in the same place where normal archs store the
34 * "initial stack frame"
35 */
36 thread_status = Z_STACK_PTR_TO_FRAME(posix_thread_status_t, stack_ptr);
37
38 /* z_thread_entry() arguments */
39 thread_status->entry_point = entry;
40 thread_status->arg1 = p1;
41 thread_status->arg2 = p2;
42 thread_status->arg3 = p3;
43 #if defined(CONFIG_ARCH_HAS_THREAD_ABORT)
44 thread_status->aborted = 0;
45 #endif
46
47 thread->callee_saved.thread_status = thread_status;
48
49 thread_status->thread_idx = posix_new_thread((void *)thread_status);
50 }
51
posix_arch_thread_entry(void * pa_thread_status)52 void posix_arch_thread_entry(void *pa_thread_status)
53 {
54 posix_thread_status_t *ptr = pa_thread_status;
55 posix_irq_full_unlock();
56 z_thread_entry(ptr->entry_point, ptr->arg1, ptr->arg2, ptr->arg3);
57 }
58
59 #if defined(CONFIG_ARCH_HAS_THREAD_ABORT)
z_impl_k_thread_abort(k_tid_t thread)60 void z_impl_k_thread_abort(k_tid_t thread)
61 {
62 unsigned int key;
63 int thread_idx;
64
65 posix_thread_status_t *tstatus =
66 (posix_thread_status_t *)
67 thread->callee_saved.thread_status;
68
69 thread_idx = tstatus->thread_idx;
70
71 key = irq_lock();
72
73 if (_current == thread) {
74 if (tstatus->aborted == 0) { /* LCOV_EXCL_BR_LINE */
75 tstatus->aborted = 1;
76 } else {
77 posix_print_warning(/* LCOV_EXCL_LINE */
78 "POSIX arch: The kernel is trying to abort and swap "
79 "out of an already aborted thread %i. This "
80 "should NOT have happened\n",
81 thread_idx);
82 }
83 posix_abort_thread(thread_idx);
84 }
85
86 z_thread_abort(thread);
87
88 if (tstatus->aborted == 0) {
89 PC_DEBUG("%s aborting now [%i] %i\n",
90 __func__,
91 posix_arch_get_unique_thread_id(thread_idx),
92 thread_idx);
93
94 tstatus->aborted = 1;
95 posix_abort_thread(thread_idx);
96 } else {
97 PC_DEBUG("%s ignoring re_abort of [%i] "
98 "%i\n",
99 __func__,
100 posix_arch_get_unique_thread_id(thread_idx),
101 thread_idx);
102 }
103
104 /* The abort handler might have altered the ready queue. */
105 z_reschedule_irqlock(key);
106 }
107 #endif
108