在本章,我们对rtlinux的一些主要API源代码进行分析,从而更加深层次了解rtlinux的调度原理。本文根据程序的调度顺序依次介绍这些函数。
3.1 rtl_thread_struct
struct rtl_thread_struct {
int *stack;/* hardcoded */
int fpu_initialized;
RTL_FPU_CONTEXT fpu_regs;
int uses_fp;
int *kmalloc_stack_bottom;
//以上为线程的栈空间,
struct rtl_sched_param
sched_param;、//线程的调度参数
struct rtl_thread_struct
*next;//该线程在线程链表中的后继线程
int cpu;//所属CPU
hrtime_t resume_time;//唤醒时间
hrtime_t period;//周期大小
hrtime_t timeval;
struct module *creator;
void (*abort)(void *);
void *abortdata;
int threadflags;//线程标志
rtl_sigset_t pending;//待处理信号
rtl_sigset_t blocked;//阻塞信号
void *user[4];
int errno_val;
struct rtl_cleanup_struct
*cleanup;
int magic;
struct
rtl_posix_thread_struct posix_data;
void *tsd [RTL_PTHREAD_KEYS_MAX];
}__cacheline_aligned;
该结构体包括实时线程的所有属性。其中为注释的属性要么我在FALinux为做更改,要么我也不理解其用处(分析的代码有限,不能完全理解,比较汗颜。)
1.struct rtl_sched_param sched_param。该属性为线程的调度参数。为了更好的理解该属性,可以仔细看如下代码:
#ifdef __cplusplus
struct sched_param {
int
sched_priority;
};
#define SCHED_OTHER0
#define SCHED_FIFO1
#define SCHED_RR2
#else
#include
#endif
#define rtl_sched_param sched_param
看了上面的代码,说句丢脸的话,我第一次明白cplusplus是C++。呵呵。很容易可以看到,在这里面主要涉及两种属性,一为优先级,二为调度策略。我们也可以看看linux/sched.h中的相关内容。
#define SCHED_OTHER0
#define SCHED_FIFO1
#define SCHED_RR2
/*
* This is
an additional bit set when we want to
* yield
the CPU for one re-schedule..
*/
#define SCHED_YIELD0x10
struct sched_param {
int
sched_priority;
};
两者之间内容几乎一样。其实在实时程序中,真正有用的也就是sched_priority,调度策略SCHED_FIFO根本在这只是摆设。可以从rtl_sched_param的相关函数中看出。
extern inline int
pthread_attr_setschedparam(pthread_attr_t *attr, const struct rtl_sched_param
*param) {
attr->sched_param
= *param;
return 0;
}
该函数在前面我们已经涉及到了,很容易发现,该函数的第二个参数在函数体中并没有涉及,涉及的就仅仅是sched_param,也就是sched_priority。
2.struct rtl_thread_struct *next。每个新线程在创建之后都会加入大系统的线程链表中,每个线程执行完毕后都会从该链表中删除。而next就是执行该线程的后继线程。该链表中线程的存放顺序按优先级从大到小排列。
3.resume_time与period用来控制周期线程的执行。
4.int threadflags;//线程标志,这些标志包括enum {RTL_CANCELPENDING, RTL_CANCELTYPE,
RTL_THREAD_JOINABLE, RTL_THREAD_FINISHED,RTL_THREAD_TIMERARMED,RTL_THREAD_WAIT_FOR_JOIN,RTL_THREAD_OK_TO_FINISH_JOIN,
RTL_THREAD_SIGNAL_INTERRUMPIBLE}。这些标志的用处在以后具体函数的应用中进行解释。
5.rtl_sigset_t pending;//待处理信号。信号技术是linux的关键技术之一,所有待处理信号都会写在该属性中。当线程得到CPU使用权后,首先判断该线程是否有未处理的信号。如果该信号并未阻塞,则执行该信号的处理程序,否则执行该线程的执行函数。
6.rtl_sigset_t blocked;//阻塞信号。当某些信号发生而线程不想响应该信号时,设置该属性的相应标志位,就可以让系统忽略该信号。
除了以上的属性外,我们在FALinux中还加入了一些新的属性。这在后面FALinux的具体实现中做详细解释。