1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34
35
36 package ti.sysbios.rts.iar;
37
38 import xdc.runtime.Error;
39 import xdc.runtime.Assert;
40
41 import ti.sysbios.knl.Task;
42 import ti.sysbios.knl.Semaphore;
43
44 /*!
45 * ======== MultithreadSupport ========
46 * Provide the kernel support needed for IAR re-entrant C run-time
47 *
48 * This multi-thread support module uses hook functions, hook context,
49 * and an overloaded implementation of the C library's lock and thread
50 * local storage access functions to make C run-time library calls
51 * re-entrant.
52 *
53 * This module is used only with the IAR compiler.
54 *
55 * To enable multi-thread support, load this module in your application
56 * configuration script.
57 *
58 * @p(code)
59 * xdc.useModule('ti.sysbios.rts.iar.MultithreadSupport');
60 * @p
61 *
62 * If your application is using a module which requires multi-thread
63 * support, then that module is responsible for loading this module.
64 * For example, the `ti.posix.tirtos.Settings` module will load this
65 * module. In this case, it is not necessary to load it explicitly.
66 *
67 * When this module is used, it will contribute the IAR linker option
68 * `--threaded_lib` to the linker command.
69 *
70 * When using the IAR Embedded Workbench IDE, if you enable thread support
71 * in your project settings, you must also include this module in your
72 * configuration (unless it is already used as described above). There is
73 * no mechanism for the IAR IDE to communicate the project selections to
74 * this module.
75 *
76 * On memory limited devices, it is possible to disable the re-entrant
77 * support in order to minimize the memory footprint. See
78 * {@link #metaenableMultithreadSupport enableMultithreadSupport} for
79 * details.
80 *
81 * @a(note)
82 * Calling C run-time functions from SWI or HWI threads is not supported
83 * and will generate an exception if multi-thread support is enabled.
84 */
85
86 @Template ("./MultithreadSupport.xdt")
87
88 module MultithreadSupport
89 {
90 /*!
91 * ======== enableMultithreadSupport ========
92 * Disable the multi-thread support feature
93 *
94 * When necessary, it is possible to disable the re-entrant support in
95 * order to minimize the memory footprint. For example, if using POSIX
96 * support on a memory limited device, you may disable re-entrant support
97 * by adding the following to your application configuration script.
98 *
99 * @p(code)
100 * var MultithreadSupport = xdc.useModule('ti.sysbios.rts.iar.MultithreadSupport');
101 * MultithreadSupport.enableMultithreadSupport = false;
102 * @p
103 *
104 * @a(note)
105 * When multi-thread support is disabled, errno will be a global
106 * symbol. If multiple threads are referencing errno, it will not
107 * be thread-safe.
108 */
109 config Bool enableMultithreadSupport = true;
110
111 /*!
112 * ======== A_badThreadType ========
113 * Asserted in MultithreadSupport_perThreadAccess()
114 *
115 * @_nodoc
116 */
117 config Assert.Id A_badThreadType = {
118 msg: "A_badThreadType: Cannot call a C runtime library API from a Hwi or Swi thread."
119 };
120
121 /*!
122 * ======== A_badLockRelease ========
123 * Asserted in MultithreadSupport_releaseLock()
124 *
125 * @_nodoc
126 */
127 config Assert.Id A_badLockRelease = {
128 msg: "A_badLockRelease: Trying to release a lock not owned by this thread."
129 };
130
131 internal:
132
133 134 135 136 137 138 139 140 141 142 143
144 Void *perThreadAccess(Void *symbp);
145
146 147 148 149
150 void *getTlsPtr();
151
152 153 154 155 156 157 158
159 void *getTlsAddr();
160
161 162 163 164 165 166 167 168 169
170 Void initLock(Void **ptr);
171
172 173 174 175 176 177 178 179 180
181 Void destroyLock(Void **ptr);
182
183 184 185 186 187 188 189 190 191
192 Void acquireLock(Void **ptr);
193
194 195 196 197 198 199 200 201 202
203 Void releaseLock(Void **ptr);
204
205 206 207 208 209 210 211 212 213 214
215 Void taskCreateHook(Task.Handle task, Error.Block *eb);
216
217 218 219 220 221 222 223
224 Void taskDeleteHook(Task.Handle task);
225
226 227 228 229 230 231 232
233 Void taskRegHook(Int id);
234
235
236
237 struct Module_State {
238 Int taskHId;
239 Ptr deletedTaskTLSPtr;
240 Task.Handle curTaskHandle;
241 Semaphore.Handle lock;
242 };
243 }