标签:index nal dex 算法 很多 style tar his ESS
/* Maximum priority level, 32 */ rt_uint32_t rt_thread_ready_priority_group; //[0:31]每一位代表一个线程优先级
1. rt_thread_ready_priority_group是一个32位全局变量,如果有新的线程创建,则会把对应的线程优先级在rt_thread_ready_priority_group对应的bit位置1。
例如:新创建的线程优先级为8,则由1,2可以看出将rt_thread_ready_priority_group的第8位置位1。
2.接下来在rt_schedule中看rt_thread_ready_priority_group变量的使用。
const rt_uint8_t __lowest_bit_bitmap[] = { /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; /** * This function finds the first bit set (beginning with the least significant bit) * in value and return the index of that bit. * * Bits are numbered starting at 1 (the least significant bit). A return value of * zero from any of these functions means that the argument was zero. * * @return return the index of the first bit set. If value is 0, then this function * shall return 0. */ int __rt_ffs(int value) { if (value == 0) return 0; if (value & 0xff) return __lowest_bit_bitmap[value & 0xff] + 1; if (value & 0xff00) return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9; if (value & 0xff0000) return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17; return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25; }
源码中的__lowest_bit_bitmap数组是根据线程优先级进行提前推算出来的。value也即rt_thread_ready_priority_group。
例如: value = 8, 8的二进制为1000,从右往左数,第一个为1的位在第3位(默认从0开始)。所以__lowest_bit_bitmap[8]为3。
value = 5, 5的二进制为101,从右往走数,第一个为1的位在第0位。所以__lowest_bit_bitmap[5]为0。
value = 16, 5的二进制为10000,从右往走数,第一个为1的位在第4位。所以__lowest_bit_bitmap[16]为4。
由数组可以找到rt_thread_ready_priority_group数值对应的最高优先级数为多少,也就找到了最高优先级线程所在的链表。
而通过3求得的highest_ready_priority有如下作用:
RT-Thread中的TCB数据结构,我们暂时只记住tlist成员:
struct rt_thread { /* rt object */ char name[RT_NAME_MAX]; /**< the name of thread */ rt_uint8_t type; /**< type of object */ rt_uint8_t flags; /**< thread‘s flags */ #ifdef RT_USING_MODULE void *module_id; /**< id of application module */ #endif rt_list_t list; /**< the object list */ rt_list_t tlist; /**< the thread list */ /* stack point and entry */ void *sp; /**< stack point */ void *entry; /**< entry */ void *parameter; /**< parameter */ void *stack_addr; /**< stack address */ rt_uint32_t stack_size; /**< stack size */ /* error code */ rt_err_t error; /**< error code */ rt_uint8_t stat; /**< thread status */ /* priority */ rt_uint8_t current_priority; /**< current priority */ rt_uint8_t init_priority; /**< initialized priority */ #if RT_THREAD_PRIORITY_MAX > 32 rt_uint8_t number; rt_uint8_t high_mask; #endif rt_uint32_t number_mask; #if defined(RT_USING_EVENT) /* thread event */ rt_uint32_t event_set; rt_uint8_t event_info; #endif #if defined(RT_USING_SIGNALS) rt_sigset_t sig_pending; /**< the pending signals */ rt_sigset_t sig_mask; /**< the mask bits of signal */ void *sig_ret; /**< the return stack pointer from signal */ rt_sighandler_t *sig_vectors; /**< vectors of signal handler */ void *si_list; /**< the signal infor list */ #endif rt_ubase_t init_tick; /**< thread‘s initialized tick */ rt_ubase_t remaining_tick; /**< remaining tick */ struct rt_timer thread_timer; /**< built-in thread timer */ void (*cleanup)(struct rt_thread *tid); /**< cleanup function when thread exit */ /* light weight process if present */ #ifdef RT_USING_LWP void *lwp; #endif rt_uint32_t user_data; /**< private user data beyond this thread */ };
优先级链表:
rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; //每一个优先级对应一个链表。是通过rt_thread结构中的tlist成员来进行相同优先级线程的链接
通过tlist成员来获取对应的rt_thread结构体的首地址信息。
/* get switch to thread */
/*/ to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next, struct rt_thread, tlist);
#define rt_list_entry(node, type, member) \ rt_container_of(node, type, member) #define rt_container_of(ptr, type, member) \ //在linux内核中该用法有很多 ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
该成员所在的地址 - 该成员相对于结构体偏移的地址 = 该结构体的首地址
综上,就可以找到对应的优先级数最高的线程进行调度。由于表是提前计算好的,所以时间复杂度为o(1)。
【RT-Thread】内核线程调度算法(基于位图的线程调度算法)
标签:index nal dex 算法 很多 style tar his ESS
原文地址:https://www.cnblogs.com/Raowz/p/13163120.html