| 92 | ****************************************************************************/ |
| 93 | |
| 94 | int up_create_stack(struct tcb_s *tcb, size_t stack_size, uint8_t ttype) |
| 95 | { |
| 96 | #ifdef CONFIG_TLS |
| 97 | /* The allocated stack size must not exceed the maximum possible for the |
| 98 | * TLS feature. |
| 99 | */ |
| 100 | |
| 101 | DEBUGASSERT(stack_size <= TLS_MAXSTACK); |
| 102 | if (stack_size >= TLS_MAXSTACK) |
| 103 | { |
| 104 | stack_size = TLS_MAXSTACK; |
| 105 | } |
| 106 | #endif |
| 107 | |
| 108 | /* Is there already a stack allocated of a different size? Because of |
| 109 | * alignment issues, stack_size might erroneously appear to be of a |
| 110 | * different size. Fortunately, this is not a critical operation. |
| 111 | */ |
| 112 | |
| 113 | if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) |
| 114 | { |
| 115 | /* Yes.. Release the old stack */ |
| 116 | |
| 117 | up_release_stack(tcb, ttype); |
| 118 | } |
| 119 | |
| 120 | /* Do we need to allocate a new stack? */ |
| 121 | |
| 122 | if (!tcb->stack_alloc_ptr) |
| 123 | { |
| 124 | /* Allocate the stack. If DEBUG is enabled (but not stack debug), |
| 125 | * then create a zeroed stack to make stack dumps easier to trace. |
| 126 | * If TLS is enabled, then we must allocate aligned stacks. |
| 127 | */ |
| 128 | |
| 129 | #ifdef CONFIG_TLS |
| 130 | #ifdef HAVE_KERNEL_HEAP |
| 131 | /* Use the kernel allocator if this is a kernel thread */ |
| 132 | |
| 133 | if (ttype == TCB_FLAG_TTYPE_KERNEL) |
| 134 | { |
| 135 | tcb->stack_alloc_ptr = mm_memalign( |
| 136 | KMM_HEAP(CONFIG_ARCH_KERNEL_STACK_HEAP), |
| 137 | TLS_STACK_ALIGN, stack_size); |
| 138 | } |
| 139 | else |
| 140 | #endif |
| 141 | { |
| 142 | /* Use the user-space allocator if this is a task or pthread */ |
| 143 | |
| 144 | tcb->stack_alloc_ptr = mm_memalign( |
| 145 | UMM_HEAP(CONFIG_ARCH_STACK_HEAP), |
| 146 | TLS_STACK_ALIGN, stack_size); |
| 147 | } |
| 148 | |
| 149 | #else /* CONFIG_TLS */ |
| 150 | #ifdef HAVE_KERNEL_HEAP |
| 151 | /* Use the kernel allocator if this is a kernel thread */ |
no test coverage detected