[svn:parrot] r48010 - in branches/gsoc_threads: include/parrot src src/pmc

Chandon at svn.parrot.org Chandon at svn.parrot.org
Mon Jul 5 15:36:04 UTC 2010


Author: Chandon
Date: Mon Jul  5 15:36:03 2010
New Revision: 48010
URL: https://trac.parrot.org/parrot/changeset/48010

Log:
[gsoc_threads] Everything is a task.

Modified:
   branches/gsoc_threads/include/parrot/scheduler.h
   branches/gsoc_threads/src/alarm.c
   branches/gsoc_threads/src/embed.c
   branches/gsoc_threads/src/main.c
   branches/gsoc_threads/src/pmc/task.pmc
   branches/gsoc_threads/src/scheduler.c

Modified: branches/gsoc_threads/include/parrot/scheduler.h
==============================================================================
--- branches/gsoc_threads/include/parrot/scheduler.h	Mon Jul  5 14:33:31 2010	(r48009)
+++ branches/gsoc_threads/include/parrot/scheduler.h	Mon Jul  5 15:36:03 2010	(r48010)
@@ -31,6 +31,16 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
+void  Parrot_cx_begin_execution(PARROT_INTERP,
+    ARGMOD(PMC *main),
+    ARGMOD(PMC *argv))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*main)
+        FUNC_MODIFIES(*argv);
+
+PARROT_EXPORT
 void Parrot_cx_broadcast_message(PARROT_INTERP,
     ARGIN(STRING *messagetype),
     ARGIN_NULLOK(PMC *data))
@@ -91,11 +101,6 @@
         FUNC_MODIFIES(*scheduler);
 
 PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-PMC * Parrot_cx_peek_task(PARROT_INTERP)
-        __attribute__nonnull__(1);
-
-PARROT_EXPORT
 void Parrot_cx_request_suspend_for_gc(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -109,14 +114,6 @@
         __attribute__nonnull__(2);
 
 PARROT_EXPORT
-void Parrot_cx_schedule_callback(PARROT_INTERP,
-    ARGIN(PMC *user_data),
-    ARGIN(char *ext_data))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
-PARROT_EXPORT
 void Parrot_cx_schedule_immediate(PARROT_INTERP, ARGIN(PMC *task))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -154,16 +151,12 @@
 void Parrot_cx_init_scheduler(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-void Parrot_cx_invoke_callback(PARROT_INTERP, ARGIN(PMC *callback))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-void Parrot_cx_runloop_wake(PARROT_INTERP, ARGMOD(PMC *scheduler))
+void Parrot_cx_reschedule(PARROT_INTERP, ARGMOD(PMC *scheduler))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*scheduler);
 
-void Parrot_cx_schedule_next_task(PARROT_INTERP, ARGMOD(PMC *scheduler))
+void Parrot_cx_runloop_wake(PARROT_INTERP, ARGMOD(PMC *scheduler))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*scheduler);
@@ -174,6 +167,10 @@
 #define ASSERT_ARGS_Parrot_cx_add_handler_local __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(handler))
+#define ASSERT_ARGS_Parrot_cx_begin_execution __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(main) \
+    , PARROT_ASSERT_ARG(argv))
 #define ASSERT_ARGS_Parrot_cx_broadcast_message __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(messagetype))
@@ -209,8 +206,6 @@
 #define ASSERT_ARGS_Parrot_cx_handle_tasks __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler))
-#define ASSERT_ARGS_Parrot_cx_peek_task __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_cx_request_suspend_for_gc \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
@@ -219,10 +214,6 @@
 #define ASSERT_ARGS_Parrot_cx_schedule_alarm __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(alarm))
-#define ASSERT_ARGS_Parrot_cx_schedule_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(user_data) \
-    , PARROT_ASSERT_ARG(ext_data))
 #define ASSERT_ARGS_Parrot_cx_schedule_immediate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(task))
@@ -242,13 +233,10 @@
     , PARROT_ASSERT_ARG(scheduler))
 #define ASSERT_ARGS_Parrot_cx_init_scheduler __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_cx_invoke_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(callback))
-#define ASSERT_ARGS_Parrot_cx_runloop_wake __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_Parrot_cx_reschedule __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler))
-#define ASSERT_ARGS_Parrot_cx_schedule_next_task __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+#define ASSERT_ARGS_Parrot_cx_runloop_wake __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */

Modified: branches/gsoc_threads/src/alarm.c
==============================================================================
--- branches/gsoc_threads/src/alarm.c	Mon Jul  5 14:33:31 2010	(r48009)
+++ branches/gsoc_threads/src/alarm.c	Mon Jul  5 15:36:03 2010	(r48010)
@@ -14,8 +14,9 @@
 #include "parrot/alarm.h"
 
 /* Some per-process state */
-static Parrot_alarm_queue* alarm_queue;
-static volatile UINTVAL    alarm_serial;
+static Parrot_alarm_queue* alarm_queue  = NULL;
+static volatile UINTVAL    alarm_serial = 0;
+static volatile UINTVAL    alarm_init   = 0;
 
 /* This file relies on POSIX. Probably need two other versions of it:
  *  one for Windows and one for platforms with no signals or threads. */
@@ -65,8 +66,7 @@
         exit(EXIT_FAILURE);
     }
 
-    alarm_serial = 1;
-    alarm_queue  = NULL;
+    alarm_init = 1;
 }
 
 /*
@@ -88,6 +88,9 @@
     struct itimerval itmr;
     int sec, usec;
 
+    if (!alarm_init)
+        Parrot_alarm_init();
+
     sec  = (int) wait;
     usec = (int) ((wait - sec) * MIL);
 
@@ -97,8 +100,13 @@
     itmr.it_interval.tv_usec = 0;
 
     if (setitimer(ITIMER_REAL, &itmr, 0) == -1) {
-        perror("setitimer failed in set_posix_alarm");
-        exit(EXIT_FAILURE);
+        if (errno == EINVAL) {
+            raise(SIGALRM);
+        }
+        else {
+            perror("setitimer failed in set_posix_alarm");
+            exit(EXIT_FAILURE);
+        }
     }
 }
 
@@ -193,6 +201,7 @@
 
     new_alarm = (Parrot_alarm_queue*) malloc(sizeof (Parrot_alarm_queue));
     new_alarm->when = when;
+    new_alarm->next = NULL;
 
     if (alarm_queue == NULL || when < alarm_queue->when) {
         new_alarm->next = alarm_queue;

Modified: branches/gsoc_threads/src/embed.c
==============================================================================
--- branches/gsoc_threads/src/embed.c	Mon Jul  5 14:33:31 2010	(r48009)
+++ branches/gsoc_threads/src/embed.c	Mon Jul  5 15:36:03 2010	(r48010)
@@ -808,7 +808,7 @@
     Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), NULL);
     Parrot_pcc_set_constants(interp, interp->ctx, interp->code->const_table->constants);
 
-    Parrot_pcc_invoke_sub_from_c_args(interp, main_sub, "P->", userargv);
+    Parrot_cx_begin_execution(interp, main_sub, userargv);
 }
 
 

Modified: branches/gsoc_threads/src/main.c
==============================================================================
--- branches/gsoc_threads/src/main.c	Mon Jul  5 14:33:31 2010	(r48009)
+++ branches/gsoc_threads/src/main.c	Mon Jul  5 15:36:03 2010	(r48010)
@@ -137,9 +137,6 @@
     /* Now initialize interpreter */
     initialize_interpreter(interp, (void*)&stacktop);
 
-    /* Register signal handler for timers */
-    Parrot_alarm_init();
-
     /* Parse flags */
     sourcefile = parseflags(interp, argc, argv, &pir_argc, &pir_argv, &core, &trace);
 

Modified: branches/gsoc_threads/src/pmc/task.pmc
==============================================================================
--- branches/gsoc_threads/src/pmc/task.pmc	Mon Jul  5 14:33:31 2010	(r48009)
+++ branches/gsoc_threads/src/pmc/task.pmc	Mon Jul  5 15:36:03 2010	(r48010)
@@ -24,7 +24,7 @@
 /* HEADERIZER BEGIN: static */
 /* HEADERIZER END: static */
 
-pmclass Task auto_attrs {
+pmclass Task provides invokable auto_attrs {
     ATTR INTVAL        id;        /* The task ID. */
     ATTR INTVAL        priority;  /* The priority of the task. */
     ATTR FLOATVAL      birthtime; /* The creation time stamp of the task. */
@@ -173,6 +173,36 @@
 
 /*
 
+=item C<opcode_t *invoke(void *next)>
+
+Invokes whatever is in the Task's associated codeblock.
+
+If the Task's data attribute is not null, pass it to the
+codeblock as the first argument.
+
+=cut
+
+*/
+
+    VTABLE opcode_t *invoke(void *next) {
+        Parrot_Task_attributes *const task = PARROT_TASK(SELF);
+
+        if (PMC_IS_NULL(task->codeblock))
+            return (opcode_t*) next;
+
+        if (PMC_IS_NULL(task->data)) {
+            Parrot_pcc_invoke_sub_from_c_args(interp, task->codeblock, "->");
+        }
+        else {
+            Parrot_pcc_invoke_sub_from_c_args(interp, task->codeblock, "P->", task->data);
+        }
+
+        return (opcode_t*) next;
+    }
+
+
+/*
+
 =item C<PMC *clone()>
 
 Create a copy of the task, resetting status, ID, and birthtime.

Modified: branches/gsoc_threads/src/scheduler.c
==============================================================================
--- branches/gsoc_threads/src/scheduler.c	Mon Jul  5 14:33:31 2010	(r48009)
+++ branches/gsoc_threads/src/scheduler.c	Mon Jul  5 15:36:03 2010	(r48010)
@@ -43,18 +43,9 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*scheduler);
 
-static void scheduler_process_wait_list(PARROT_INTERP,
-    ARGMOD(PMC *scheduler))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        FUNC_MODIFIES(*scheduler);
-
 #define ASSERT_ARGS_scheduler_process_messages __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler))
-#define ASSERT_ARGS_scheduler_process_wait_list __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(scheduler))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: static */
 
@@ -103,6 +94,43 @@
 
 /*
 
+=item C<void Parrot_cx_begin_execution(PARROT_INTERP, PMC *main, PMC *argv)>
+
+Construct the main task, add it to the task queue, and then execute tasks
+until the task queue becomes empty.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_cx_begin_execution(PARROT_INTERP, ARGMOD(PMC *main), ARGMOD(PMC *argv))
+{
+    ASSERT_ARGS(Parrot_cx_begin_execution)
+    PMC *scheduler = interp->scheduler;
+    Parrot_Scheduler_attributes *sched = PARROT_SCHEDULER(scheduler);
+    INTVAL task_count = 1;
+
+    PMC* main_task = Parrot_pmc_new(interp, enum_class_Task);
+    Parrot_Task_attributes *tdata = PARROT_TASK(main_task);
+    tdata->codeblock = main;
+    tdata->data      = argv;
+
+    Parrot_cx_schedule_task(interp, main_task);
+
+    do {
+        Parrot_cx_reschedule(interp, scheduler);
+        task_count = VTABLE_get_integer(interp, sched->task_queue);
+    } while (task_count > 0);
+}
+
+
+/* Parrot_pcc_invoke_sub_from_c_args(interp, main_sub, "P->", userargv); */
+
+
+/*
+
 =item C<void Parrot_cx_check_tasks(PARROT_INTERP, PMC *scheduler)>
 
 If a wake request has been received or an OS timer has expired
@@ -147,7 +175,7 @@
 
     if (SCHEDULER_resched_requested_TEST(scheduler)) {
         SCHEDULER_resched_requested_CLEAR(scheduler);
-        Parrot_cx_schedule_next_task(interp, scheduler);
+        Parrot_cx_reschedule(interp, scheduler);
     }
 
 #ifdef PARROT_CX_BUILD_OLD_STUFF
@@ -213,7 +241,7 @@
 
 
 /*
-=item C<void Parrot_cx_schedule_next_task(PARROT_INTERP, PMC *scheduler)>
+=item C<void Parrot_cx_reschedule(PARROT_INTERP, PMC *scheduler)>
 
 Put the current task on the foot of the task queue and schedule whatever
 is on the head, then reset the rescheduling quantum.
@@ -225,20 +253,25 @@
 */
 
 void
-Parrot_cx_schedule_next_task(PARROT_INTERP, ARGMOD(PMC *scheduler))
+Parrot_cx_reschedule(PARROT_INTERP, ARGMOD(PMC *scheduler))
 {
-    ASSERT_ARGS(Parrot_cx_schedule_next_task)
+    ASSERT_ARGS(Parrot_cx_reschedule)
     Parrot_Scheduler_attributes *sched = PARROT_SCHEDULER(scheduler);
     INTVAL task_count = VTABLE_get_integer(interp, sched->task_queue);
 
     if (task_count > 0) {
-        PMC *sub = VTABLE_shift_pmc(interp, sched->task_queue);
-
         FLOATVAL time_now = Parrot_floatval_time();
+        PMC *task0 = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
+        PMC *task1 = VTABLE_shift_pmc(interp, sched->task_queue);
+
+        if (!PMC_IS_NULL(task0))
+            VTABLE_push_pmc(interp, sched->task_queue, task0);
+
         interp->quantum_done = time_now + PARROT_TASK_SWITCH_QUANTUM;
         Parrot_alarm_set(interp->quantum_done);
 
-        Parrot_pcc_invoke_sub_from_c_args(interp, sub, "->");
+        if (!PMC_IS_NULL(task1))
+            Parrot_pcc_invoke_sub_from_c_args(interp, task1, "->");
     }
 }
 
@@ -332,60 +365,6 @@
 
 /*
 
-=item C<PMC * Parrot_cx_peek_task(PARROT_INTERP)>
-
-Retrieve the the top task on the scheduler's task list, but don't remove it
-from the list.
-
-=cut
-
-*/
-
-#ifdef COMPILE_OLD_STUFF
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-PMC *
-Parrot_cx_peek_task(PARROT_INTERP)
-{
-    ASSERT_ARGS(Parrot_cx_peek_task)
-    if (!interp->scheduler)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Scheduler was not initialized for this interpreter.\n");
-
-
-
-    return VTABLE_pop_pmc(interp, interp->scheduler);
-}
-
-/*
-
-=item C<void Parrot_cx_schedule_callback(PARROT_INTERP, PMC *user_data, char
-*ext_data)>
-
-Create a new callback event, with an argument for the call.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_cx_schedule_callback(PARROT_INTERP, ARGIN(PMC *user_data), ARGIN(char *ext_data))
-{
-    ASSERT_ARGS(Parrot_cx_schedule_callback)
-    PMC * const callback = Parrot_pmc_new(interp, enum_class_Task);
-    Parrot_Task_attributes * const task_struct = PARROT_TASK(callback);
-
-    task_struct->type    = CONST_STRING(interp, "callback");
-    task_struct->data    = user_data;
-    task_struct->cb_data = ext_data;
-
-    Parrot_cx_schedule_task(interp, callback);
-}
-#endif
-
-/*
-
 =item C<void Parrot_cx_request_suspend_for_gc(PARROT_INTERP)>
 
 Tell the scheduler to suspend for GC at the next safe pause.
@@ -985,27 +964,6 @@
 
 /*
 
-=item C<void Parrot_cx_invoke_callback(PARROT_INTERP, PMC *callback)>
-
-Run the associated code block for a callback event.
-
-=cut
-
-*/
-
-void
-Parrot_cx_invoke_callback(PARROT_INTERP, ARGIN(PMC *callback))
-{
-    ASSERT_ARGS(Parrot_cx_invoke_callback)
-    Parrot_Task_attributes * const task_struct = PARROT_TASK(callback);
-    if (!PMC_IS_NULL(task_struct->data)) {
-        Parrot_run_callback(interp, task_struct->data,
-                task_struct->cb_data);
-    }
-}
-
-/*
-
 =back
 
 =head2 Opcode Functions
@@ -1066,60 +1024,6 @@
     return next;
 }
 
-/*
-
-=back
-
-=head2 Internal Functions
-
-Functions that are only used within the scheduler.
-
-=over 4
-
-=item C<static void scheduler_process_wait_list(PARROT_INTERP, PMC *scheduler)>
-
-Scheduler maintenance, scan the list of waiting tasks to see if any are ready
-to become active tasks.
-
-=cut
-
-*/
-
-static void
-scheduler_process_wait_list(PARROT_INTERP, ARGMOD(PMC *scheduler))
-{
-    ASSERT_ARGS(scheduler_process_wait_list)
-
-#ifdef BUILD_OLD_CODE
-    Parrot_Scheduler_attributes * sched_struct = PARROT_SCHEDULER(scheduler);
-    INTVAL num_tasks, index;
-
-    /* Sweep the wait list for completed timers */
-    num_tasks = VTABLE_elements(interp, sched_struct->wait_index);
-    for (index = 0; index < num_tasks; ++index) {
-        INTVAL tid = VTABLE_get_integer_keyed_int(interp, sched_struct->wait_index, index);
-        if (tid > 0) {
-            PMC *task = VTABLE_get_pmc_keyed_int(interp, sched_struct->task_list, tid);
-            if (PMC_IS_NULL(task)) {
-                /* Cleanup expired tasks. */
-                VTABLE_set_integer_keyed_int(interp, sched_struct->wait_index, index, 0);
-            }
-            else {
-                /* Move the timer to the active task list if the timer has
-                 * completed. */
-                FLOATVAL timer_end_time = VTABLE_get_number_keyed_int(interp,
-                        task, PARROT_TIMER_NSEC);
-                if (timer_end_time <= Parrot_floatval_time()) {
-                    VTABLE_push_integer(interp, sched_struct->task_index, tid);
-                    VTABLE_set_integer_keyed_int(interp, sched_struct->wait_index, index, 0);
-                    Parrot_cx_schedule_repeat(interp, task);
-                    SCHEDULER_cache_valid_CLEAR(scheduler);
-                }
-            }
-        }
-    }
-#endif
-}
 
 /*
 


More information about the parrot-commits mailing list