Page 1 of 2
killing tasks
Posted: Sat Mar 08, 2008 1:23 pm
by lukem95
i'm using JamesM's code as a starting point, and implemented (what i thought) was a working kill_task() function. to cut a long story short, it didn't work.
I know how i would make one, but it just doesn't seem to work for me.
I tried to adapt the task_t struct so there was a link to the previous task in the linked list, and then alter this so that it skipped the current task (one being killed) in the scheduler. This resulted in my multitasking halting suddenly, and despite a whole lot of debugging, i never came to a conclusion as to why.
I also tried changing the EIP to zero, and checking for this in my switch_task() function. I thought this worked, but i guess not.
does anybody have a working implementation i could take a peek at?
Posted: Sat Mar 08, 2008 1:33 pm
by t0xic
I don't use JamesM's code, but I have a "status" flag in my task_t struct. When I kill a task, I set it to a value which is then checked in my scheduler. If the flag is set, then the scheduler will rotate to the next task (I use a round robin scheduler)
Hope that helped.
--Michael
Posted: Sat Mar 08, 2008 1:50 pm
by lukem95
yeah thats what im trying to do, but it doesn't seem to work.
I'll keep fiddling, if anyone has any other ideas or suggestion (or code) it would be appreciated
Posted: Sat Mar 08, 2008 1:59 pm
by t0xic
I can spare some code:
Code: Select all
/* uint32 sched(uint32 esp)
* Called by the timer IRQ0 handler,
* returns the stack of the next task */
uint32 sched(uint32 esp)
{
AtomicIncrement(&timer_ticks); // Increment tick count
if (sched_active == 0) // Is multitasking enabled?
return esp; // Scheduler turned off
tasks[current_pid].stack = esp; // Save old esp
switch_pid(); // Find next pid
if (tasks[current_pid].state) // Is task still running?
{
tasks[current_pid].spins++;
return tasks[current_pid].stack;
}
else // No active tasks
{
return esp; // Don't switch - no active tasks
}
}
Posted: Sat Mar 08, 2008 3:08 pm
by piranha
If you mean an exit() function, here's mine (using JamesM's tutorials):
Code: Select all
int exit()
{
// We are modifying kernel structures, and so cannot interrupt
asm volatile("cli");
// Set up some basic task structs
task_t *task_d = 0;
task_t *task_r = (task_t*)ready_queue;
//task_r is already initalized
//While the next task is not NULL (end of Linked List)
//Set test_r to the next task
for(;task_r->next!=0;task_r=task_r->next)
{
if(task_r->next == current_task)
task_d=task_r; // Now we have the previous task
}
if(!task_d) //Make sure that the above worked
return -1;
task_d->next = current_task->next; //Remove current_task from the list
kfree(current_task); //Free up the memory
switch_task(); //We must update the scheduler, or current_task will run for a bit more
asm volatile("sti"); //Restart interrupts
return 0;
}
-JL
Posted: Sat Mar 08, 2008 3:21 pm
by lukem95
thankyou both for your code, iv hacked together something that works, im gonna use piranas idea to try and reduce the overhead.
Posted: Sat Mar 08, 2008 3:34 pm
by jerryleecooper
I diodn't read the whole thread sorry it makes my head spin fast.
What I use myself, as an exit function, it just set a flag in the process struct saying that is it to be removed, and immediately there's an infinite loop. THe scheduler takes care of removing the process. It's not optimal, no? But's easy, really easy. a lot easier than doing the same and issuing an interrupt immediately for the scheduler switching process.
Simplicity is better than economizing a few cycles, I think. If you really want to get your few cycles, do a syscall to your scheduler.
Posted: Sat Mar 08, 2008 3:43 pm
by lukem95
yeah, im working on shaving down those few.
one aim i have with my kernel is to optimise it as much as i can now, so it saves me time later.
Posted: Sat Mar 08, 2008 8:45 pm
by pcmattman
issuing an interrupt immediately for the scheduler switching process.
You should really write your scheduler so it doesn't need an interrupt to switch two tasks. It kills a lot of overhead.
Posted: Sat Mar 08, 2008 9:56 pm
by jerryleecooper
The scheduler itself doesn't do anything with interrupts, ignoring processes that are marked as slepping or thoses that are waiting. removing the processes marked as remove. It then select the next process to run in the list, beggining in the beginning when it reach the last one, the famous idle process. What it does when it has selected the process to run is to set 2 global variables. and when the handler() function that is called each time an interrupt fires returns, set the tss accordingly, and the asm code sets the stack from one of the global variable.
But these info I just gave are probably redundant since some of you are well over the step of implementing a multitasker.
I don't know of any other method to switch processes.
Posted: Sun Mar 09, 2008 1:15 am
by pcmattman
that is called each time an interrupt fires returns
My point is, it still requires an interrupt to switch. My switcher can switch inline, so you call kSchedule and when it returns ever other process has had its timeslice.
If anyone wants any tips as to how to implement this PM me.
Posted: Sun Mar 09, 2008 2:01 am
by JamesM
My point is, it still requires an interrupt to switch. My switcher can switch inline, so you call kSchedule and when it returns ever other process has had its timeslice.
Unless you're using syscall/sysret, *every* call to the scheduler requires an interrupt, whether it's IRQ or software generated.
Posted: Sun Mar 09, 2008 2:08 am
by pcmattman
JamesM: I'm talking about code within the kernel. If the kill() function is within the kernel and an interrupt comes in as a system call, you can still call the reschedule function and have it do whatever it has to.
When I said "it still requires an interrupt to switch" I mean that it still depends on an interrupt firing to switch tasks, which is a nuisance IMHO.
Posted: Sun Mar 09, 2008 4:15 am
by JamesM
Surely that's the same as piranha's snippet, though? They're functionally equivalent, AFAICS.
Posted: Sun Mar 09, 2008 4:24 am
by pcmattman
I think I may have misinterpreted jerryleecooper's comment earlier, leading me down a path of incorrect assumptions.
Sorry for the confusion!