Rev 38 | Rev 657 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* |
2 | * Project: S.Ha.R.K. |
||
3 | * |
||
4 | * Coordinators: |
||
5 | * Giorgio Buttazzo <giorgio@sssup.it> |
||
6 | * Paolo Gai <pj@gandalf.sssup.it> |
||
7 | * |
||
8 | * Authors : |
||
9 | * Paolo Gai <pj@gandalf.sssup.it> |
||
10 | * Massimiliano Giorgi <massy@gandalf.sssup.it> |
||
11 | * Luca Abeni <luca@gandalf.sssup.it> |
||
12 | * (see the web pages for full authors list) |
||
13 | * |
||
14 | * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
||
15 | * |
||
16 | * http://www.sssup.it |
||
17 | * http://retis.sssup.it |
||
18 | * http://shark.sssup.it |
||
19 | */ |
||
20 | |||
21 | |||
22 | /** |
||
23 | ------------ |
||
79 | pj | 24 | CVS : $Id: descr.h,v 1.4 2003-03-13 13:36:27 pj Exp $ |
2 | pj | 25 | |
26 | File: $File$ |
||
79 | pj | 27 | Revision: $Revision: 1.4 $ |
28 | Last update: $Date: 2003-03-13 13:36:27 $ |
||
2 | pj | 29 | ------------ |
30 | |||
31 | Kernel main data structures |
||
32 | |||
33 | This file declare: |
||
34 | |||
35 | - the descriptors |
||
36 | - cleanup handlers |
||
37 | - levels |
||
38 | - mutexes |
||
39 | - mutex attributes |
||
40 | - resource levels |
||
41 | |||
42 | |||
43 | **/ |
||
44 | |||
45 | /* |
||
46 | * Copyright (C) 2000 Paolo Gai |
||
47 | * |
||
48 | * This program is free software; you can redistribute it and/or modify |
||
49 | * it under the terms of the GNU General Public License as published by |
||
50 | * the Free Software Foundation; either version 2 of the License, or |
||
51 | * (at your option) any later version. |
||
52 | * |
||
53 | * This program is distributed in the hope that it will be useful, |
||
54 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
55 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
56 | * GNU General Public License for more details. |
||
57 | * |
||
58 | * You should have received a copy of the GNU General Public License |
||
59 | * along with this program; if not, write to the Free Software |
||
60 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
61 | * |
||
62 | */ |
||
63 | |||
64 | |||
65 | |||
66 | #ifndef __KERNEL_DESCR_H__ |
||
67 | #define __KERNEL_DESCR_H__ |
||
68 | |||
69 | |||
70 | #include <ll/ll.h> |
||
71 | #include <kernel/model.h> |
||
72 | #include <kernel/types.h> |
||
29 | pj | 73 | #include <kernel/iqueue.h> |
2 | pj | 74 | #include <limits.h> |
79 | pj | 75 | #include "ll/sys/cdefs.h" |
2 | pj | 76 | |
79 | pj | 77 | __BEGIN_DECLS |
78 | |||
2 | pj | 79 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
80 | CLEANUP HANDLER STRUCTURES |
||
81 | |||
82 | Derived directly from posix standard, B.18.2.3 |
||
83 | This structure implements the task cleanup functions queue... |
||
84 | look at kern.c! |
||
85 | |||
86 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
||
87 | struct _task_handler_rec { |
||
88 | void (*f)(void *); |
||
89 | void *a; |
||
90 | struct _task_handler_rec *next; |
||
91 | }; |
||
92 | |||
93 | |||
94 | |||
95 | struct condition_struct; |
||
96 | |||
97 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
98 | GENERAL TASK DESCRIPTOR |
||
99 | |||
100 | In this type definition there is all the basic information for |
||
101 | handling a task in the system. |
||
102 | |||
103 | All the informations scheduler-dependent (like deadline, priority, |
||
104 | and so on) are put in the level module files. |
||
105 | In any case, a priority field is inserted to simplify the implementation |
||
106 | of most of the scheduling algorithms |
||
107 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
||
108 | |||
109 | typedef struct { |
||
110 | DWORD task_ID; /*+ progressive task counter ID +*/ |
||
111 | LEVEL task_level; /*+ the "real" level that owns the task +*/ |
||
112 | |||
113 | CONTEXT context; /*+ Context area pointer (see vm.h) +*/ |
||
114 | BYTE *stack; /*+ Pointer to stack area base +*/ |
||
115 | TASK (*body)(); /*+ Pointer to the code of the task |
||
116 | (starting address) +*/ |
||
117 | char name[MAX_TASKNAME]; /*+ Text identifing the process name +*/ |
||
118 | |||
119 | WORD status; /*+ actual task status |
||
120 | (it could be EXE, SLEEP, IDLE, ...) +*/ |
||
121 | WORD pclass; /*+ The code number of the task model used +*/ |
||
122 | WORD group; /*+ 0 if task is single, else group id +*/ |
||
123 | WORD stacksize; /*+ Task stack size +*/ |
||
124 | DWORD control; /*+ Control task operating mode |
||
125 | Refer to the TASK_MODEL type for its use +*/ |
||
126 | |||
127 | int frozen_activations; /*+ number of frozen activation; |
||
128 | see kern.c, task_block_activations |
||
129 | see model.h,flag in control field +*/ |
||
130 | |||
131 | /* sigset_t!!! */ |
||
132 | int sigmask; /*+ The task signal mask +*/ |
||
133 | int sigpending; /*+ The signal pending mask +*/ |
||
134 | int sigwaiting; /*+ The signal waiting mask +*/ |
||
135 | |||
136 | int avail_time; /*+ the time the task can execute before a |
||
137 | timer fire. see also the control field |
||
138 | and bits related in model.h +*/ |
||
139 | |||
140 | PID shadow; /*+ Shadow task +*/ |
||
141 | |||
142 | struct _task_handler_rec *cleanup_stack; |
||
143 | /*+ The cleanup stack +*/ |
||
144 | |||
145 | |||
29 | pj | 146 | |
2 | pj | 147 | int errnumber; |
148 | |||
149 | /* Job Execution Time fields */ |
||
150 | TIME jet_table[JET_TABLE_DIM]; |
||
151 | /*+ Execution time of the last |
||
152 | activations of the task. +*/ |
||
153 | int jet_tvalid; /*+ number of valid entry in the jet_table +*/ |
||
154 | int jet_curr; /*+ Current entry in the jet_table +*/ |
||
155 | TIME jet_max; /*+ Maximum Execution time since task_create |
||
156 | or last jet_delstat +*/ |
||
157 | TIME jet_sum; /*+ Mean Execution time since task_create |
||
158 | or last jet_delstat +*/ |
||
159 | TIME jet_n; /*+ Number of instances on witch the mean |
||
160 | time have to be computed +*/ |
||
161 | |||
162 | /* task_join fields */ |
||
163 | PID waiting_for_me; /*+ the task that waits my dead, |
||
164 | NIL if there aren't +*/ |
||
165 | void *return_value; /*+ task return value +*/ |
||
166 | |||
167 | /* task specific data (it uses directly POSIX constant) */ |
||
168 | void *keys[PTHREAD_KEYS_MAX]; |
||
169 | |||
170 | /* condition variable field */ |
||
171 | struct condition_struct *cond_waiting; |
||
172 | /*+ the condition on that the task is |
||
173 | waiting +*/ |
||
174 | |||
175 | /* stuff used in most algorithms; they are not used directly in |
||
176 | * the generic kernel, with exclusion of delay_timer that is used |
||
177 | * also in cond_timedwait |
||
178 | */ |
||
29 | pj | 179 | |
2 | pj | 180 | int delay_timer; /*+ A field useful to store the delay timer +*/ |
181 | |||
182 | int wcet; /*+ a worst case time execution +*/ |
||
183 | |||
184 | |||
185 | } proc_des; |
||
186 | |||
187 | |||
188 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
189 | LEVEL DESCRIPTOR |
||
190 | |||
191 | In this type definition there is all the basic information for |
||
192 | handling a scheduling level in the system. |
||
193 | |||
194 | All the informations that depends on the particular module are put |
||
195 | in the level module files. |
||
196 | |||
38 | pj | 197 | Here a small description of the various functions: |
2 | pj | 198 | |
38 | pj | 199 | ------------------------------------------------------------------- |
200 | - PUBLIC Functions: |
||
201 | on one side, a module should export an interface to the Generic |
||
202 | Kernel, giving a set of functions that the Generic Kernel can use |
||
203 | to ask a service to the module. That is, the Public Functions are |
||
204 | called ONLY by the Generic Kernel. |
||
2 | pj | 205 | |
38 | pj | 206 | - PRIVATE Functions: on the other side, a module can export an |
207 | interface to the public part of the same or of another |
||
208 | module. That is, Private Functions are called ONLY by Public and |
||
209 | Private Functions. |
||
210 | ------------------------------------------------------------------- |
||
2 | pj | 211 | |
38 | pj | 212 | int (*private_insert )(LEVEL l, PID p, TASK_MODEL *m); |
213 | Inserts a task into the internal module data structure. |
||
214 | |||
215 | void (*private_extract )(LEVEL l, PID p); |
||
216 | Removes a task from the internal module data structure. |
||
2 | pj | 217 | |
38 | pj | 218 | int (*private_eligible)(LEVEL l, PID p); |
219 | A task inserted into the internal module data structure needs to be |
||
220 | scheduled. returns 0 if it can be scheduled, -1 if not. |
||
2 | pj | 221 | |
38 | pj | 222 | void (*private_dispatch)(LEVEL l, PID p, int nostop); |
223 | A task inserted into the internal module data structure has been dispatched. |
||
2 | pj | 224 | |
38 | pj | 225 | void (*private_epilogue)(LEVEL l, PID p); |
226 | A task inserted into the internal module data structure has been preempted. |
||
227 | |||
2 | pj | 228 | |
229 | |||
230 | |||
38 | pj | 231 | PID (*public_scheduler)(LEVEL l); |
232 | returns a task to schedule, or -1 if no tasks are ready |
||
2 | pj | 233 | |
38 | pj | 234 | int (*public_guarantee)(LEVEL l, bandwidth_t *freebandwidth); |
235 | returns 0 if the level is guaranteed, -1 if not |
||
236 | no guarantee if (*f)()=null |
||
237 | the function updates the parameter freebandwidth (see guarantee() ) |
||
238 | int (*public_create )(LEVEL l, PID p, TASK_MODEL *m); |
||
239 | the task p is created into the module |
||
240 | returns 0->ok, -1->error |
||
2 | pj | 241 | |
38 | pj | 242 | void (*public_detach )(LEVEL l, PID p); |
243 | there is an error in the public_create. The function removes all the |
||
244 | informations about the task in the module. |
||
2 | pj | 245 | |
38 | pj | 246 | void (*public_end )(LEVEL l, PID p); |
247 | the task has been killed, or it ended regularly |
||
2 | pj | 248 | |
38 | pj | 249 | int (*public_eligible )(LEVEL l, PID p); |
250 | A task needs to be scheduled. returns 0 if it can be scheduled, -1 if not. |
||
251 | |||
252 | void (*public_dispatch )(LEVEL l, PID p, int nostop); |
||
253 | A task has been dispatched. |
||
2 | pj | 254 | |
38 | pj | 255 | void (*public_epilogue )(LEVEL l, PID p); |
256 | A task has been preempted (or its capacity is exausted). |
||
2 | pj | 257 | |
38 | pj | 258 | void (*public_activate )(LEVEL l, PID p); |
259 | A task has been activated. |
||
2 | pj | 260 | |
38 | pj | 261 | void (*public_unblock )(LEVEL l, PID p); |
262 | void (*public_block )(LEVEL l, PID p); |
||
263 | A task has been unblocked/blocked on a synchronization point |
||
264 | (e.g. a semaphore, a mailbox, a nanosleep). |
||
2 | pj | 265 | |
38 | pj | 266 | int (*public_message )(LEVEL l, PID p, void *m); |
267 | A task sent a message m to the module. |
||
2 | pj | 268 | |
38 | pj | 269 | If the message has value NULL the |
270 | behavior should be the task_endcycle primitive behavior. |
||
2 | pj | 271 | |
38 | pj | 272 | The function returns an integer to the user. |
2 | pj | 273 | |
38 | pj | 274 | If you want to avoid the call to public_epilogue, after public_message, |
275 | just write exec = exec_shadow = -1; in your public_message code. |
||
2 | pj | 276 | |
38 | pj | 277 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
278 | |||
279 | typedef struct { |
||
280 | void (*private_insert )(LEVEL l, PID p, TASK_MODEL *m); |
||
281 | void (*private_extract )(LEVEL l, PID p); |
||
282 | int (*private_eligible)(LEVEL l, PID p); |
||
283 | void (*private_dispatch)(LEVEL l, PID p, int nostop); |
||
284 | void (*private_epilogue)(LEVEL l, PID p); |
||
285 | |||
286 | PID (*public_scheduler)(LEVEL l); |
||
287 | int (*public_guarantee)(LEVEL l, bandwidth_t *freebandwidth); |
||
288 | int (*public_create )(LEVEL l, PID p, TASK_MODEL *m); |
||
289 | void (*public_detach )(LEVEL l, PID p); |
||
290 | void (*public_end )(LEVEL l, PID p); |
||
291 | int (*public_eligible )(LEVEL l, PID p); |
||
292 | void (*public_dispatch )(LEVEL l, PID p, int nostop); |
||
293 | void (*public_epilogue )(LEVEL l, PID p); |
||
294 | void (*public_activate )(LEVEL l, PID p); |
||
295 | void (*public_unblock )(LEVEL l, PID p); |
||
296 | void (*public_block )(LEVEL l, PID p); |
||
297 | int (*public_message )(LEVEL l, PID p, void *m); |
||
2 | pj | 298 | } level_des; |
299 | |||
300 | |||
301 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
302 | RESOURCE DESCRIPTOR |
||
303 | |||
304 | In this type definition there is all the basic information for |
||
305 | handling a resource module in the system. |
||
306 | |||
307 | All the informations protocol-dependent (like ceiling, task that use |
||
308 | a particular resource, and so on) are put in the resource module files. |
||
309 | |||
310 | In general, the initialization of a resource module is splitted in two |
||
311 | parts: |
||
312 | - the registration -> tipically done with a finction called |
||
313 | XXX_register_module. It is called before the |
||
314 | system initialization, in |
||
315 | the function __kernel_register_levels__(). |
||
316 | - the initialization -> called during the system initialization, |
||
317 | This is done posting some init functions with |
||
318 | the sys_at_init() |
||
319 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
||
320 | |||
321 | typedef struct { |
||
322 | int rtype; /*+ resource module extented interface |
||
323 | code (see model.h) +*/ |
||
324 | |||
38 | pj | 325 | int (*res_register)(RLEVEL l, PID p, RES_MODEL *r); |
326 | /*+ When the system knows that a |
||
327 | resource model can be registered |
||
328 | by a level, it calls this |
||
329 | function. It registers all the |
||
330 | information about the task and the |
||
331 | model. returns 0 if the model |
||
332 | can be handled, -1 otherwise+*/ |
||
2 | pj | 333 | |
334 | void (*res_detach)(RLEVEL l, PID p); |
||
335 | /*+ this function is called when the task |
||
336 | is killed or some error is occurred |
||
337 | in the task_create. It have to unlink |
||
338 | the task from the module... If the task |
||
339 | is already unlinked from the protocol |
||
340 | no action is done +*/ |
||
341 | } resource_des; |
||
342 | |||
343 | |||
344 | |||
345 | |||
346 | |||
347 | |||
348 | |||
349 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
350 | MUTEX DESCRIPTOR |
||
351 | |||
352 | In this type definition there is all the basic fields for |
||
353 | handling a mutex in the system |
||
354 | |||
355 | Many of the informations protocol-dependent (like ceiling, and so on) |
||
356 | are put in the resource module or are pointef by the field opt. |
||
357 | |||
358 | The opt field is used because in this way a mutex can be allocated in |
||
359 | a dynamic way (in this case opt points to a dynamically allocated |
||
360 | structure) or in a static way (in this case opt can be an index or a |
||
361 | pointer to a static structure) |
||
362 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
||
363 | typedef struct { |
||
364 | RLEVEL mutexlevel; /*+ protocol used by the mutex. +*/ |
||
365 | int use; /*+ the mutex is used in a condition wait... +*/ |
||
366 | void *opt; |
||
367 | } mutex_t; |
||
368 | |||
369 | |||
370 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
371 | MUTEX RESOURCE DESCRIPTOR |
||
372 | |||
373 | This object is a resource_des object with a set of functions used to |
||
374 | implement the mutex behaviour. |
||
375 | |||
376 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
||
377 | typedef struct { |
||
378 | resource_des r; |
||
379 | |||
380 | int (*init) (RLEVEL l, mutex_t *m, const mutexattr_t *a); |
||
38 | pj | 381 | /*+ this function is called when a mutex is created. it returns |
382 | >=0 if the mutexattr_t can be managed by the level (=0 Ok, an |
||
383 | error otherwise), -1 otherwise +*/ |
||
2 | pj | 384 | int (*destroy)(RLEVEL l, mutex_t *m); |
385 | int (*lock) (RLEVEL l, mutex_t *m); |
||
386 | int (*trylock)(RLEVEL l, mutex_t *m); |
||
387 | int (*unlock) (RLEVEL l, mutex_t *m); |
||
388 | |||
389 | } mutex_resource_des; |
||
390 | |||
391 | /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
392 | CONDITION VARIABLE DESCRIPTOR |
||
393 | |||
394 | This is the condition variable descriptor. |
||
395 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
||
396 | |||
397 | typedef struct condition_struct { |
||
29 | pj | 398 | IQUEUE waiters; /*+ queue for tasks waiting on the condition +*/ |
2 | pj | 399 | mutex_t *used_for_waiting; |
400 | } cond_t; |
||
401 | |||
79 | pj | 402 | __END_DECLS |
2 | pj | 403 | #endif /* __TYPE_H__ */ |