[svn:parrot] r48117 - in branches/gsoc_threads: include/parrot include/parrot/oplib src src/ops src/pmc t/pmc

Chandon at svn.parrot.org Chandon at svn.parrot.org
Tue Jul 20 01:19:43 UTC 2010


Author: Chandon
Date: Tue Jul 20 01:19:43 2010
New Revision: 48117
URL: https://trac.parrot.org/parrot/changeset/48117

Log:
[gsoc_threads] First half of the Task API.

Modified:
   branches/gsoc_threads/include/parrot/oplib/core_ops.h
   branches/gsoc_threads/include/parrot/oplib/ops.h
   branches/gsoc_threads/include/parrot/opsenum.h
   branches/gsoc_threads/include/parrot/scheduler.h
   branches/gsoc_threads/include/parrot/scheduler_private.h
   branches/gsoc_threads/src/events.c
   branches/gsoc_threads/src/ops/core.ops
   branches/gsoc_threads/src/ops/core_ops.c
   branches/gsoc_threads/src/ops/experimental.ops
   branches/gsoc_threads/src/pmc/event.pmc
   branches/gsoc_threads/src/pmc/task.pmc
   branches/gsoc_threads/src/scheduler.c
   branches/gsoc_threads/t/pmc/task.t

Modified: branches/gsoc_threads/include/parrot/oplib/core_ops.h
==============================================================================
--- branches/gsoc_threads/include/parrot/oplib/core_ops.h	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/include/parrot/oplib/core_ops.h	Tue Jul 20 01:19:43 2010	(r48117)
@@ -1105,6 +1105,9 @@
  opcode_t * Parrot_find_codepoint_i_sc(opcode_t *, PARROT_INTERP);
  opcode_t * Parrot_finalize_p(opcode_t *, PARROT_INTERP);
  opcode_t * Parrot_finalize_pc(opcode_t *, PARROT_INTERP);
+ opcode_t * Parrot_recv_p(opcode_t *, PARROT_INTERP);
+ opcode_t * Parrot_wait_p(opcode_t *, PARROT_INTERP);
+ opcode_t * Parrot_wait_pc(opcode_t *, PARROT_INTERP);
 
 
 #endif /* PARROT_OPLIB_CORE_OPS_H_GUARD */

Modified: branches/gsoc_threads/include/parrot/oplib/ops.h
==============================================================================
--- branches/gsoc_threads/include/parrot/oplib/ops.h	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/include/parrot/oplib/ops.h	Tue Jul 20 01:19:43 2010	(r48117)
@@ -1099,7 +1099,10 @@
     PARROT_OP_find_codepoint_i_s,              /* 1079 */
     PARROT_OP_find_codepoint_i_sc,             /* 1080 */
     PARROT_OP_finalize_p,                      /* 1081 */
-    PARROT_OP_finalize_pc                      /* 1082 */
+    PARROT_OP_finalize_pc,                     /* 1082 */
+    PARROT_OP_recv_p,                          /* 1083 */
+    PARROT_OP_wait_p,                          /* 1084 */
+    PARROT_OP_wait_pc                          /* 1085 */
 
 } parrot_opcode_enums;
 

Modified: branches/gsoc_threads/include/parrot/opsenum.h
==============================================================================
--- branches/gsoc_threads/include/parrot/opsenum.h	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/include/parrot/opsenum.h	Tue Jul 20 01:19:43 2010	(r48117)
@@ -1099,6 +1099,9 @@
     enum_ops_find_codepoint_i_sc           = 1080,
     enum_ops_finalize_p                    = 1081,
     enum_ops_finalize_pc                   = 1082,
+    enum_ops_recv_p                        = 1083,
+    enum_ops_wait_p                        = 1084,
+    enum_ops_wait_pc                       = 1085,
 };
 
 

Modified: branches/gsoc_threads/include/parrot/scheduler.h
==============================================================================
--- branches/gsoc_threads/include/parrot/scheduler.h	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/include/parrot/scheduler.h	Tue Jul 20 01:19:43 2010	(r48117)
@@ -128,6 +128,11 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*scheduler);
 
+PARROT_CANNOT_RETURN_NULL
+PMC* Parrot_cx_stop_task(PARROT_INTERP, ARGIN(opcode_t *next))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 #define ASSERT_ARGS_Parrot_cx_begin_execution __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(main) \
@@ -182,9 +187,13 @@
 #define ASSERT_ARGS_Parrot_cx_runloop_wake __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler))
+#define ASSERT_ARGS_Parrot_cx_stop_task __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(next))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/scheduler.c */
 
+
 /* Timer PMC interface constants */
 /* &gen_from_enum(timer.pasm) */
 typedef enum {

Modified: branches/gsoc_threads/include/parrot/scheduler_private.h
==============================================================================
--- branches/gsoc_threads/include/parrot/scheduler_private.h	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/include/parrot/scheduler_private.h	Tue Jul 20 01:19:43 2010	(r48117)
@@ -46,9 +46,13 @@
 
 /*
  * Task private flags
+ *
+ * in_preempt - This flag is set if the runloop is ending because the current
+ *              task has been pre-empted. When the runloop ends because a task
+ *              is done, this flag is not set.
  */
 typedef enum {
-    TASK_terminate_runloop_FLAG = PObj_private0_FLAG
+    TASK_in_preempt_FLAG = PObj_private0_FLAG
 } task_flags_enum;
 
 #define TASK_get_FLAGS(o) (PObj_get_FLAGS(o))
@@ -57,9 +61,9 @@
 #define TASK_flag_CLEAR(flag, o) (TASK_get_FLAGS(o) &= ~(UINTVAL)(TASK_ ## flag ## _FLAG))
 
 /* Mark a task to terminate the scheduler runloop */
-#define TASK_terminate_runloop_TEST(o)  TASK_flag_TEST(terminate_runloop, o)
-#define TASK_terminate_runloop_SET(o)   TASK_flag_SET(terminate_runloop, o)
-#define TASK_terminate_runloop_CLEAR(o) TASK_flag_CLEAR(terminate_runloop, o)
+#define TASK_in_preempt_TEST(o)  TASK_flag_TEST(in_preempt, o)
+#define TASK_in_preempt_SET(o)   TASK_flag_SET(in_preempt, o)
+#define TASK_in_preempt_CLEAR(o) TASK_flag_CLEAR(in_preempt, o)
 
 #endif /* PARROT_SCHEDULER_PRIVATE_H_GUARD */
 

Modified: branches/gsoc_threads/src/events.c
==============================================================================
--- branches/gsoc_threads/src/events.c	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/events.c	Tue Jul 20 01:19:43 2010	(r48117)
@@ -58,8 +58,8 @@
 
         /* If the scheduler was flagged to terminate, make sure you process all
          * tasks. */
-        if (SCHEDULER_terminate_requested_TEST(scheduler))
-            Parrot_cx_refresh_task_list(interp, scheduler);
+        /* if (SCHEDULER_terminate_requested_TEST(scheduler))
+           Parrot_cx_refresh_task_list(interp, scheduler); */
 
     } /* end of pending tasks */
 #endif

Modified: branches/gsoc_threads/src/ops/core.ops
==============================================================================
--- branches/gsoc_threads/src/ops/core.ops	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/ops/core.ops	Tue Jul 20 01:19:43 2010	(r48117)
@@ -8,9 +8,11 @@
 #include "parrot/dynext.h"
 #include "parrot/embed.h"
 #include "parrot/runcore_api.h"
+#include "parrot/events.h"
 #include "pmc/pmc_continuation.h"
 #include "pmc/pmc_parrotlibrary.h"
 
+
 END_OPS_PREAMBLE
 
 =head1 NAME

Modified: branches/gsoc_threads/src/ops/core_ops.c
==============================================================================
--- branches/gsoc_threads/src/ops/core_ops.c	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/ops/core_ops.c	Tue Jul 20 01:19:43 2010	(r48117)
@@ -33,10 +33,12 @@
 #include "parrot/dynext.h"
 #include "parrot/embed.h"
 #include "parrot/runcore_api.h"
+#include "parrot/events.h"
 #include "pmc/pmc_continuation.h"
 #include "pmc/pmc_parrotlibrary.h"
 
 
+
  /* Signed shift operator that is compatible with PMC shifts.  This is
   * guaranteed to produce the same result as bitwise_left_shift_internal modulo
   * word size, ignoring the fact that Parrot integers are always signed.  This
@@ -60,15 +62,17 @@
 #  include <unicode/uchar.h>
 #endif
 
+#include "pmc/pmc_task.h"
+
 
 
-INTVAL core_numops = 1084;
+INTVAL core_numops = 1087;
 
 /*
 ** Op Function Table:
 */
 
-static op_func_t core_op_func_table[1084] = {
+static op_func_t core_op_func_table[1087] = {
   Parrot_end,                                        /*      0 */
   Parrot_noop,                                       /*      1 */
   Parrot_check_events,                               /*      2 */
@@ -1152,6 +1156,9 @@
   Parrot_find_codepoint_i_sc,                        /*   1080 */
   Parrot_finalize_p,                                 /*   1081 */
   Parrot_finalize_pc,                                /*   1082 */
+  Parrot_recv_p,                                     /*   1083 */
+  Parrot_wait_p,                                     /*   1084 */
+  Parrot_wait_pc,                                    /*   1085 */
 
   NULL /* NULL function pointer */
 };
@@ -1162,7 +1169,7 @@
 ** Op Info Table:
 */
 
-static op_info_t core_op_info_table[1084] = {
+static op_info_t core_op_info_table[1087] = {
   { /* 0 */
     /* type PARROT_INLINE_OP, */
     "end",
@@ -14159,6 +14166,42 @@
     { PARROT_ARGDIR_IN },
     { 0 }
   },
+  { /* 1083 */
+    /* type PARROT_FUNCTION_OP, */
+    "recv",
+    "recv_p",
+    "Parrot_recv_p",
+    /* "",  body */
+    0,
+    2,
+    { PARROT_ARG_P },
+    { PARROT_ARGDIR_OUT },
+    { 0 }
+  },
+  { /* 1084 */
+    /* type PARROT_FUNCTION_OP, */
+    "wait",
+    "wait_p",
+    "Parrot_wait_p",
+    /* "",  body */
+    0,
+    2,
+    { PARROT_ARG_P },
+    { PARROT_ARGDIR_IN },
+    { 0 }
+  },
+  { /* 1085 */
+    /* type PARROT_FUNCTION_OP, */
+    "wait",
+    "wait_pc",
+    "Parrot_wait_pc",
+    /* "",  body */
+    0,
+    2,
+    { PARROT_ARG_PC },
+    { PARROT_ARGDIR_IN },
+    { 0 }
+  },
 
 };
 
@@ -25009,6 +25052,50 @@
 
 return (opcode_t *)cur_opcode + 2;}
 
+opcode_t *
+Parrot_recv_p(opcode_t *cur_opcode, PARROT_INTERP)  {
+    const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
+    opcode_t *const dest = cur_opcode + 2;
+    PREG(1) = PMCNULL;
+
+return (opcode_t *)cur_opcode + 2;}
+
+opcode_t *
+Parrot_wait_p(opcode_t *cur_opcode, PARROT_INTERP)  {
+    const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
+    opcode_t *const next = cur_opcode + 2;
+    PMC *task = PREG(1);
+    PMC *cur_task;
+    Parrot_Task_attributes *tdata;
+
+    if (!VTABLE_isa(interp, task, Parrot_str_new_constant(interp, "Task")))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Argument to wait op must be a Task.\n");
+
+    cur_task = Parrot_cx_stop_task(interp, next);
+    tdata    = PARROT_TASK(task);
+    VTABLE_push_pmc(interp, tdata->waiters, cur_task);return (opcode_t *)0;
+
+return (opcode_t *)cur_opcode + 2;}
+
+opcode_t *
+Parrot_wait_pc(opcode_t *cur_opcode, PARROT_INTERP)  {
+    const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
+    opcode_t *const next = cur_opcode + 2;
+    PMC *task = CONST(1)->u.key;
+    PMC *cur_task;
+    Parrot_Task_attributes *tdata;
+
+    if (!VTABLE_isa(interp, task, Parrot_str_new_constant(interp, "Task")))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Argument to wait op must be a Task.\n");
+
+    cur_task = Parrot_cx_stop_task(interp, next);
+    tdata    = PARROT_TASK(task);
+    VTABLE_push_pmc(interp, tdata->waiters, cur_task);return (opcode_t *)0;
+
+return (opcode_t *)cur_opcode + 2;}
+
 
 /*
 ** op lib descriptor:
@@ -25022,7 +25109,7 @@
   2,    /* major_version */
   5,    /* minor_version */
   0,    /* patch_version */
-  1083,             /* op_count */
+  1086,             /* op_count */
   core_op_info_table,       /* op_info_table */
   core_op_func_table,       /* op_func_table */
   get_op          /* op_code() */ 

Modified: branches/gsoc_threads/src/ops/experimental.ops
==============================================================================
--- branches/gsoc_threads/src/ops/experimental.ops	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/ops/experimental.ops	Tue Jul 20 01:19:43 2010	(r48117)
@@ -9,6 +9,8 @@
 #  include <unicode/uchar.h>
 #endif
 
+#include "pmc/pmc_task.h"
+
 END_OPS_PREAMBLE
 
 =head1 NAME
@@ -414,6 +416,39 @@
     }
 }
 
+=item B<recv>(out PMC)
+
+Recieve a message sent to the current task.
+
+=cut
+
+op recv(out PMC) {
+    opcode_t *const dest = expr NEXT();
+    $1 = PMCNULL;
+}
+
+=item B<wait>(in PMC)
+
+Block and wait for a task to complete.
+
+=cut
+
+op wait(in PMC) {
+    opcode_t *const next = expr NEXT();
+    PMC *task = $1;
+    PMC *cur_task;
+    Parrot_Task_attributes *tdata;
+
+    if (!VTABLE_isa(interp, task, Parrot_str_new_constant(interp, "Task")))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Argument to wait op must be a Task.\n");
+
+    cur_task = Parrot_cx_stop_task(interp, next);
+    tdata    = PARROT_TASK(task);
+    VTABLE_push_pmc(interp, tdata->waiters, cur_task);
+
+    goto ADDRESS(0);
+}
 
 =back
 

Modified: branches/gsoc_threads/src/pmc/event.pmc
==============================================================================
--- branches/gsoc_threads/src/pmc/event.pmc	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/pmc/event.pmc	Tue Jul 20 01:19:43 2010	(r48117)
@@ -64,7 +64,7 @@
         core_struct->interp      = INTERP;
 
         /* Make sure the flag is cleared by default */
-        TASK_terminate_runloop_CLEAR(SELF);
+        /* TASK_terminate_runloop_CLEAR(SELF); */
 
     }
 

Modified: branches/gsoc_threads/src/pmc/task.pmc
==============================================================================
--- branches/gsoc_threads/src/pmc/task.pmc	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/pmc/task.pmc	Tue Jul 20 01:19:43 2010	(r48117)
@@ -30,6 +30,8 @@
     ATTR PMC          *code;      /* An (optional) code for the task. */
     ATTR PMC          *data;      /* Additional data for the task. */
     ATTR INTVAL        killed;    /* Dead tasks don't get run. */
+    ATTR PMC          *mailbox;   /* List of incoming messages. */
+    ATTR PMC          *waiters;   /* Tasks waiting on this one. */
 
 /*
 
@@ -53,6 +55,11 @@
         core_struct->data      = PMCNULL;
         core_struct->interp    = INTERP;
         core_struct->killed    = 0;
+        core_struct->mailbox   = Parrot_pmc_new(interp, enum_class_PMCList);
+        core_struct->waiters   = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
+
+        /* By default, a task is not being pre-empted */
+        TASK_in_preempt_CLEAR(SELF);
     }
 
 /*
@@ -75,10 +82,6 @@
 
 Some data that will be passed to C<code> when invoked.
 
-=item C<interp>
-
-An interpreter in which to execute this task.
-
 =back
 
 =cut
@@ -106,10 +109,6 @@
             elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "data"));
             if (! PMC_IS_NULL(elem))
                 core_struct->data = elem;
-
-            elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "interp"));
-            if (! PMC_IS_NULL(elem))
-                core_struct->interp = elem;
         }
         else {
             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
@@ -133,17 +132,27 @@
     VTABLE opcode_t *invoke(void *next) {
         Parrot_Task_attributes *const task = PARROT_TASK(SELF);
 
-        if (task->killed)
-            return (opcode_t*) 0;
+        /* If a task is pre-empted, this will be set again. */
+        TASK_in_preempt_CLEAR(SELF);
 
-        if (PMC_IS_NULL(task->code))
-            return (opcode_t*) next;
-
-        if (PMC_IS_NULL(task->data)) {
-            Parrot_pcc_invoke_sub_from_c_args(interp, task->code, "->");
-        }
-        else {
-            Parrot_pcc_invoke_sub_from_c_args(interp, task->code, "P->", task->data);
+        if (!(task->killed || PMC_IS_NULL(task->code))) {
+            if (PMC_IS_NULL(task->data)) {
+                Parrot_pcc_invoke_sub_from_c_args(interp, task->code, "->");
+            }
+            else {
+                Parrot_pcc_invoke_sub_from_c_args(interp, task->code, "P->", task->data);
+            }
+        }
+
+        if (!TASK_in_preempt_TEST(SELF)) {
+            /* The task is done, schedule any waiters. */
+            int i;
+            int n = VTABLE_get_integer(interp, task->waiters);
+
+            for (i = 0; i < n; ++i) {
+                PMC *wtask = VTABLE_get_pmc_keyed_int(interp, task->waiters, i);
+                Parrot_cx_schedule_task(interp, wtask);
+            }
         }
 
         return (opcode_t*) next;
@@ -272,6 +281,8 @@
 
             Parrot_gc_mark_PMC_alive(INTERP, core_struct->code);
             Parrot_gc_mark_PMC_alive(INTERP, core_struct->data);
+            Parrot_gc_mark_PMC_alive(INTERP, core_struct->mailbox);
+            Parrot_gc_mark_PMC_alive(INTERP, core_struct->waiters);
         }
     }
 
@@ -291,6 +302,8 @@
         /* 1) visit code block */
         VISIT_PMC_ATTR(INTERP, info, SELF, Task, code);
         VISIT_PMC_ATTR(INTERP, info, SELF, Task, data);
+        VISIT_PMC_ATTR(INTERP, info, SELF, Task, mailbox);
+        VISIT_PMC_ATTR(INTERP, info, SELF, Task, waiters);
     }
 
 /*
@@ -362,21 +375,8 @@
 */
 
     METHOD send(PMC *message) {
-        fprintf(stderr, "Task#send not implemented.\n");
-    }
-
-/*
-
-=item METHOD wait()
-
-Block until this task ends.
-
-=cut
-
-*/
-
-    METHOD wait() {
-        fprintf(stderr, "Task#wait not implemented.\n");
+        Parrot_Task_attributes *tdata = PARROT_TASK(SELF);
+        VTABLE_push_pmc(interp, tdata->mailbox, message);
     }
 
 /*
@@ -390,7 +390,8 @@
 */
 
     METHOD kill() {
-        fprintf(stderr, "Task#kill not implemented.\n");
+        Parrot_Task_attributes *tdata = PARROT_TASK(SELF);
+        tdata->killed = 1;
     }
 }
 

Modified: branches/gsoc_threads/src/scheduler.c
==============================================================================
--- branches/gsoc_threads/src/scheduler.c	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/src/scheduler.c	Tue Jul 20 01:19:43 2010	(r48117)
@@ -255,21 +255,18 @@
 }
 
 /*
-=item C<opcode_t* Parrot_cx_preempt_task(PARROT_INTERP, PMC *scheduler, opcode_t
-*next)>
+=item C<PMC* Parrot_cx_stop_task(PARROT_INTERP, opcode_t *next)>
 
-Pre-empt the current task. It goes on the foot of the task queue,
-and then we jump all the way back to the task scheduling loop.
+Stop the current task and pack it up into a PMC what can be used to resume later.
 
 =cut
 */
 
 PARROT_CANNOT_RETURN_NULL
-opcode_t*
-Parrot_cx_preempt_task(PARROT_INTERP, ARGMOD(PMC *scheduler), ARGIN(opcode_t *next))
+PMC*
+Parrot_cx_stop_task(PARROT_INTERP, ARGIN(opcode_t *next))
 {
-    ASSERT_ARGS(Parrot_cx_preempt_task)
-    Parrot_Scheduler_attributes *sched = PARROT_SCHEDULER(scheduler);
+    ASSERT_ARGS(Parrot_cx_stop_task)
 
     PMC *task = interp->current_task;
     Parrot_Task_attributes *tdata = PARROT_TASK(task);
@@ -279,10 +276,32 @@
 
     if (PMC_IS_NULL(task) || !VTABLE_isa(interp, interp->current_task, CONST_STRING(interp, "Task")))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Attempt to pre-empt invalid interp->current_task.\n");
+            "Attempt to stop invalid interp->current_task.\n");
 
     tdata->code = cont;
+    TASK_in_preempt_SET(task);
+
+    return task;
+}
+
+/*
+=item C<opcode_t* Parrot_cx_preempt_task(PARROT_INTERP, PMC *scheduler, opcode_t
+*next)>
+
+Pre-empt the current task. It goes on the foot of the task queue,
+and then we jump all the way back to the task scheduling loop.
+
+=cut
+*/
+
+PARROT_CANNOT_RETURN_NULL
+opcode_t*
+Parrot_cx_preempt_task(PARROT_INTERP, ARGMOD(PMC *scheduler), ARGIN(opcode_t *next))
+{
+    ASSERT_ARGS(Parrot_cx_preempt_task)
+    Parrot_Scheduler_attributes *sched = PARROT_SCHEDULER(scheduler);
 
+    PMC* task = Parrot_cx_stop_task(interp, next);
     VTABLE_push_pmc(interp, sched->task_queue, task);
 
     interp->current_task = PMCNULL;

Modified: branches/gsoc_threads/t/pmc/task.t
==============================================================================
--- branches/gsoc_threads/t/pmc/task.t	Mon Jul 19 21:54:44 2010	(r48116)
+++ branches/gsoc_threads/t/pmc/task.t	Tue Jul 20 01:19:43 2010	(r48117)
@@ -1,19 +1,116 @@
-#! parrot
+#!./parrot
 # Copyright (C) 2010, Parrot Foundation.
 # $Id$
 
 .sub main
     .include 'test_more.pir'
 
-    plan(1)
+    plan(9)
 
-    ok1()
+    tasks_run_in_order()
+    task_send_recv()
+    task_kill()
+    task_wait()
+
+    $P0 = get_global 'exit0'
+    $P1 = new 'Task', $P0
+    schedule $P1
 
-    $P0 = new 'Task'
+again:
+    goto again
 .end
 
-.sub ok1
-    say "ok 1"
+.sub tasks_run_in_order
+    $P0 = new 'Integer', 0
+    set_global 'N', $P0
+
+    $P0 = get_global 'task1'
+    $P1 = new 'Task', $P0
+    schedule $P1
+
+    $P0 = get_global 'sub1'
+    schedule $P0
+
+    $P0 = get_global 'task2'
+    $P1 = new 'Task', $P0
+    schedule $P1
+
+    sleep 0.01
+.end
+
+.sub task1
+    $P0 = get_global 'N'
+    is($P0, 0, "Task ran in order (0)")
+
+    $P0 = 1
+    set_global 'N', $P0
+.end
+
+.sub sub1
+    $P0 = get_global 'N'
+    is($P0, 1, "Implicit task ran in order (2)")
+
+    $P0 = 2
+    set_global 'N', $P0
+.end
+
+.sub task2
+    $P0 = get_global 'N'
+    is($P0, 2, "Task ran in order (3)")
+
+    $P0 = 3
+    set_global 'N', $P0
+.end
+
+.sub task_send_recv
+    $P0 = get_global 'recv_msg'
+    $P1 = new 'Task', $P0
+    $P2 = new 'String'
+    $P2 = "Hai"
+    $P1.'send'($P2)
+    schedule $P1
+.end
+
+.sub task_kill
+    $P0 = get_global 'task_to_kill'
+    $P1 = new 'Task', $P0
+    schedule $P1
+    sleep 0.001
+    $P1.'kill'()
+    sleep 0.1
+    ok(1, "task_to_kill killed")
+.end
+
+.sub task_to_kill
+    ok(1, "task_to_kill running")
+    sleep 0.05
+    ok(0, "task_to_kill wasn't killed")
+.end
+
+.sub recv_msg
+    $P0 = recv
+    $P1 = new 'String'
+    $P1 = "Hai"
+#is($P0, $P1, "Got message")
+    skip("Chandon TODO: Message Passing")
+.end
+
+.sub task_wait
+    $P0 = get_global 'wait_sub1'
+    $P1 = new 'Task', $P0
+    schedule $P1
+
+    wait $P1
+    ok(1, "After wait")
+.end
+
+.sub wait_sub1
+    ok(1, "in wait_sub1")
+.end
+
+.sub exit0
+    ok(1, "Pre-empt and exit")
+    exit 0
 .end
 
 # Local Variables:


More information about the parrot-commits mailing list