preempt: much closer
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 15 Aug 2008 19:34:39 +0000 (19:34 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Fri, 15 Aug 2008 19:34:39 +0000 (19:34 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1642 38d2e660-2303-0410-9eaa-f027e97ec537

app/demo/demo.mk
bertos/kern/preempt.c
bertos/kern/proc.c
bertos/kern/proc_p.h

index 941e28a6b76e911a37f9463d894e635e7229e39c..a66e0f893723f2b8b628d27a80f3612ceffd531c 100644 (file)
@@ -19,6 +19,7 @@ TRG += demo
 
 # FIXME: we want to use g++ for C source too
 CC = g++
+CXX = g++
 
 demo_CXXSRC = \
        bertos/emul/emul.cpp \
index dfa343d7a9b702c769a590d8b76e0a409bdec9e2..ab3fc7a8f7db005e5f1e3f2c8623b8647a6a737e 100644 (file)
@@ -92,10 +92,12 @@ void proc_preempt(void)
 
        ATOMIC(LIST_ASSERT_VALID(&ProcReadyList));
 
+       TRACEMSG("hello1");
        IRQ_DISABLE;
        /* Poll on the ready queue for the first ready process */
        while (!(CurrentProcess = (struct Process *)list_remHead(&ProcReadyList)))
        {
+       TRACEMSG("hello2");
                /*
                 * Make sure we physically reenable interrupts here, no matter what
                 * the current task status is. This is important because if we
@@ -109,11 +111,13 @@ void proc_preempt(void)
                 * are reloaded.
                 */
                IRQ_ENABLE;
-               CPU_IDLE;
+               //FIXME: calls Qt stuff from sighandler! CPU_IDLE;
                MEMORY_BARRIER;
                IRQ_DISABLE;
+       TRACEMSG("hello3");
        }
        IRQ_ENABLE;
+       TRACEMSG("hello4");
 }
 
 void proc_preempt_timer(void)
@@ -121,12 +125,20 @@ void proc_preempt_timer(void)
        // TODO: check Quantum
 
        alarm(1);
-       ATOMIC(SCHED_ENQUEUE(CurrentProcess));
-       proc_schedule();
+
+       if (CurrentProcess)
+       {
+               TRACEMSG("preempting %p:%s", CurrentProcess, CurrentProcess->monitor.name);
+               ATOMIC(SCHED_ENQUEUE(CurrentProcess));
+               proc_schedule();
+       }
 }
 
 void proc_schedule(void)
 {
+       TRACE;
+
+       // Will invoke proc_preempt() in interrupt context
        kill(0, SIGUSR1);
 }
 
@@ -137,21 +149,27 @@ void proc_yield(void)
        proc_schedule();
 }
 
+void proc_entry(void (*user_entry)(void))
+{
+       user_entry();
+       proc_exit();
+}
+
 /* signal handler */
 void irq_entry(int signum)
 {
        Process *old_process;
 
-       TRACEMSG("storing %p:%s", CurrentProcess, CurrentProcess->monitor.name);
-       CurrentProcess->leaving = false;
-       getcontext(&CurrentProcess->context);
+//     TRACEMSG("storing %p:%s", CurrentProcess, CurrentProcess->monitor.name);
+//     CurrentProcess->leaving = false;
+//     getcontext(&CurrentProcess->context);
        /* We get here in two ways: directly, and after setcontext() below */
 
-       if (CurrentProcess->leaving)
-       {
-               TRACEMSG("leaving to %p:%s", CurrentProcess, CurrentProcess->monitor.name);
-               return;
-       }
+//     if (CurrentProcess->leaving)
+//     {
+//             TRACEMSG("leaving to %p:%s", CurrentProcess, CurrentProcess->monitor.name);
+//             return;
+//     }
 
        old_process = CurrentProcess;
 
@@ -159,9 +177,13 @@ void irq_entry(int signum)
 
        if (old_process != CurrentProcess)
        {
-               TRACEMSG("launching %p:%s", CurrentProcess, CurrentProcess->monitor.name);
-               CurrentProcess->leaving = true;
-               setcontext(&CurrentProcess->context);
+               TRACEMSG("switching from %p:%s to %p:%s",
+                       old_process, old_process->monitor.name,
+                       CurrentProcess, CurrentProcess->monitor.name);
+               swapcontext(&old_process->context, &CurrentProcess->context);
+//             TRACEMSG("launching %p:%s", CurrentProcess, CurrentProcess->monitor.name);
+//             CurrentProcess->leaving = true;
+//             setcontext(&CurrentProcess->context);
                /* not reached */
        }
 
index afe9e34a92e5430a9832d2d76a0d2ce2907c15d1..3f2548923dbc1527660cdf3138a091c285f00aee 100644 (file)
@@ -52,9 +52,6 @@
 
 #include <string.h>           /* memset() */
 
-#if CONFIG_KERN_PREEMPT
-#include "preempt.h"
-#endif
 
 /*
  * The scheduer tracks ready processes by enqueuing them in the
@@ -209,7 +206,7 @@ struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(voi
        proc->context.uc_stack.ss_sp = stack_base;
        proc->context.uc_stack.ss_size = stack_size;
        proc->context.uc_link = NULL;
-       makecontext(&proc->context, entry, 0);
+       makecontext(&proc->context, (void (*)(void))proc_entry, 1, entry);
 
 #else // !CONFIG_KERN_PREEMPT
        /* Initialize process stack frame */
@@ -248,7 +245,7 @@ void proc_rename(struct Process *proc, const char *name)
  */
 void proc_exit(void)
 {
-       TRACE;
+       TRACEMSG("%p:%s", CurrentProcess, CurrentProcess->monitor.name);
 
 #if CONFIG_KERN_MONITOR
        monitor_remove(CurrentProcess);
index a98f9428aa65f684ad414c4f2a0267c67f0547a1..fbac38fc565a59016267868d9a20f95a0c64fe9e 100644 (file)
@@ -122,6 +122,11 @@ extern REGISTER List     ProcReadyList;
 /** Schedule to another process *without* adding the current to the ready list. */
 void proc_schedule(void);
 
+#if CONFIG_KERN_PREEMPT
+void proc_entry(void (*user_entry)(void));
+void preempt_init(void);
+#endif
+
 #if CONFIG_KERN_MONITOR
        /** Initialize the monitor */
        void monitor_init(void);