The priority is an important attribute of the task and the basis for the kernel during scheduling. For priority management in Nucleus, people who carefully see the code should be clear. But the query table used in it, I think it is not every person. And if you don't know why the query is that looks, I estimate that you will not be very thorough for priority management.
The following first concurrently introduces the operation related to priority.
/ * Two global variables * /
EXTERN UNSIGNED TCD_PRIORITY_GROUPS; / * Unsigned long * / extern data_element tcd_sub_priority_groups [tc_max_groups]; / * unsigned char * /
1. Create a task
/ * Low three digits of priority value as its value in a certain priority group * / task -> tc_sub_priority = (DATA_ELEMENT) (1 << (Priority & 7)); / * High five digits of priority value It is the index value of the priority group * / priority = priority >> 3; / * If a priority belongs to a priority group, the corresponding position 1 * / task -> tc_priority_group = ((unsigned) 1) << priority ; / * Save pointer to priority group * / task -> tc_sub_priority_ptr = & (tcd_sub_priority_groups [priority]);
2. When running a TASK
/ * According to the two values of Task * / / * Update the prior Group bit map to indeicate That priority now Has a task ready. * / Tcd_priority_groups = tcd_priority_groups | (Task -> tc_priority_group); / * Update the sub-priority bit map to show what priority is ready. * / * (Task -> tc_sub_priority_ptr) = (* (Task -> tc_sub_priority_ptr)) | Task -> TC_SUB_PRIORITY
3. Inquiry the current highest priority
#define TC_HIGHEST_MASK 0x000000Fful # define TC_NEXT_HIGHEST_MASK 0x0000FF00UL # Define TC_NEXT_LOWEST_MASK 0x00FF0000UL # define TC_LOWEST_MASK 0xFF000000UL
/ * Find the next highest priority task. * / / * Is divided into two processes: find the lowest priority group and the minimum priority priority group in the priority group, organize in eight groups, first judging Which group is given a start value. * / If (TCD_Priority_Groups & TC_HIGHEST_MASK) / * Base of sub-group is 0. * / index = 0; else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) / * Base of sub-group is 8. * / index = 8; else if ( TCD_PRIORITY_GROUPS & TC_NEXT_LOWEST_MASK) / * base of sub-group is 16. * / index = 16; Else / * base of sub-group is 24. * / index = 24; / * Calculate the highest available priority. * / / * Take the TCD_PRIORITY_GROUPS value with the set of related data as an index value to query in the table to obtain an offset value relative to the start value, and the two is added to the priority group where the current highest priority TASK is located. * / Index = index TCD_Lowest_Set_Bit [(INT) (TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)]; / * Get the mask of the priority within the group of 8 priorities * / temp = TCD_Sub_Priority_Groups [index];. / * Calculate the Actual priority. * / * The value check in the priority group corresponding to Task is obtained in the highest priority in this priority group, and the value of the priority group by 8 is added, that is, the current highest priority Level * / TCD_HIGHEST_PRIORITY = (Index << 3) TCD_LOWEST_SET_BIT [TEMP]; / **************************************************** *********************************************************** ***** / The following focuses on this query table.
First give an example to illustrate the specific query process. Suppose the TCD_PRIORITY_GROUPS value is 0x00208C00 (0000 0000 0010 0000 1000 1100 0000 0000), then index = 8, then remove 0x8c, as an index value query in the table, get 2, two add 10, this is the highest priority The value of the priority group. Then suppose TCD_SUB_PRIORITY_GROUPS [10] = 2, the query is obtained in the table, and the highest priority is 10 * 8 2 = 82. So what is the data in this table? In fact, according to this table, it is the location of a given 1 to 1 in a given eight-bit binary value. Understand this, you can understand this form. For example, when the lowest 1 is 0 (0, 1, 2 ... 7) from the low position to the high position, the value of the foundation is always 0 regardless of the value of the high position. That is, regardless of the value given from 0000 0001b to 1111 1111b, the value obtained by querying the value is 0. Thus, in the table, 1 (0000 000 0001), 3 (0000 0011), 5 (0000 0101), ... each place should be filled. When the lowest 1 is in the first bit, regardless of the value of the high position, the value of the foundation is always 1. That is, no matter which value given is from 0000 0010b to 1111 1110b, the value obtained by querying the value is 1. Thus, on the table, on the table, No. 2 (0000 0000), 6 (0000 0110), 10 (0000 1010) ... each place should be filled in 1. When the lowest 1 is in the second place, the 4th, 12th, 20 ... of the table should be filled 2. When the lowest 1 is located in the third place, the 8th, 24th, 40th ... of the table should be filled 3. These values are located in the table of the table. When the lowest 1 is on the 4th, 5th, 6th positions. When the lowest 1 is located 7th, there is only one value, that is, the 128th value is 7. The data at the 0th position in the table is 0, but this value is not used. The above is a description of the query table used in Nucleus, in fact, in the UCOS-II, the author has also been carefully analyzed. Appendix: Partial code and query table
/ * TCC_CREATE_TASK () * / task -> tc_sub_priority = (data_element) (1 << (Priority & 7)); priority = priority >> 3; Task -> tc_priority_group = ((unsigned) 1) << priority; task - > tc_sub_priority_ptr = & (TCD_Sub_Priority_Groups [priority]); / * TCC_Resume_Task () * / / * Update the priority group bit map to indicate that this priority now has a task ready * / TCD_Priority_Groups = TCD_Priority_Groups | (task -> tc_priority_group);. / * Update the sub-priority bit map to show that this priority is ready * / * (task -> tc_sub_priority_ptr) = (* (task -> tc_sub_priority_ptr)) | task -> tc_sub_priority;. / * TCC_Signal_Shell () * / / * Find the next highest priority task * / if (TCD_Priority_Groups & TC_HIGHEST_MASK) / * Base of sub-group is 0. * / index = 0;. else if (TCD_Priority_Groups & TC_NEXT_HIGHEST_MASK) / * Base of sub-group is 8. * / Index = 8; Else IF (TCD_PRIRITY_GROUPS & TC_NEXT_LOWEST_MASK) / * Base of Sub-Group IS 16. * / INDEX = 16; else / * Base of sub-group is 24. * / index = 24;. / * Calculate the highest available priority * / index = index TCD_Lowest_Set_Bit [(INT) ((TCD_Priority_Groups >> index) & TC_HIGHEST_MASK)] ; / * Get the mask of the priority within the group of 8 priorities * / temp = TCD_Sub_Priority_Groups [index];.. / * Calculate the actual priority * / TCD_Highest_Priority = (index << 3) TCD_Lowest_Set_Bit [temp]; / * This table is rearranged to make it easy to understand * / unsigned_char tcd_lowest_set_bit [] =