I have been trying to implement sleep properly in my kernel for the last few days. I have tried various mechanisms and apparently none of them seem to be working at this point. Basically, my sleep is a system call that basically runs an idle loop till the number of sleep seconds expires. I am using the PIT timer to keep decrementing a global variable that tells me if the timer has expired/not. I have declared ticks globally.
Code: Select all
int ticks = 0;
Code: Select all
void i86_pit_irq(){
i86_set_mask(1);
// sleeping processes in queue
ticks++;
i86_pic_send_eoi_command(32);
struct pcb *process = sleeping_queue.processes;
while(process != NULL)
{
if(process->sleep_time == 0)
{
try_to_wake_up(&sleeping_queue, process);
}
else
{
process->sleep_time = process->sleep_time - 1;
}
process = process->next_in_queue;
}
struct pcb *current = get_current_process();
if(current->is_sigkill_pending) // current is current process
{
/* usually involves killing the process- signals are always handled by current process */
current->is_sigkill_pending = 0;
sys_exit(9); // signal code KILL -9
}
else if(current->is_sigsegv_pending)
{
current->is_sigsegv_pending = 0;
sys_exit(11); // signal code : 11
}
current->time_slice = current->time_slice - 1;
if(current->time_slice <= 0)
{
schedule();
}
i86_clear_mask(1);
}
Code: Select all
void sys_sleep(unsigned long seconds)
{
unsigned int timer_ticks;
timer_ticks = ticks + (seconds * 1000);
/*
kprintf("sleeping for %d seconds ", seconds);*/
while(ticks < timer_ticks);
kprintf("sleep done");
}
The problem here is that the sys_sleep function does not return. It basically keeps running the while loop even after the condition has become false (when ticks > timer_ticks).
I tried using gdb to see in assembly which instruction is getting executed repeatedly. I noticed a peculiar jmp instruction.
Code: Select all
0xffffffff80201567 <sys_sleep+13> add (%rax),%edi
0xffffffff80201569 <sys_sleep+15> cmp (%rax),%edi
0xffffffff8020156b <sys_sleep+17> jbe 0xffffffff8020156f <sys_sleep+21>
0xffffffff8020156d <sys_sleep+19> jmp 0xffffffff8020156d <sys_sleep+19>
The fourth jump instruction seems to be the culprit as it is jumping to the same address repeatedly and hence the system is going to an infinite loop.
I am quite confused as to what a proper sleep implementation would be. Is my current implementation correct ? If so, what is causing this bug ? Should I change my design in any way ?
Thanks.