/ base / include / rtai_sched.h
rtai_sched.h
  1  /*
  2   * Copyright (C) 1999-2008 Paolo Mantegazza <mantegazza@aero.polimi.it>
  3   *
  4   * This program is free software; you can redistribute it and/or
  5   * modify it under the terms of the GNU General Public License as
  6   * published by the Free Software Foundation; either version 2 of the
  7   * License, or (at your option) any later version.
  8   *
  9   * This program is distributed in the hope that it will be useful,
 10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12   * GNU General Public License for more details.
 13   *
 14   * You should have received a copy of the GNU General Public License
 15   * along with this program; if not, write to the Free Software
 16   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 17   */
 18  
 19  #ifndef _RTAI_SCHED_H
 20  #define _RTAI_SCHED_H
 21  
 22  #include <rtai.h>
 23  #ifndef __KERNEL__
 24  #include <sys/time.h>
 25  #include <time.h>
 26  #include <errno.h>
 27  #include <rtai_types.h>
 28  #endif /* __KERNEL__ */
 29  
 30  #define RT_SCHED_UP   1
 31  #define RT_SCHED_SMP  2
 32  #define RT_SCHED_MUP  3
 33  
 34  #define RT_SCHED_HIGHEST_PRIORITY  0
 35  #define RT_SCHED_LOWEST_PRIORITY   0x3fffFfff
 36  #define RT_SCHED_LINUX_PRIORITY    0x7fffFfff
 37  
 38  #define RT_RESEM_SUSPDEL  (-0x7fffFfff)
 39  
 40  #define RT_SCHED_READY        1
 41  #define RT_SCHED_SUSPENDED    2
 42  #define RT_SCHED_DELAYED      4
 43  #define RT_SCHED_SEMAPHORE    8
 44  #define RT_SCHED_SEND        16
 45  #define RT_SCHED_RECEIVE     32
 46  #define RT_SCHED_RPC         64
 47  #define RT_SCHED_RETURN     128
 48  #define RT_SCHED_MBXSUSP    256
 49  #define RT_SCHED_SFTRDY     512
 50  #define RT_SCHED_POLL      1024
 51  #define RT_SCHED_SIGSUSP    (1 << 15)
 52  
 53  #define RT_RWLINV     (11)  // keep this the highest
 54  #define RT_CHGPORTERR (10)
 55  #define RT_CHGPORTOK  (9)
 56  #define RT_NETIMOUT   (8)
 57  #define RT_DEADLOK    (7)
 58  #define RT_PERM       (6)
 59  #define RT_OBJINV     (5)
 60  #define RT_OBJREM     (4)
 61  #define RT_TIMOUT     (3)
 62  #define RT_UNBLKD     (2)
 63  #define RT_TMROVRN    (1)  // keep this the lowest, must be 1
 64  #define RTP_RWLINV     ((void *)RT_RWLINV)
 65  #define RTP_CHGPORTERR ((void *)RT_CHGPORTERR)
 66  #define RTP_CHGPORTOK  ((void *)RT_CHGPORTOK)
 67  #define RTP_NETIMOUT   ((void *)RT_NETIMOUT)
 68  #define RTP_DEADLOK    ((void *)RT_DEADLOK)
 69  #define RTP_PERM       ((void *)RT_PERM)
 70  #define RTP_OBJINV     ((void *)RT_OBJINV)
 71  #define RTP_OBJREM     ((void *)RT_OBJREM)
 72  #define RTP_TIMOUT     ((void *)RT_TIMOUT)
 73  #define RTP_UNBLKD     ((void *)RT_UNBLKD)
 74  #define RTP_TMROVRN    ((void *)RT_TMROVRN)
 75  #define RTP_HIGERR     (RTP_RWLINV)
 76  #define RTP_LOWERR     (RTP_TMROVRN)
 77  #if CONFIG_RTAI_USE_NEWERR
 78  #define RTE_BASE       (0x3FFFFF00)
 79  #define RTE_RWLINV     (RTE_BASE + RT_RWLINV)
 80  #define RTE_CHGPORTERR (RTE_BASE + RT_CHGPORTERR)
 81  #define RTE_CHGPORTOK  (RTE_BASE + RT_CHGPORTOK)
 82  #define RTE_NETIMOUT   (RTE_BASE + RT_NETIMOUT)
 83  #define RTE_DEADLOK    (RTE_BASE + RT_DEADLOK)
 84  #define RTE_PERM       (RTE_BASE + RT_PERM)
 85  #define RTE_OBJINV     (RTE_BASE + RT_OBJINV)
 86  #define RTE_OBJREM     (RTE_BASE + RT_OBJREM)
 87  #define RTE_TIMOUT     (RTE_BASE + RT_TIMOUT)
 88  #define RTE_UNBLKD     (RTE_BASE + RT_UNBLKD)
 89  #define RTE_TMROVRN    (RTE_BASE + RT_TMROVRN)
 90  #define RTE_HIGERR     (RTE_RWLINV)
 91  #define RTE_LOWERR     (RTE_TMROVRN)
 92  #else
 93  #define RTE_BASE       (0xFFFB)
 94  #define RTE_RWLINV     (RTE_BASE + RT_RWLINV)
 95  #define RTE_CHGPORTERR (RTE_BASE + RT_CHGPORTERR)
 96  #define RTE_CHGPORTOK  (RTE_BASE + RT_CHGPORTOK)
 97  #define RTE_NETIMOUT   (RTE_BASE + RT_NETIMOUT)
 98  #define RTE_DEADLOK    (RTE_BASE + RT_DEADLOK)
 99  #define RTE_PERM       (RTE_BASE + RT_PERM)
100  #define RTE_OBJINV     (RTE_BASE + RT_OBJREM)
101  #define RTE_OBJREM     (RTE_BASE + RT_OBJREM)
102  #define RTE_TIMOUT     (RTE_BASE + RT_TIMOUT)
103  #define RTE_UNBLKD     (RTE_BASE + RT_UNBLKD)
104  #define RTE_TMROVRN    (RTE_BASE + RT_TMROVRN)
105  #define RTE_HIGERR     (RTE_RWLINV)
106  #define RTE_LOWERR     (RTE_TMROVRN)
107  #endif
108  
109  #define RT_EINTR      (RTE_UNBLKD)
110  
111  #define rt_is_reterr(i)  (i >= RTE_LOWERR)
112  
113  #define RT_IRQ_TASK         0
114  #define RT_IRQ_TASKLET      1
115  #define RT_IRQ_TASK_ERR     0x7FFFFFFF
116  
117  struct rt_task_struct;
118  
119  typedef struct rt_task_info { 
120  	RTIME period; long base_priority, priority; 
121  } RT_TASK_INFO;
122  
123  #ifdef __KERNEL__
124  
125  #include <linux/time.h>
126  #include <linux/errno.h>
127  
128  #if defined(CONFIG_RTAI_LONG_TIMED_LIST) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
129  #include <linux/rbtree.h>
130  typedef struct rb_node rb_node_t;
131  typedef struct rb_root rb_root_t;
132  #endif
133  
134  #define RT_TASK_MAGIC 0x9ad25f6f  // nam2num("rttask")
135  
136  #ifndef __cplusplus
137  
138  #include <linux/sched.h>
139  
140  typedef struct rt_queue {
141  	struct rt_queue *prev;
142  	struct rt_queue *next;
143  	struct rt_task_struct *task;
144  } QUEUE;
145  
146  struct mcb_t {
147  	void *sbuf;
148  	int sbytes;
149  	void *rbuf;
150  	int rbytes;
151  };
152  
153  /*Exit handler functions are called like C++ destructors in rt_task_delete().*/
154  typedef struct rt_ExitHandler {
155  	struct rt_ExitHandler *nxt;
156  	void (*fun) (void *arg1, int arg2);
157  	void *arg1;
158  	int   arg2;
159  } XHDL;
160  
161  struct rt_heap_t { void *heap, *kadr, *uadr; };
162  
163  #define RTAI_MAX_NAME_LENGTH  32
164  
165  typedef struct rt_task_struct {
166  	long *stack __attribute__ ((__aligned__ (L1_CACHE_BYTES)));
167  	int uses_fpu;
168  	int magic;
169  	volatile int state, running;
170  	unsigned long runnable_on_cpus;
171  	long *stack_bottom;
172  	volatile int priority;
173  	int base_priority;
174  	int policy;
175  	int sched_lock_priority;
176  	struct rt_task_struct *prio_passed_to;
177  	RTIME period;
178  	RTIME resume_time;
179  	RTIME periodic_resume_time;
180  	RTIME yield_time;
181  	int rr_quantum, rr_remaining;
182  	int suspdepth;
183  	struct rt_queue queue;
184  	int owndres;
185  	struct rt_queue *blocked_on;
186  	struct rt_queue msg_queue;
187  	int tid;  /* trace ID */
188  	unsigned long msg;
189  	struct rt_queue ret_queue;
190  	void (*signal)(void);
191  	FPU_ENV fpu_reg __attribute__ ((__aligned__ (L1_CACHE_BYTES)));
192  	struct rt_task_struct *prev, *next;
193  	struct rt_task_struct *tprev, *tnext;
194  	struct rt_task_struct *rprev, *rnext;
195  
196  	/* For calls from LINUX. */
197  	long *fun_args;
198  	long *bstack;
199  	struct task_struct *lnxtsk;
200  	long long retval;
201  	char *msg_buf[2];
202  	long max_msg_size[2];
203  	char task_name[RTAI_MAX_NAME_LENGTH];
204  	void *system_data_ptr;
205  	struct rt_task_struct *nextp, *prevp;
206  
207  	RT_TRAP_HANDLER task_trap_handler[HAL_NR_FAULTS];
208  
209  	long unblocked;
210  	void *rt_signals;
211  	volatile unsigned long pstate;
212  	unsigned long usp_flags;
213  	unsigned long usp_flags_mask;
214  	unsigned long force_soft;
215  	volatile int is_hard;
216  	int kerrno;
217  
218  	long busy_time_align;
219  	void *linux_syscall_server;
220  
221  	/* For use by watchdog. */
222  	int resync_frame;
223  
224  	/* For use by exit handler functions. */
225  	XHDL *ExitHook;
226  
227  	RTIME exectime[2];	/* [0] = time spent in thread, [1] = start time of thread */
228  	struct mcb_t mcb;
229  
230  	/* Real time heaps. */
231  	struct rt_heap_t heap[2];
232  
233  	volatile int scheduler;
234  
235  #ifdef CONFIG_RTAI_LONG_TIMED_LIST
236  	rb_root_t rbr;
237  	rb_node_t rbn;
238  #endif
239  	struct rt_queue resq;
240  	unsigned long resumsg;
241  } RT_TASK __attribute__ ((__aligned__ (L1_CACHE_BYTES)));
242  
243  #else /* __cplusplus */
244  extern "C" {
245  #endif /* !__cplusplus */
246  
247  int rt_task_init(struct rt_task_struct *task,
248  		 void (*rt_thread)(long),
249  		 long data,
250  		 int stack_size,
251  		 int priority,
252  		 int uses_fpu,
253  		 void(*signal)(void));
254  
255  int rt_task_init_cpuid(struct rt_task_struct *task,
256  		       void (*rt_thread)(long),
257  		       long data,
258  		       int stack_size,
259  		       int priority,
260  		       int uses_fpu,
261  		       void(*signal)(void),
262  		       unsigned run_on_cpu);
263  
264  int rt_kthread_init(struct rt_task_struct *task,
265  		    void (*rt_thread)(long),
266  		    long data,
267  		    int stack_size,
268  		    int priority,
269  		    int uses_fpu,
270  		    void(*signal)(void));
271  
272  int rt_kthread_init_cpuid(struct rt_task_struct *task,
273  		          void (*rt_thread)(long),
274  		          long data,
275  		          int stack_size,
276  		          int priority,
277  		          int uses_fpu,
278  		          void(*signal)(void),
279  		          unsigned run_on_cpu);
280  
281  RTAI_SYSCALL_MODE void rt_set_runnable_on_cpus(struct rt_task_struct *task,
282  			     unsigned long cpu_mask);
283  
284  RTAI_SYSCALL_MODE void rt_set_runnable_on_cpuid(struct rt_task_struct *task,
285  			      unsigned cpuid);
286  
287  RTAI_SYSCALL_MODE void rt_set_sched_policy(struct rt_task_struct *task,
288  			 int policy,
289  			 int rr_quantum_ns);
290  
291  int rt_task_delete(struct rt_task_struct *task);
292  
293  int rt_get_task_state(struct rt_task_struct *task);
294  
295  void rt_gettimeorig(RTIME time_orig[]);
296  
297  int rt_get_timer_cpu(void);
298  
299  int rt_is_hard_timer_running(void);
300  
301  void rt_set_periodic_mode(void);
302  
303  void rt_set_oneshot_mode(void);
304  
305  RTAI_SYSCALL_MODE RTIME start_rt_timer(int period);
306  
307  #define start_rt_timer_ns(period) start_rt_timer(nano2count((period)))
308  
309  RTAI_SYSCALL_MODE void start_rt_apic_timers(struct apic_timer_setup_data *setup_mode,
310  			  unsigned rcvr_jiffies_cpuid);
311  
312  void stop_rt_timer(void);
313  
314  struct rt_task_struct *rt_whoami(void);
315  
316  int rt_sched_type(void);
317  
318  RTAI_SYSCALL_MODE int rt_task_signal_handler(struct rt_task_struct *task,
319  			   void (*handler)(void));
320  
321  RTAI_SYSCALL_MODE int rt_task_use_fpu(struct rt_task_struct *task,
322  		    int use_fpu_flag);
323    
324  void rt_linux_use_fpu(int use_fpu_flag);
325  
326  RTAI_SYSCALL_MODE int rt_hard_timer_tick_count(void);
327  
328  RTAI_SYSCALL_MODE int rt_hard_timer_tick_count_cpuid(int cpuid);
329  
330  RTAI_SYSCALL_MODE RTIME count2nano(RTIME timercounts);
331  
332  RTAI_SYSCALL_MODE RTIME nano2count(RTIME nanosecs);
333    
334  RTAI_SYSCALL_MODE RTIME count2nano_cpuid(RTIME timercounts, unsigned cpuid);
335  
336  RTAI_SYSCALL_MODE RTIME nano2count_cpuid(RTIME nanosecs, unsigned cpuid);
337    
338  RTIME rt_get_time(void);
339  
340  RTAI_SYSCALL_MODE RTIME rt_get_time_cpuid(unsigned cpuid);
341  
342  RTIME rt_get_time_ns(void);
343  
344  RTAI_SYSCALL_MODE RTIME rt_get_time_ns_cpuid(unsigned cpuid);
345  
346  RTIME rt_get_cpu_time_ns(void);
347  
348  RTIME rt_get_real_time(void);
349  
350  RTIME rt_get_real_time_ns(void);
351  
352  void rt_get_exectime(struct rt_task_struct *task, RTIME *exectime);
353  
354  int rt_get_prio(struct rt_task_struct *task);
355  
356  int rt_get_inher_prio(struct rt_task_struct *task);
357  
358  RTAI_SYSCALL_MODE int rt_task_get_info(RT_TASK *task, RT_TASK_INFO *task_info);
359  
360  RTAI_SYSCALL_MODE int rt_get_priorities(struct rt_task_struct *task, int *priority, int *base_priority);
361  
362  RTAI_SYSCALL_MODE void rt_spv_RMS(int cpuid);
363  
364  RTAI_SYSCALL_MODE int rt_change_prio(struct rt_task_struct *task,
365  		   int priority);
366  
367  void rt_sched_lock(void);
368  
369  void rt_sched_unlock(void);
370  
371  void rt_task_yield(void);
372  
373  RTAI_SYSCALL_MODE int rt_task_suspend(struct rt_task_struct *task);
374  
375  RTAI_SYSCALL_MODE int rt_task_suspend_if(struct rt_task_struct *task);
376  
377  RTAI_SYSCALL_MODE int rt_task_suspend_until(struct rt_task_struct *task, RTIME until);
378  
379  RTAI_SYSCALL_MODE int rt_task_suspend_timed(struct rt_task_struct *task, RTIME delay);
380  
381  RTAI_SYSCALL_MODE int rt_task_resume(struct rt_task_struct *task);
382  
383  RTAI_SYSCALL_MODE int rt_set_linux_syscall_mode(long sync_async, void (*callback_fun)(long, long));
384  
385  struct linux_syscalls_list;
386  void rt_exec_linux_syscall(RT_TASK *rt_current, struct linux_syscalls_list *syscalls, struct pt_regs *regs);
387  
388  RTAI_SYSCALL_MODE void rt_return_linux_syscall(RT_TASK *task, unsigned long retval);
389  
390  RTAI_SYSCALL_MODE int rt_irq_wait(unsigned irq);
391  
392  RTAI_SYSCALL_MODE int rt_irq_wait_if(unsigned irq);
393  
394  RTAI_SYSCALL_MODE int rt_irq_wait_until(unsigned irq, RTIME until);
395  
396  RTAI_SYSCALL_MODE int rt_irq_wait_timed(unsigned irq, RTIME delay);
397  
398  RTAI_SYSCALL_MODE void rt_irq_signal(unsigned irq);
399  
400  RTAI_SYSCALL_MODE int rt_request_irq_task (unsigned irq, void *handler, int type, int affine2task);
401  
402  RTAI_SYSCALL_MODE int rt_release_irq_task (unsigned irq);
403  
404  RTAI_SYSCALL_MODE int rt_task_make_periodic_relative_ns(struct rt_task_struct *task,
405  				      RTIME start_delay,
406  				      RTIME period);
407  
408  RTAI_SYSCALL_MODE int rt_task_make_periodic(struct rt_task_struct *task,
409  			  RTIME start_time,
410  			  RTIME period);
411  
412  RTAI_SYSCALL_MODE void rt_task_set_resume_end_times(RTIME resume,
413  				  RTIME end);
414  
415  RTAI_SYSCALL_MODE int rt_set_resume_time(struct rt_task_struct *task,
416  		       RTIME new_resume_time);
417  
418  RTAI_SYSCALL_MODE int rt_set_period(struct rt_task_struct *task,
419  		  RTIME new_period);
420  
421  int rt_task_wait_period(void);
422  
423  void rt_schedule(void);
424  
425  RTIME next_period(void);
426  
427  RTAI_SYSCALL_MODE void rt_busy_sleep(int nanosecs);
428  
429  RTAI_SYSCALL_MODE int rt_sleep(RTIME delay);
430  
431  RTAI_SYSCALL_MODE int rt_sleep_until(RTIME time);
432  
433  RTAI_SYSCALL_MODE int rt_task_masked_unblock(struct rt_task_struct *task, unsigned long mask);
434  
435  #define rt_task_wakeup_sleeping(t)  rt_task_masked_unblock(t, RT_SCHED_DELAYED)
436  
437  RTAI_SYSCALL_MODE struct rt_task_struct *rt_named_task_init(const char *task_name,
438  					  void (*thread)(long),
439  					  long data,
440  					  int stack_size,
441  					  int prio,
442  					  int uses_fpu,
443  					  void(*signal)(void));
444  
445  RTAI_SYSCALL_MODE struct rt_task_struct *rt_named_task_init_cpuid(const char *task_name,
446  						void (*thread)(long),
447  						long data,
448  						int stack_size,
449  						int prio,
450  						int uses_fpu,
451  						void(*signal)(void),
452  						unsigned run_on_cpu);
453  
454  RTAI_SYSCALL_MODE int rt_named_task_delete(struct rt_task_struct *task);
455  
456  RT_TRAP_HANDLER rt_set_task_trap_handler(struct rt_task_struct *task,
457  					 unsigned vec,
458  					 RT_TRAP_HANDLER handler);
459  
460  static inline RTIME timeval2count(struct timeval *t)
461  {
462          return nano2count(t->tv_sec*1000000000LL + t->tv_usec*1000);
463  }
464  
465  static inline void count2timeval(RTIME rt, struct timeval *t)
466  {
467          t->tv_sec = rtai_ulldiv(count2nano(rt), 1000000000, (unsigned long *)&t->tv_usec);
468          t->tv_usec /= 1000;
469  }
470  
471  static inline RTIME timespec2count(const struct timespec *t)
472  {
473          return nano2count(t->tv_sec*1000000000LL + t->tv_nsec);
474  }
475  
476  static inline void count2timespec(RTIME rt, struct timespec *t)
477  {
478          t->tv_sec = rtai_ulldiv(count2nano(rt), 1000000000, (unsigned long *)&t->tv_nsec);
479  }
480  
481  static inline RTIME timespec2nanos(const struct timespec *t)
482  {
483          return t->tv_sec*1000000000LL + t->tv_nsec;
484  }
485  
486  static inline void nanos2timespec(RTIME rt, struct timespec *t)
487  {
488          t->tv_sec = rtai_ulldiv(rt, 1000000000, (unsigned long *)&t->tv_nsec);
489  }
490  
491  void rt_make_hard_real_time(RT_TASK *task);
492  
493  void rt_make_soft_real_time(RT_TASK *task);
494  
495  #ifdef __cplusplus
496  }
497  #else /* !__cplusplus */
498  
499  /* FIXME: These calls should move to rtai_schedcore.h */
500  
501  RT_TASK *rt_get_base_linux_task(RT_TASK **base_linux_task);
502  
503  RT_TASK *rt_alloc_dynamic_task(void);
504  
505  void rt_enq_ready_edf_task(RT_TASK *ready_task);
506  
507  void rt_enq_ready_task(RT_TASK *ready_task);
508  
509  int rt_renq_ready_task(RT_TASK *ready_task,
510  		       int priority);
511  
512  void rt_rem_ready_task(RT_TASK *task);
513  
514  void rt_rem_ready_current(RT_TASK *rt_current);
515  
516  void rt_enq_timed_task(RT_TASK *timed_task);
517  
518  void rt_rem_timed_task(RT_TASK *task);
519  
520  void rt_dequeue_blocked(RT_TASK *task);
521  
522  RT_TASK **rt_register_watchdog(RT_TASK *wdog,
523  			       int cpuid);
524  
525  void rt_deregister_watchdog(RT_TASK *wdog,
526  			    int cpuid);
527  
528  #endif /* __cplusplus */
529  
530  #endif /* __KERNEL__ */
531  
532  #if !defined(__KERNEL__) || defined(__cplusplus)
533  
534  typedef struct rt_task_struct {
535      int opaque;
536  } RT_TASK;
537  
538  typedef struct QueueBlock {
539      int opaque;
540  } QBLK;
541  
542  typedef struct QueueHook {
543      int opaque;
544  } QHOOK;
545  
546  #endif /* !__KERNEL__ || __cplusplus */
547  
548  #endif /* !_RTAI_SCHED_H */