00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _RTAI_TASKLETS_H
00027 #define _RTAI_TASKLETS_H
00028
00029
00030
00031
00032
00033 #include <rtai_types.h>
00034 #include <rtai_sched.h>
00035
00036 #define TASKLETS_IDX 1
00037
00038 #define INIT 0
00039 #define DELETE 1
00040 #define TASK_INSERT 2
00041 #define TASK_REMOVE 3
00042 #define USE_FPU 4
00043 #define TIMER_INSERT 5
00044 #define TIMER_REMOVE 6
00045 #define SET_TASKLETS_PRI 7
00046 #define SET_FIR_TIM 8
00047 #define SET_PER 9
00048 #define SET_HDL 10
00049 #define SET_DAT 11
00050 #define EXEC_TASKLET 12
00051 #define WAIT_IS_HARD 13
00052 #define SET_TSK_PRI 14
00053 #define REG_TASK 15
00054 #define GET_TMR_TIM 16
00055 #define GET_TMR_OVRN 17
00056
00057
00058
00059 #define PTIMER_CREATE 18
00060 #define PTIMER_SETTIME 19
00061 #define PTIMER_OVERRUN 20
00062 #define PTIMER_GETTIME 21
00063 #define PTIMER_DELETE 22
00064
00065 #define POSIX_TIMERS 128
00066
00067
00068
00069 struct rt_task_struct;
00070
00071 #define TASKLET_STACK_SIZE 8196
00072
00073 struct rt_usp_tasklet_struct {
00074 struct rt_tasklet_struct *next, *prev;
00075 int priority, uses_fpu, cpuid;
00076 RTIME firing_time, period;
00077 void (*handler)(unsigned long);
00078 unsigned long data, id;
00079 long thread;
00080 struct rt_task_struct *task;
00081 struct rt_tasklet_struct *usptasklet;
00082 int overrun;
00083 };
00084
00085 #ifdef __KERNEL__
00086
00087 struct rt_tasklet_struct {
00088 struct rt_tasklet_struct *next, *prev;
00089 int priority, uses_fpu, cpuid;
00090 RTIME firing_time, period;
00091 void (*handler)(unsigned long);
00092 unsigned long data, id;
00093 long thread;
00094 struct rt_task_struct *task;
00095 struct rt_tasklet_struct *usptasklet;
00096 int overrun;
00097 #ifdef CONFIG_RTAI_LONG_TIMED_LIST
00098 rb_root_t rbr;
00099 rb_node_t rbn;
00100 #endif
00101 };
00102
00103 #ifdef __cplusplus
00104 extern "C" {
00105 #endif
00106
00107 int __rtai_tasklets_init(void);
00108
00109 void __rtai_tasklets_exit(void);
00110
00111 struct rt_tasklet_struct *rt_init_tasklet(void);
00112
00113 RTAI_SYSCALL_MODE int rt_delete_tasklet(struct rt_tasklet_struct *tasklet);
00114
00115 RTAI_SYSCALL_MODE int rt_insert_tasklet(struct rt_tasklet_struct *tasklet, int priority, void (*handler)(unsigned long), unsigned long data, unsigned long id, int pid);
00116
00117 RTAI_SYSCALL_MODE void rt_remove_tasklet(struct rt_tasklet_struct *tasklet);
00118
00119 struct rt_tasklet_struct *rt_find_tasklet_by_id(unsigned long id);
00120
00121 RTAI_SYSCALL_MODE int rt_exec_tasklet(struct rt_tasklet_struct *tasklet);
00122
00123 RTAI_SYSCALL_MODE void rt_set_tasklet_priority(struct rt_tasklet_struct *tasklet, int priority);
00124
00125 RTAI_SYSCALL_MODE int rt_set_tasklet_handler(struct rt_tasklet_struct *tasklet, void (*handler)(unsigned long));
00126
00127 #define rt_fast_set_tasklet_handler(t, h) do { (t)->handler = (h); } while (0)
00128
00129 RTAI_SYSCALL_MODE void rt_set_tasklet_data(struct rt_tasklet_struct *tasklet, unsigned long data);
00130
00131 #define rt_fast_set_tasklet_data(t, d) \
00132 do { \
00133 (t)->data = (d); \
00134 } while (0)
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 RTAI_SYSCALL_MODE struct rt_task_struct *rt_tasklet_use_fpu(struct rt_tasklet_struct *tasklet, int use_fpu);
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 #define rt_init_timer rt_init_tasklet
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 #define rt_delete_timer rt_delete_tasklet
00191
00192 RTAI_SYSCALL_MODE int rt_insert_timer(struct rt_tasklet_struct *timer, int priority, RTIME firing_time, RTIME period, void (*handler)(unsigned long), unsigned long data, int pid);
00193
00194 RTAI_SYSCALL_MODE void rt_remove_timer(struct rt_tasklet_struct *timer);
00195
00196 RTAI_SYSCALL_MODE void rt_set_timer_priority(struct rt_tasklet_struct *timer, int priority);
00197
00198 RTAI_SYSCALL_MODE void rt_set_timer_firing_time(struct rt_tasklet_struct *timer, RTIME firing_time);
00199
00200 RTAI_SYSCALL_MODE void rt_set_timer_period(struct rt_tasklet_struct *timer, RTIME period);
00201
00202 RTAI_SYSCALL_MODE void rt_get_timer_times(struct rt_tasklet_struct *timer, RTIME timer_times[]);
00203
00204 RTAI_SYSCALL_MODE RTIME rt_get_timer_overrun(struct rt_tasklet_struct *timer);
00205
00206
00207
00208 RTAI_SYSCALL_MODE timer_t rt_ptimer_create(struct rt_tasklet_struct *timer, void (*handler)(unsigned long), unsigned long data, long pid, long thread);
00209
00210 RTAI_SYSCALL_MODE void rt_ptimer_settime(timer_t timer, const struct itimerspec *value, unsigned long data, long flags);
00211
00212 RTAI_SYSCALL_MODE int rt_ptimer_overrun(timer_t timer);
00213
00214 RTAI_SYSCALL_MODE void rt_ptimer_gettime(timer_t timer, RTIME timer_times[]);
00215
00216 RTAI_SYSCALL_MODE int rt_ptimer_delete(timer_t timer, long space);
00217
00218
00219
00220 #define rt_fast_set_timer_period(t, p) \
00221 do { \
00222 (t)->period = (p); \
00223 } while (0)
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 #define rt_set_timer_handler rt_set_tasklet_handler
00248
00249 #define rt_fast_set_timer_handler(t, h) do { (t)->handler = (h); } while (0)
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 #define rt_set_timer_data rt_set_tasklet_data
00273
00274 #define rt_fast_set_timer_data(t, d) do { (t)->data = (d); } while (0)
00275
00276 #define rt_timer_use_fpu rt_tasklet_use_fpu
00277
00278 RTAI_SYSCALL_MODE int rt_wait_tasklet_is_hard(struct rt_tasklet_struct *tasklet, long thread);
00279
00280 RTAI_SYSCALL_MODE void rt_register_task(struct rt_tasklet_struct *tasklet, struct rt_tasklet_struct *usptasklet, struct rt_task_struct *task);
00281
00282 #ifdef __cplusplus
00283 }
00284 #endif
00285
00286 #else
00287
00288 #include <sys/types.h>
00289 #include <sys/wait.h>
00290 #include <sys/mman.h>
00291 #include <stdarg.h>
00292
00293 #include <rtai_usi.h>
00294 #include <rtai_lxrt.h>
00295
00296 #define rt_tasklet_struct rt_usp_tasklet_struct
00297 #if 0
00298 struct rt_tasklet_struct {
00299 struct rt_tasklet_struct *next, *prev;
00300 int priority, uses_fpu, cpuid;
00301 RTIME firing_time, period;
00302 void (*handler)(unsigned long);
00303 unsigned long data, id;
00304 long thread;
00305 struct rt_task_struct *task;
00306 struct rt_tasklet_struct *usptasklet;
00307 int overrun;
00308 #ifdef CONFIG_RTAI_LONG_TIMED_LIST
00309 struct { void *rb_parent; int rb_color; void *rb_right, *rb_left; } rbn;
00310 struct { void *rb_node; } rbr;
00311 #endif
00312 };
00313 #endif
00314
00315 #ifndef __SUPPORT_TASKLET__
00316 #define __SUPPORT_TASKLET__
00317
00318 struct support_tasklet_s { struct rt_tasklet_struct *tasklet; pthread_t thread; volatile int done; };
00319
00320 static int support_tasklet(struct support_tasklet_s *args)
00321 {
00322 RT_TASK *task;
00323 struct rt_tasklet_struct usptasklet;
00324
00325 if ((task = rt_thread_init((unsigned long)args->tasklet, 98, 0, SCHED_FIFO, 0xF))) {
00326 {
00327 struct { struct rt_tasklet_struct *tasklet, *usptasklet; RT_TASK *task; } reg = { args->tasklet, &usptasklet, task };
00328 rtai_lxrt(TASKLETS_IDX, sizeof(reg), REG_TASK, ®);
00329 }
00330 rt_grow_and_lock_stack(TASKLET_STACK_SIZE/2);
00331 mlockall(MCL_CURRENT | MCL_FUTURE);
00332 rt_make_hard_real_time();
00333 args->done = 1;
00334 while (1) {
00335 rt_task_suspend(task);
00336 if (usptasklet.handler) {
00337 usptasklet.handler(usptasklet.data);
00338 } else {
00339 break;
00340 }
00341 }
00342 rtai_sti();
00343 rt_make_soft_real_time();
00344 rt_task_delete(task);
00345 return 0;
00346 }
00347 printf("CANNOT INIT SUPPORT TASKLET\n");
00348 return -1;
00349
00350 }
00351 #endif
00352
00353 #ifdef __cplusplus
00354 extern "C" {
00355 #endif
00356
00357 RTAI_PROTO(void, rt_delete_tasklet, (struct rt_tasklet_struct *tasklet));
00358
00359 RTAI_PROTO(struct rt_tasklet_struct *, rt_init_tasklet, (void))
00360 {
00361 int is_hard;
00362 struct support_tasklet_s arg;
00363
00364 if ((arg.tasklet = (struct rt_tasklet_struct*)rtai_lxrt(TASKLETS_IDX, SIZARG, INIT, &arg).v[LOW])) {
00365 if ((is_hard = rt_is_hard_real_time(NULL))) {
00366 rt_make_soft_real_time();
00367 }
00368 arg.done = 0;
00369 if ((arg.thread = rt_thread_create((void *)support_tasklet, &arg.tasklet, TASKLET_STACK_SIZE))) {
00370 int i;
00371 #define POLLS_PER_SEC 100
00372 for (i = 0; i < POLLS_PER_SEC/5 && !arg.done; i++) {
00373 struct timespec delay = { 0, 1000000000/POLLS_PER_SEC };
00374 nanosleep(&delay, NULL);
00375 }
00376 #undef POLLS_PER_SEC
00377 if (!arg.done || rtai_lxrt(TASKLETS_IDX, SIZARG, WAIT_IS_HARD, &arg).i[LOW]) {
00378 goto notdone;
00379 }
00380 } else {
00381 notdone:
00382 rt_delete_tasklet(arg.tasklet);
00383 arg.tasklet = NULL;
00384 }
00385 if (is_hard) {
00386 rt_make_hard_real_time();
00387 }
00388 }
00389 return arg.tasklet;
00390 }
00391
00392 #define rt_init_timer rt_init_tasklet
00393
00394 RTAI_PROTO(void, rt_delete_tasklet, (struct rt_tasklet_struct *tasklet))
00395 {
00396 int thread;
00397 struct { struct rt_tasklet_struct *tasklet; } arg = { tasklet };
00398 if ((thread = rtai_lxrt(TASKLETS_IDX, SIZARG, DELETE, &arg).i[LOW])) {
00399 rt_thread_join(thread);
00400 }
00401 }
00402
00403 #define rt_delete_timer rt_delete_tasklet
00404
00405 RTAI_PROTO(int, rt_insert_timer,(struct rt_tasklet_struct *timer,
00406 int priority,
00407 RTIME firing_time,
00408 RTIME period,
00409 void (*handler)(unsigned long),
00410 unsigned long data,
00411 int pid))
00412 {
00413 struct { struct rt_tasklet_struct *timer; long priority; RTIME firing_time; RTIME period; void (*handler)(unsigned long); unsigned long data; long pid; } arg = { timer, priority, firing_time, period, handler, data, pid };
00414 return rtai_lxrt(TASKLETS_IDX, SIZARG, TIMER_INSERT, &arg).i[LOW];
00415 }
00416
00417 RTAI_PROTO(void, rt_remove_timer, (struct rt_tasklet_struct *timer))
00418 {
00419 struct { struct rt_tasklet_struct *timer; } arg = { timer };
00420 rtai_lxrt(TASKLETS_IDX, SIZARG, TIMER_REMOVE, &arg);
00421 }
00422
00423 RTAI_PROTO(void, rt_set_timer_priority, (struct rt_tasklet_struct *timer, int priority))
00424 {
00425 struct { struct rt_tasklet_struct *timer; long priority; } arg = { timer, priority };
00426 rtai_lxrt(TASKLETS_IDX, SIZARG, SET_TASKLETS_PRI, &arg);
00427 }
00428
00429 RTAI_PROTO(void, rt_set_timer_firing_time, (struct rt_tasklet_struct *timer, RTIME firing_time))
00430 {
00431 struct { struct rt_tasklet_struct *timer; RTIME firing_time; } arg = { timer, firing_time };
00432 rtai_lxrt(TASKLETS_IDX, SIZARG, SET_FIR_TIM, &arg);
00433 }
00434
00435 RTAI_PROTO(void, rt_set_timer_period, (struct rt_tasklet_struct *timer, RTIME period))
00436 {
00437 struct { struct rt_tasklet_struct *timer; RTIME period; } arg = { timer, period };
00438 rtai_lxrt(TASKLETS_IDX, SIZARG, SET_PER, &arg);
00439 }
00440
00441 RTAI_PROTO(void, rt_get_timer_times, (struct rt_tasklet_struct *timer, RTIME timer_times[]))
00442 {
00443 if (timer_times) {
00444 RTIME ltimer_times[2];
00445 struct { struct rt_tasklet_struct *timer; RTIME *timer_times; } arg = { timer, ltimer_times };
00446 rtai_lxrt(TASKLETS_IDX, SIZARG, GET_TMR_TIM, &arg);
00447 memcpy(timer_times, ltimer_times, sizeof(ltimer_times));
00448 }
00449 }
00450
00451 RTAI_PROTO(RTIME, rt_get_timer_overrun, (struct rt_tasklet_struct *timer ))
00452 {
00453 struct { struct rt_tasklet_struct *timer; } arg = { timer };
00454 return rtai_lxrt(TASKLETS_IDX, SIZARG, GET_TMR_OVRN, &arg).rt;
00455 }
00456
00457 RTAI_PROTO(int, rt_set_tasklet_handler, (struct rt_tasklet_struct *tasklet, void (*handler)(unsigned long)))
00458 {
00459 struct { struct rt_tasklet_struct *tasklet; void (*handler)(unsigned long); } arg = { tasklet, handler };
00460 return rtai_lxrt(TASKLETS_IDX, SIZARG, SET_HDL, &arg).i[LOW];
00461 }
00462
00463 #define rt_set_timer_handler rt_set_tasklet_handler
00464
00465 RTAI_PROTO(void, rt_set_tasklet_data, (struct rt_tasklet_struct *tasklet, unsigned long data))
00466 {
00467 struct { struct rt_tasklet_struct *tasklet; unsigned long data; } arg = { tasklet, data };
00468 rtai_lxrt(TASKLETS_IDX, SIZARG, SET_DAT, &arg);
00469 }
00470
00471 #define rt_set_timer_data rt_set_tasklet_data
00472
00473 RTAI_PROTO(RT_TASK *, rt_tasklet_use_fpu, (struct rt_tasklet_struct *tasklet, int use_fpu))
00474 {
00475 RT_TASK *task;
00476 struct { struct rt_tasklet_struct *tasklet; long use_fpu; } arg = { tasklet, use_fpu };
00477 if ((task = (RT_TASK*)rtai_lxrt(TASKLETS_IDX, SIZARG, USE_FPU, &arg).v[LOW])) {
00478 rt_task_use_fpu(task, use_fpu);
00479 }
00480 return task;
00481 }
00482
00483 #define rt_timer_use_fpu rt_tasklet_use_fpu
00484
00485 RTAI_PROTO(int, rt_insert_tasklet,(struct rt_tasklet_struct *tasklet,
00486 int priority,
00487 void (*handler)(unsigned long),
00488 unsigned long data,
00489 unsigned long id,
00490 int pid))
00491 {
00492 struct { struct rt_tasklet_struct *tasklet; long priority; void (*handler)(unsigned long); unsigned long data; unsigned long id; long pid; } arg = { tasklet, priority, handler, data, id, pid };
00493 return rtai_lxrt(TASKLETS_IDX, SIZARG, TASK_INSERT, &arg).i[LOW];
00494 }
00495
00496 RTAI_PROTO(void, rt_set_tasklet_priority, (struct rt_tasklet_struct *tasklet, int priority))
00497 {
00498 struct { struct rt_tasklet_struct *tasklet; long priority; } arg = { tasklet, priority };
00499 rtai_lxrt(TASKLETS_IDX, SIZARG, SET_TSK_PRI, &arg);
00500 }
00501
00502 RTAI_PROTO(void, rt_remove_tasklet, (struct rt_tasklet_struct *tasklet))
00503 {
00504 struct { struct rt_tasklet_struct *tasklet; } arg = { tasklet };
00505 rtai_lxrt(TASKLETS_IDX, SIZARG, TASK_REMOVE, &arg);
00506 }
00507
00508 RTAI_PROTO(int, rt_exec_tasklet, (struct rt_tasklet_struct *tasklet))
00509 {
00510 struct { struct rt_tasklet_struct *tasklet; } arg = { tasklet };
00511 return rtai_lxrt(TASKLETS_IDX, SIZARG, EXEC_TASKLET, &arg).i[LOW];
00512 }
00513
00514 #include <stdlib.h>
00515
00516 struct rt_tasklets_struct { volatile int in, out, avb, ntasklets; struct rt_tasklet_struct **tasklets; unsigned long lock; };
00517
00518 RTAI_PROTO(struct rt_tasklets_struct *, rt_create_tasklets, (int ntasklets))
00519 {
00520 struct rt_tasklets_struct *tasklets;
00521 if ((tasklets = (struct rt_tasklets_struct *)malloc(sizeof(struct rt_tasklets_struct)))) {
00522 if ((tasklets->tasklets = (struct rt_tasklet_struct **)malloc(ntasklets*sizeof(struct rt_tasklet_struct *)))) {
00523 int i;
00524 for (i = 0; i < ntasklets; i++) {
00525 if (!(tasklets->tasklets[i] = rt_init_tasklet())) {
00526 int k;
00527 for (k = 0; k < i; k++) {
00528 rt_delete_tasklet(tasklets->tasklets[k]);
00529 }
00530 free(tasklets->tasklets);
00531 goto free_tasklets;
00532 }
00533 }
00534 tasklets->lock = 0;
00535 tasklets->ntasklets = tasklets->avb = tasklets->in = tasklets->out = ntasklets;
00536 return tasklets;
00537 } else {
00538 free_tasklets:
00539 free(tasklets);
00540 }
00541 }
00542 return NULL;
00543 }
00544
00545 #define rt_create_timers rt_create_tasklets
00546
00547 RTAI_PROTO(void, rt_destroy_tasklets, (struct rt_tasklets_struct *tasklets))
00548 {
00549 int i;
00550 for (i = 0; i < tasklets->ntasklets; i++) {
00551 rt_delete_tasklet(tasklets->tasklets[i]);
00552 }
00553 free(tasklets->tasklets);
00554 free(tasklets);
00555 }
00556
00557 #define rt_destroy_timers rt_destroy_tasklets
00558
00559 #include <asm/rtai_atomic.h>
00560
00561 RTAI_PROTO(struct rt_tasklet_struct *, rt_get_tasklet, (struct rt_tasklets_struct *tasklets))
00562 {
00563 struct rt_tasklet_struct *tasklet;
00564 while (atomic_cmpxchg((void *)&tasklets->lock, 0, 1));
00565 if (tasklets->avb > 0) {
00566 if (tasklets->out >= tasklets->ntasklets) {
00567 tasklets->out = 0;
00568 }
00569 tasklets->avb--;
00570 tasklet = tasklets->tasklets[tasklets->out++];
00571 tasklets->lock = 0;
00572 return tasklet;
00573 }
00574 tasklets->lock = 0;
00575 return NULL;
00576 }
00577
00578 #define rt_get_timer rt_get_tasklet
00579
00580 RTAI_PROTO(int, rt_gvb_tasklet, (struct rt_tasklet_struct *tasklet, struct rt_tasklets_struct *tasklets))
00581 {
00582 while (atomic_cmpxchg((void *)&tasklets->lock, 0, 1));
00583 if (tasklets->avb < tasklets->ntasklets) {
00584 if (tasklets->in >= tasklets->ntasklets) {
00585 tasklets->in = 0;
00586 }
00587 tasklets->avb++;
00588 tasklets->tasklets[tasklets->in++] = tasklet;
00589 tasklets->lock = 0;
00590 return 0;
00591 }
00592 tasklets->lock = 0;
00593 return EINVAL;
00594 }
00595
00596 #define rt_gvb_timer rt_gvb_tasklet
00597
00598 #ifdef __cplusplus
00599 }
00600 #endif
00601
00602 #endif
00603
00604
00605
00606 #endif