add inline assembler functions to determine the MSB and LSB

This commit is contained in:
Stefan Lankes 2011-09-01 13:31:41 -07:00
parent 8f00510250
commit e6fb99beb4
2 changed files with 30 additions and 15 deletions

View file

@ -272,22 +272,42 @@ static inline uint32_t read_eflags(void)
return result;
}
/** @brief search the first bit, which is set
/** @brief search the first most significant bit
*
* @param i source operand
* @return first bit, which is set in the source operand
* @return
* - first bit, which is set in the source operand
* - invalid value, if not bit ist set
*/
static inline uint32_t last_set(uint32_t i)
static inline size_t msb(size_t i)
{
uint32_t ret;
size_t ret;
if (!i)
return 0;
return (sizeof(size_t)*8);
asm volatile ("bsr %1, %0" : "=r"(ret) : "r"(i) : "cc");
return ret;
}
/** @brief search the least significant bit
*
* @param i source operand
* @return
* - first bit, which is set in the source operand
* - invalid value, if not bit ist set
*/
static inline size_t lsb(size_t i)
{
size_t ret;
if (!i)
return (sizeof(size_t)*8);
asm volatile ("bsf %1, %0" : "=r"(ret) : "r"(i) : "cc");
return ret;
}
/** @brief Read extended instruction pointer
* @return The EIP's value
*/

View file

@ -69,7 +69,7 @@ task_t* get_current_task(void) {
}
uint32_t get_highest_priority(uint32_t core_id) {
return last_set(runqueues[core_id].prio_bitmap);
return msb(runqueues[core_id].prio_bitmap);
}
int multitasking_init(void) {
@ -1228,20 +1228,15 @@ void scheduler(void)
}
runqueues[core_id].old_task = NULL; // reset old task
prio = last_set(runqueues[core_id].prio_bitmap); // determines highest priority
prio = msb(runqueues[core_id].prio_bitmap); // determines highest priority
#if MAX_CORES > 1
if (!prio) {
if (prio >= sizeof(size_t)*8) {
load_balancing();
prio = last_set(runqueues[core_id].prio_bitmap); // retry...
prio = msb(runqueues[core_id].prio_bitmap); // retry...
}
#endif
if (BUILTIN_EXPECT(prio > MAX_PRIO, 0)) {
kprintf("Invalid priority %u by bitmap 0x%x\n", prio, runqueues[core_id].prio_bitmap);
prio = 0;
}
if (!prio) {
if (prio >= sizeof(size_t)*8) {
if ((curr_task->status == TASK_RUNNING) || (curr_task->status == TASK_IDLE))
goto get_task_out;
curr_task = per_core(current_task) = runqueues[core_id].idle;