[svn:parrot] r48093 - in branches/gsoc_threads: config/gen/makefiles include/parrot src src/pmc t/native_pbc t/pmc

Chandon at svn.parrot.org Chandon at svn.parrot.org
Thu Jul 15 04:48:05 UTC 2010


Author: Chandon
Date: Thu Jul 15 04:48:04 2010
New Revision: 48093
URL: https://trac.parrot.org/parrot/changeset/48093

Log:
[gsoc_threads] Clean up task vs. event; make timers not be tasks.

Added:
   branches/gsoc_threads/include/parrot/events.h   (contents, props changed)
   branches/gsoc_threads/src/events.c   (contents, props changed)
   branches/gsoc_threads/src/pmc/event.pmc
   branches/gsoc_threads/t/pmc/event.t
      - copied, changed from r48070, branches/gsoc_threads/t/pmc/task.t
Deleted:
   branches/gsoc_threads/t/pmc/task.t
Modified:
   branches/gsoc_threads/config/gen/makefiles/root.in
   branches/gsoc_threads/include/parrot/platform_interface.h
   branches/gsoc_threads/include/parrot/scheduler.h
   branches/gsoc_threads/src/pmc/task.pmc
   branches/gsoc_threads/src/pmc/timer.pmc
   branches/gsoc_threads/src/scheduler.c
   branches/gsoc_threads/t/native_pbc/annotations.pbc
   branches/gsoc_threads/t/native_pbc/integer.pbc
   branches/gsoc_threads/t/native_pbc/number.pbc
   branches/gsoc_threads/t/native_pbc/string.pbc
   branches/gsoc_threads/t/pmc/timer.t

Modified: branches/gsoc_threads/config/gen/makefiles/root.in
==============================================================================
--- branches/gsoc_threads/config/gen/makefiles/root.in	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/config/gen/makefiles/root.in	Thu Jul 15 04:48:04 2010	(r48093)
@@ -446,7 +446,7 @@
     src/exit$(O) \
     src/extend$(O) \
     src/extend_vtable$(O) \
-	src/alarm$(O) \
+    src/alarm$(O) \
     src/gc/alloc_memory$(O) \
     src/gc/api$(O) \
     src/gc/gc_ms$(O) \
@@ -484,6 +484,7 @@
     src/runcore/cores$(O) \
     src/runcore/profiling$(O) \
     src/scheduler$(O) \
+    src/events$(O) \
     src/spf_render$(O) \
     src/spf_vtable$(O) \
     src/string/primitives$(O) \
@@ -688,6 +689,7 @@
     src/runcore/main.str \
     src/runcore/profiling.str \
     src/scheduler.str \
+    src/events.str \
     src/spf_render.str \
     src/spf_vtable.str \
     src/string/api.str \
@@ -917,6 +919,8 @@
 	$(INC_DIR)/scheduler_private.h \
 	$(INC_DIR)/runcore_api.h
 
+src/events$(O) : $(PARROT_H_HEADERS) $(INC_DIR)/runcore_api.h
+
 src/alarm$(O) : $(PARROT_H_HEADERS) src/alarm.c \
 	$(INC_DIR)/alarm.h
 

Added: branches/gsoc_threads/include/parrot/events.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gsoc_threads/include/parrot/events.h	Thu Jul 15 04:48:04 2010	(r48093)
@@ -0,0 +1,97 @@
+/* Copyright (C) 2010, Parrot Foundation.
+ * $Id$ 
+ */
+
+#ifndef PARROT_EVENTS_H_GUARD
+#define PARROT_EVENTS_H_GUARD
+
+/* HEADERIZER BEGIN: src/events.c */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+
+PARROT_EXPORT
+void Parrot_cx_add_handler(PARROT_INTERP, ARGIN(PMC *handler))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_cx_add_handler_local(PARROT_INTERP, ARGIN(PMC *handler))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+INTVAL Parrot_cx_count_handlers_local(PARROT_INTERP,
+    ARGIN(STRING *handler_type))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+INTVAL Parrot_cx_count_handlers_typed(PARROT_INTERP,
+    ARGIN(STRING *handler_type))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_cx_delete_handler_local(PARROT_INTERP,
+    ARGIN(STRING *handler_type))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_cx_delete_handler_typed(PARROT_INTERP,
+    ARGIN(STRING *handler_type))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC * Parrot_cx_find_handler_for_task(PARROT_INTERP, ARGIN(PMC *task))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC * Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
+#define ASSERT_ARGS_Parrot_cx_add_handler __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(handler))
+#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_count_handlers_local \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(handler_type))
+#define ASSERT_ARGS_Parrot_cx_count_handlers_typed \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(handler_type))
+#define ASSERT_ARGS_Parrot_cx_delete_handler_local \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(handler_type))
+#define ASSERT_ARGS_Parrot_cx_delete_handler_typed \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(handler_type))
+#define ASSERT_ARGS_Parrot_cx_find_handler_for_task \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(task))
+#define ASSERT_ARGS_Parrot_cx_find_handler_local __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(task))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
+/* HEADERIZER END: src/events.c */
+
+#endif
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
+

Modified: branches/gsoc_threads/include/parrot/platform_interface.h
==============================================================================
--- branches/gsoc_threads/include/parrot/platform_interface.h	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/include/parrot/platform_interface.h	Thu Jul 15 04:48:04 2010	(r48093)
@@ -55,6 +55,7 @@
 
 void Parrot_sleep(unsigned int seconds);
 void Parrot_usleep(unsigned int microseconds);
+void Parrot_floatval_sleep(FLOATVAL time);
 INTVAL Parrot_intval_time(void);
 FLOATVAL Parrot_floatval_time(void);
 

Modified: branches/gsoc_threads/include/parrot/scheduler.h
==============================================================================
--- branches/gsoc_threads/include/parrot/scheduler.h	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/include/parrot/scheduler.h	Thu Jul 15 04:48:04 2010	(r48093)
@@ -21,16 +21,6 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
 PARROT_EXPORT
-void Parrot_cx_add_handler(PARROT_INTERP, ARGIN(PMC *handler))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
-void Parrot_cx_add_handler_local(PARROT_INTERP, ARGIN(PMC *handler))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
 void Parrot_cx_begin_execution(PARROT_INTERP,
     ARGMOD(PMC *main),
     ARGMOD(PMC *argv))
@@ -54,46 +44,10 @@
         FUNC_MODIFIES(*scheduler);
 
 PARROT_EXPORT
-INTVAL Parrot_cx_count_handlers_local(PARROT_INTERP,
-    ARGIN(STRING *handler_type))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
-INTVAL Parrot_cx_count_handlers_typed(PARROT_INTERP,
-    ARGIN(STRING *handler_type))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
-void Parrot_cx_delete_handler_local(PARROT_INTERP,
-    ARGIN(STRING *handler_type))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
-void Parrot_cx_delete_handler_typed(PARROT_INTERP,
-    ARGIN(STRING *handler_type))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
 PARROT_CAN_RETURN_NULL
 PMC * Parrot_cx_delete_suspend_for_gc(PARROT_INTERP)
         __attribute__nonnull__(1);
 
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-PMC * Parrot_cx_find_handler_for_task(PARROT_INTERP, ARGIN(PMC *task))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-PMC * Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
-
 PARROT_CANNOT_RETURN_NULL
 PARROT_EXPORT
 opcode_t* Parrot_cx_handle_tasks(PARROT_INTERP,
@@ -174,12 +128,6 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*scheduler);
 
-#define ASSERT_ARGS_Parrot_cx_add_handler __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(handler))
-#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) \
@@ -190,32 +138,9 @@
 #define ASSERT_ARGS_Parrot_cx_check_alarms __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler))
-#define ASSERT_ARGS_Parrot_cx_count_handlers_local \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(handler_type))
-#define ASSERT_ARGS_Parrot_cx_count_handlers_typed \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(handler_type))
-#define ASSERT_ARGS_Parrot_cx_delete_handler_local \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(handler_type))
-#define ASSERT_ARGS_Parrot_cx_delete_handler_typed \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(handler_type))
 #define ASSERT_ARGS_Parrot_cx_delete_suspend_for_gc \
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
-#define ASSERT_ARGS_Parrot_cx_find_handler_for_task \
-     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(task))
-#define ASSERT_ARGS_Parrot_cx_find_handler_local __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
-       PARROT_ASSERT_ARG(interp) \
-    , PARROT_ASSERT_ARG(task))
 #define ASSERT_ARGS_Parrot_cx_handle_tasks __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(scheduler) \

Added: branches/gsoc_threads/src/events.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gsoc_threads/src/events.c	Thu Jul 15 04:48:04 2010	(r48093)
@@ -0,0 +1,416 @@
+/*
+Copyright (C) 2007-2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/events.c - Routines supporting the event handling mechanism.
+
+=head1 DESCRIPTION
+
+Users can register event handlers. When events occur, they are dispatched
+to the appropriate handler asynchronously.
+
+=cut
+
+*/
+
+#include "parrot/parrot.h"
+#include "parrot/runcore_api.h"
+#include "parrot/events.h"
+
+#include "events.str"
+
+/* HEADERIZER HFILE: include/parrot/events.h */
+
+/*
+
+=item C<void Parrot_cx_add_handler_local(PARROT_INTERP, PMC *handler)>
+
+Add a handler to the current context's list of handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_cx_add_handler_local(PARROT_INTERP, ARGIN(PMC *handler))
+{
+    ASSERT_ARGS(Parrot_cx_add_handler_local)
+    if (PMC_IS_NULL(Parrot_pcc_get_handlers(interp, interp->ctx)))
+        Parrot_pcc_set_handlers(interp, interp->ctx,
+                                Parrot_pmc_new(interp, enum_class_ResizablePMCArray));
+
+    VTABLE_unshift_pmc(interp, Parrot_pcc_get_handlers(interp, interp->ctx), handler);
+
+}
+
+/*
+
+=item C<void Parrot_cx_delete_handler_local(PARROT_INTERP, STRING
+*handler_type)>
+
+Remove the top task handler of a particular type from the context's list of
+handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_cx_delete_handler_local(PARROT_INTERP, ARGIN(STRING *handler_type))
+{
+    ASSERT_ARGS(Parrot_cx_delete_handler_local)
+    PMC *handlers  = Parrot_pcc_get_handlers(interp, interp->ctx);
+
+    if (PMC_IS_NULL(handlers))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "No handler to delete.");
+
+    if (STRING_IS_NULL(handler_type) || STRING_IS_EMPTY(handler_type))
+        VTABLE_shift_pmc(interp, handlers);
+    else {
+        /* Loop from newest handler to oldest handler. */
+        STRING      *exception_str = CONST_STRING(interp, "exception");
+        STRING      *event_str     = CONST_STRING(interp, "event");
+        STRING      *handler_str   = CONST_STRING(interp, "ExceptionHandler");
+        const INTVAL elements      = VTABLE_elements(interp, handlers);
+        INTVAL       index;
+        typedef enum { Hunknown,  Hexception, Hevent } Htype;
+
+        const Htype htype =
+            Parrot_str_equal(interp, handler_type, exception_str) ?
+            Hexception :
+            Parrot_str_equal(interp, handler_type, event_str) ?
+                Hevent :
+                Hunknown;
+        STRING * const handler_name = (htype == Hexception) ? handler_str : (STRING *)NULL;
+
+        for (index = 0; index < elements; ++index) {
+            PMC * const handler = VTABLE_get_pmc_keyed_int(interp, handlers, index);
+            if (!PMC_IS_NULL(handler)) {
+                switch (htype) {
+                  case Hexception:
+                    if (VTABLE_isa(interp, handler, handler_name)) {
+                        VTABLE_set_pmc_keyed_int(interp, handlers, index, PMCNULL);
+                        return;
+                    }
+                    break;
+                  case Hevent:
+                    if (handler->vtable->base_type == enum_class_EventHandler) {
+                        VTABLE_set_pmc_keyed_int(interp, handlers, index, PMCNULL);
+                        return;
+                    }
+                    break;
+                  default:
+                    break;
+                }
+            }
+        }
+
+        Parrot_ex_throw_from_c_args(interp, NULL,
+            EXCEPTION_INVALID_OPERATION, "No handler to delete.");
+    }
+}
+
+
+/*
+
+=item C<INTVAL Parrot_cx_count_handlers_local(PARROT_INTERP, STRING
+*handler_type)>
+
+Count the number of active handlers of a particular type from the
+context's list of handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+INTVAL
+Parrot_cx_count_handlers_local(PARROT_INTERP, ARGIN(STRING *handler_type))
+{
+    ASSERT_ARGS(Parrot_cx_count_handlers_local)
+    PMC * const handlers = Parrot_pcc_get_handlers(interp, interp->ctx);
+    INTVAL elements;
+
+    if (PMC_IS_NULL(handlers))
+        return 0;
+
+    elements = VTABLE_elements(interp, handlers);
+
+    if (STRING_IS_NULL(handler_type) || STRING_IS_EMPTY(handler_type))
+        return elements;
+
+    /* Loop from newest handler to oldest handler. */
+    {
+        STRING      *exception_str = CONST_STRING(interp, "exception");
+        STRING      *event_str     = CONST_STRING(interp, "event");
+        STRING      *handler_str   = CONST_STRING(interp, "ExceptionHandler");
+        INTVAL       count = 0;
+        INTVAL       index;
+        typedef enum { Hunknown,  Hexception, Hevent } Htype;
+
+        const Htype htype =
+            (Parrot_str_equal(interp, handler_type, exception_str)) ?
+            Hexception :
+            (Parrot_str_equal(interp, handler_type, event_str)) ?
+                Hevent :
+                Hunknown;
+        STRING * const handler_name = (htype == Hexception) ? handler_str : (STRING *)NULL;
+
+        for (index = 0; index < elements; ++index) {
+            PMC * const handler = VTABLE_get_pmc_keyed_int(interp, handlers, index);
+            if (!PMC_IS_NULL(handler)) {
+                switch (htype) {
+                  case Hexception:
+                    if (VTABLE_isa(interp, handler, handler_name))
+                        ++count;
+                    break;
+                  case Hevent:
+                    if (handler->vtable->base_type == enum_class_EventHandler)
+                        ++count;
+                    break;
+                  default:
+                    break;
+                }
+            }
+        }
+        return count;
+    }
+}
+
+
+/*
+
+=item C<void Parrot_cx_add_handler(PARROT_INTERP, PMC *handler)>
+
+Add a task handler to scheduler's list of handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_cx_add_handler(PARROT_INTERP, ARGIN(PMC *handler))
+{
+    ASSERT_ARGS(Parrot_cx_add_handler)
+    STRING * const add_handler = CONST_STRING(interp, "add_handler");
+    if (!interp->scheduler)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Scheduler was not initialized for this interpreter.\n");
+
+    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, add_handler, "P->", handler);
+}
+
+/*
+
+=item C<void Parrot_cx_delete_handler_typed(PARROT_INTERP, STRING
+*handler_type)>
+
+Remove the top task handler of a particular type from the scheduler's list of
+handlers.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+Parrot_cx_delete_handler_typed(PARROT_INTERP, ARGIN(STRING *handler_type))
+{
+    ASSERT_ARGS(Parrot_cx_delete_handler_typed)
+    if (!interp->scheduler)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Scheduler was not initialized for this interpreter.\n");
+
+    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, CONST_STRING(interp, "delete_handler"), "S->", handler_type);
+}
+
+/*
+
+=item C<INTVAL Parrot_cx_count_handlers_typed(PARROT_INTERP, STRING
+*handler_type)>
+
+Count the number of active handlers of a particular type (event, exception) in
+the concurrency scheduler.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+INTVAL
+Parrot_cx_count_handlers_typed(PARROT_INTERP, ARGIN(STRING *handler_type))
+{
+    ASSERT_ARGS(Parrot_cx_count_handlers_typed)
+    INTVAL count = 0;
+
+    if (!interp->scheduler)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Scheduler was not initialized for this interpreter.\n");
+
+    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, CONST_STRING(interp, "count_handlers"), "S->I", handler_type, &count);
+
+    return count;
+}
+
+
+/*
+
+=back
+
+=head2 Task Interface Functions
+
+Functions that are used to interface with a specific task in the concurrency scheduler.
+
+=over 4
+
+=item C<PMC * Parrot_cx_find_handler_for_task(PARROT_INTERP, PMC *task)>
+
+Retrieve a handler appropriate to a given task. If the scheduler has no
+appropriate handler, returns PMCNULL.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC *
+Parrot_cx_find_handler_for_task(PARROT_INTERP, ARGIN(PMC *task))
+{
+    ASSERT_ARGS(Parrot_cx_find_handler_for_task)
+    PMC *handler = PMCNULL;
+#if CX_DEBUG
+    fprintf(stderr, "searching for handler\n");
+#endif
+
+    if (!interp->scheduler)
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+            "Scheduler was not initialized for this interpreter.\n");
+
+    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, CONST_STRING(interp, "find_handler"), "P->P", task, &handler);
+
+#if CX_DEBUG
+    fprintf(stderr, "done searching for handler\n");
+#endif
+
+    return handler;
+}
+
+/*
+
+=item C<PMC * Parrot_cx_find_handler_local(PARROT_INTERP, PMC *task)>
+
+Retrieve a handler appropriate to a given task from the local context. If the
+context has no appropriate handler, returns PMCNULL.
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC *
+Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
+{
+    ASSERT_ARGS(Parrot_cx_find_handler_local)
+
+    /*
+     * Quick&dirty way to avoid infinite recursion
+     * when an exception is thrown while looking
+     * for a handler
+     */
+    static int already_doing = 0;
+    static PMC * keep_context = NULL;
+
+    PMC            *context;
+    PMC            *iter        = PMCNULL;
+    STRING * const  handled_str = CONST_STRING(interp, "handled");
+    STRING * const  iter_str    = CONST_STRING(interp, "handler_iter");
+
+    if (already_doing) {
+        Parrot_io_eprintf(interp,
+            "** Exception caught while looking for a handler, trying next **\n");
+        if (! keep_context)
+            return NULL;
+        /*
+         * Note that we are now trying to handle the new exception,
+         * not the initial task argument (exception or whatever).
+         */
+        context = Parrot_pcc_get_caller_ctx(interp, keep_context);
+        keep_context = NULL;
+        if (context && !PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
+            iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
+        else
+            iter = PMCNULL;
+    }
+    else {
+        ++already_doing;
+
+        /* Exceptions store the handler iterator for rethrow, other kinds of
+         * tasks don't (though they could). */
+        if (task->vtable->base_type == enum_class_Exception
+        && VTABLE_get_integer_keyed_str(interp, task, handled_str) == -1) {
+            iter    = VTABLE_get_attr_str(interp, task, iter_str);
+            context = (PMC *)VTABLE_get_pointer(interp, task);
+        }
+        else {
+            context = CURRENT_CONTEXT(interp);
+            if (!PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
+                iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
+        }
+    }
+
+    while (context) {
+        keep_context = context;
+        /* Loop from newest handler to oldest handler. */
+        while (!PMC_IS_NULL(iter) && VTABLE_get_bool(interp, iter)) {
+            PMC * const handler = VTABLE_shift_pmc(interp, iter);
+
+            if (!PMC_IS_NULL(handler)) {
+                INTVAL valid_handler = 0;
+                if (handler->vtable->base_type == enum_class_Object)
+                    Parrot_pcc_invoke_method_from_c_args(interp, handler, CONST_STRING(interp, "can_handle"),
+                        "P->I", task, &valid_handler);
+                else
+                    Parrot_pcc_invoke_method_from_c_args(interp, handler, CONST_STRING(interp, "can_handle"),
+                        "P->I", task, &valid_handler);
+
+                if (valid_handler) {
+                    if (task->vtable->base_type == enum_class_Exception) {
+                        /* Store iterator and context for a later rethrow. */
+                        VTABLE_set_attr_str(interp, task, CONST_STRING(interp, "handler_iter"), iter);
+                        VTABLE_set_pointer(interp, task, context);
+                    }
+                    --already_doing;
+                    keep_context = NULL;
+                    return handler;
+                }
+            }
+        }
+
+        /* Continue the search in the next context up the chain. */
+        context = Parrot_pcc_get_caller_ctx(interp, context);
+        if (context && !PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
+            iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
+        else
+            iter = PMCNULL;
+    }
+
+    /* Reached the end of the context chain without finding a handler. */
+
+    --already_doing;
+    return PMCNULL;
+}
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Added: branches/gsoc_threads/src/pmc/event.pmc
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ branches/gsoc_threads/src/pmc/event.pmc	Thu Jul 15 04:48:04 2010	(r48093)
@@ -0,0 +1,556 @@
+/*
+Copyright (C) 2001-2008, Parrot Foundation.
+$Id: task.pmc 48010 2010-07-05 15:36:03Z Chandon $
+
+=head1 NAME
+
+src/pmc/event.pmc - An event that may want to be handled.
+
+=head1 DESCRIPTION
+
+Implements the basic event behavior for the concurrency scheduler.
+
+=head2 Functions
+
+=over 4
+
+=cut
+
+*/
+
+#include "parrot/scheduler_private.h"
+
+/* HEADERIZER HFILE: none */
+/* HEADERIZER BEGIN: static */
+/* HEADERIZER END: static */
+
+pmclass Event 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. */
+    ATTR STRING       *type;      /* The type of the task. */
+    ATTR STRING       *subtype;   /* The subtype of the task. */
+    ATTR STRING       *status;    /* The status of the task. */
+    ATTR Parrot_Interp interp;    /* The interpreter that created the task. */
+    ATTR PMC          *codeblock; /* An (optional) codeblock for the task. */
+    ATTR PMC          *data;      /* Additional data for the task. */
+    ATTR char         *cb_data;   /* Additional data for a callback event. */
+
+/*
+
+=item C<void init()>
+
+Initialize an event object.
+
+=cut
+
+*/
+
+    VTABLE void init() {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+
+        /* Set flags for custom GC mark. */
+        PObj_custom_mark_SET(SELF);
+
+        /* Set up the core struct. */
+        core_struct->id          = 0;
+        core_struct->type        = CONST_STRING(INTERP, "");
+        core_struct->subtype     = CONST_STRING(INTERP, "");
+        core_struct->priority    = 0;
+        core_struct->status      = CONST_STRING(INTERP, "created");
+        core_struct->birthtime   = 0.0;
+        core_struct->codeblock   = PMCNULL;
+        core_struct->data        = PMCNULL;
+        core_struct->interp      = INTERP;
+
+        /* Make sure the flag is cleared by default */
+        TASK_terminate_runloop_CLEAR(SELF);
+
+    }
+
+/*
+
+=item C<void init_pmc(PMC *data)>
+
+Initializes a new Event with a C<Hash> PMC with any or all of the keys:
+
+=over 4
+
+=item C<id>
+
+An C<Integer> representing the task's unique identifier.
+
+=item C<type>
+
+A C<String> representing the type of the task.
+
+=item C<subtype>
+
+A C<String> representing the subtype of the task. (Used mostly by events and
+exceptions to identify appropriate handlers.)
+
+=item C<priority>
+
+An C<Integer> representing the task's priority, from 0 to 100.
+
+=item C<status>
+
+A C<String> representing the task's status, one of C<created>, C<invoked>,
+C<inprocess>, or C<completed>.
+
+=item C<birthtime>
+
+The time at which this Event was inserted into the task list.
+
+=item C<code>
+
+A C<Sub> or descendant PMC related to this task.
+
+=item C<interp>
+
+An interpreter in which to execute this task.
+
+=back
+
+=cut
+
+*/
+
+    VTABLE void init_pmc(PMC *data) {
+        PMC         *elem;
+        Parrot_Event_attributes *core_struct;
+
+        if (! VTABLE_isa(INTERP, data, CONST_STRING(INTERP, "Hash")))
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
+                "Event initializer must be a Hash");
+
+        core_struct = (Parrot_Event_attributes *) PMC_data(SELF);
+
+        /* Set flags for custom GC mark. */
+        PObj_custom_mark_SET(SELF);
+
+        /* Set up the core struct. */
+
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "id"));
+        if (! PMC_IS_NULL(elem))
+            core_struct->id = VTABLE_get_integer(INTERP, elem);
+        else
+            core_struct->id = 0;
+
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "type"));
+        if (! PMC_IS_NULL(elem))
+            core_struct->type = VTABLE_get_string(INTERP, elem);
+        else
+            core_struct->type = CONST_STRING(INTERP, "");
+
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "subtype"));
+        if (! PMC_IS_NULL(elem))
+            core_struct->subtype = VTABLE_get_string(INTERP, elem);
+        else
+            core_struct->subtype = CONST_STRING(INTERP, "");
+
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "priority"));
+        if (! PMC_IS_NULL(elem))
+            core_struct->priority = VTABLE_get_integer(INTERP, elem);
+        else
+            core_struct->priority = 0;
+
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "status"));
+        if (! PMC_IS_NULL(elem))
+            core_struct->status = VTABLE_get_string(INTERP, elem);
+        else
+            core_struct->status = CONST_STRING(INTERP, "created");
+
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "birthtime"));
+        if (! PMC_IS_NULL(elem))
+            core_struct->birthtime = VTABLE_get_number(INTERP, elem);
+        else
+            core_struct->birthtime = 0.0;
+
+        core_struct->codeblock = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "code"));
+        core_struct->interp = (Parrot_Interp)VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "data"));
+    }
+
+/*
+
+=item C<opcode_t *invoke(void *next)>
+
+Invokes whatever is in the Event's associated codeblock.
+
+If the Event's data attribute is not null, pass it to the
+codeblock as the first argument.
+
+=cut
+
+*/
+
+    VTABLE opcode_t *invoke(void *next) {
+        Parrot_Event_attributes *const task = PARROT_EVENT(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.
+
+=cut
+
+*/
+
+    VTABLE PMC *clone() {
+        /* Create the new task PMC, of the same type of this one (we may
+         * have been subclassed). */
+        PMC * const copy  = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
+        Parrot_Event_attributes * const new_struct = PARROT_EVENT(copy);
+        Parrot_Event_attributes * const old_struct = PARROT_EVENT(SELF);
+
+        new_struct->codeblock = VTABLE_clone(INTERP, old_struct->codeblock);
+        new_struct->data      = old_struct->data;
+        new_struct->type      = old_struct->type;
+        new_struct->subtype   = old_struct->subtype;
+        new_struct->priority  = old_struct->priority;
+
+        return copy;
+    }
+/*
+
+=item C<PMC *get_attr_str(STRING *name)>
+
+Gets the value of an attribute for this task.
+
+=cut
+
+*/
+    VTABLE PMC *get_attr_str(STRING *name) {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+        PMC *value;
+
+        if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "id"))) {
+            value = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
+                    core_struct->id);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "type"))) {
+            value = Parrot_pmc_new(INTERP, enum_class_String);
+            VTABLE_set_string_native(INTERP, value, core_struct->type);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "subtype"))) {
+            value = Parrot_pmc_new(INTERP, enum_class_String);
+            VTABLE_set_string_native(INTERP, value, core_struct->subtype);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "priority"))) {
+            value = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
+                    core_struct->priority);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "status"))) {
+            value = Parrot_pmc_new(INTERP, enum_class_String);
+            VTABLE_set_string_native(INTERP, value, core_struct->status);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "birthtime"))) {
+            value = Parrot_pmc_new(INTERP, enum_class_Float);
+            VTABLE_set_number_native(INTERP, value, core_struct->birthtime);
+        }
+        else {
+            value = PMCNULL;
+        }
+
+        return value;
+    }
+
+/*
+
+=item C<void set_attr_str(STRING *name, PMC *value)>
+
+Sets the value of an attribute for this task.
+
+=cut
+
+*/
+    VTABLE void set_attr_str(STRING *name, PMC *value) {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+
+        if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "id"))) {
+            core_struct->id = VTABLE_get_integer(INTERP, value);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "type"))) {
+            core_struct->type = VTABLE_get_string(INTERP, value);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "subtype"))) {
+            core_struct->subtype = VTABLE_get_string(INTERP, value);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "priority"))) {
+            core_struct->priority = VTABLE_get_integer(INTERP, value);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "status"))) {
+            core_struct->status = VTABLE_get_string(INTERP, value);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "birthtime"))) {
+            core_struct->birthtime = VTABLE_get_number(INTERP, value);
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "code"))) {
+            core_struct->codeblock = value;
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "data"))) {
+            core_struct->data = value;
+        }
+    }
+
+/*
+
+=item C<INTVAL get_integer()>
+
+Retrieves the task ID for this task.
+
+=cut
+
+*/
+    VTABLE INTVAL get_integer() {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+        return core_struct->id;
+    }
+
+/*
+
+=item C<void set_integer_native(INTVAL value)>
+
+Sets the task ID of the task.
+
+=cut
+
+*/
+
+    VTABLE void set_integer_native(INTVAL value) {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+        core_struct->id = value;
+    }
+
+/*
+
+=item C<void set_number_native(FLOATVAL value)>
+
+Sets the birthtime of the task.
+
+=cut
+
+*/
+
+    VTABLE void set_number_native(FLOATVAL value) {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+        core_struct->birthtime = value;
+    }
+
+/*
+
+=item C<void set_string_native(STRING *value)>
+
+Sets the type of the task.
+
+=cut
+
+*/
+
+    VTABLE void set_string_native(STRING *value) {
+        Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+        core_struct->type = value;
+    }
+
+/*
+
+=item C<PMC *share_ro()>
+
+Set this PMC as shared.
+
+=cut
+
+*/
+
+    VTABLE PMC *share_ro() {
+        PMC *shared_self;
+        Parrot_Event_attributes *shared_struct;
+
+        if (PObj_is_PMC_shared_TEST(SELF))
+            return SELF;
+
+        shared_self = pt_shared_fixup(INTERP, SELF);
+        shared_struct = PARROT_EVENT(shared_self);
+
+        if (!PMC_IS_NULL(shared_struct->codeblock))
+            shared_struct->codeblock = pt_shared_fixup(INTERP, shared_struct->codeblock);
+
+        if (!PMC_IS_NULL(shared_struct->data))
+            shared_struct->data = pt_shared_fixup(INTERP, shared_struct->data);
+
+        return shared_self;
+    }
+
+/*
+
+=item C<void mark()>
+
+Mark any referenced strings and PMCs.
+
+=cut
+
+*/
+    VTABLE void mark() {
+        if (PARROT_EVENT(SELF)) {
+            Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+
+            Parrot_gc_mark_STRING_alive(INTERP, core_struct->type);
+            Parrot_gc_mark_STRING_alive(INTERP, core_struct->subtype);
+            Parrot_gc_mark_STRING_alive(INTERP, core_struct->status);
+            Parrot_gc_mark_PMC_alive(INTERP, core_struct->codeblock);
+            Parrot_gc_mark_PMC_alive(INTERP, core_struct->data);
+        }
+    }
+
+/*
+
+=item C<void visit(PMC *info)>
+
+This is used by freeze/thaw to visit the contents of the task.
+
+C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
+
+=cut
+
+*/
+
+    VTABLE void visit(PMC *info) {
+        /* 1) visit code block */
+        VISIT_PMC_ATTR(INTERP, info, SELF, Event, codeblock);
+    }
+
+/*
+
+=item C<void freeze(PMC *info)>
+
+Used to archive the task.
+
+=cut
+
+*/
+
+    VTABLE void freeze(PMC *info) {
+        const Parrot_Event_attributes * const core_struct = PARROT_EVENT(SELF);
+
+        /* 1) freeze task id */
+        VTABLE_push_integer(INTERP, info, core_struct->id);
+
+        /* 2) freeze task birthtime */
+        VTABLE_push_float(INTERP, info, core_struct->birthtime);
+
+        /* 3) freeze task priority */
+        VTABLE_push_integer(INTERP, info, core_struct->priority);
+
+        /* 4) freeze task type */
+        VTABLE_push_string(INTERP, info, core_struct->type);
+
+        /* 5) freeze task subtype */
+        VTABLE_push_string(INTERP, info, core_struct->subtype);
+
+        /* 6) freeze task status */
+        VTABLE_push_string(INTERP, info, core_struct->status);
+    }
+
+/*
+
+=item C<void thaw(PMC *info)>
+
+Used to unarchive the task.
+
+=cut
+
+*/
+
+    VTABLE void thaw(PMC *info) {
+        /* 1. thaw task id */
+        const INTVAL id = VTABLE_shift_integer(INTERP, info);
+
+        /* 2. thaw task birthtime */
+        const FLOATVAL birthtime = VTABLE_shift_float(INTERP, info);
+
+        /* 3. thaw task priority */
+        const INTVAL priority = VTABLE_shift_integer(INTERP, info);
+
+        /* 4. thaw task type */
+        STRING * const type = VTABLE_shift_string(INTERP, info);
+
+        /* 5. thaw task subtype */
+        STRING * const subtype = VTABLE_shift_string(INTERP, info);
+
+        /* 6. thaw task status */
+        STRING * const status = VTABLE_shift_string(INTERP, info);
+
+        /* Allocate the task's core data struct and set custom flags. */
+        SELF.init();
+
+        /* Set the task's id to the frozen id */
+        PARROT_EVENT(SELF)->id = id;
+
+        /* Set the task's birthtime to the frozen birthtime */
+        PARROT_EVENT(SELF)->birthtime = birthtime;
+
+        /* Set the task's type to the frozen type */
+        PARROT_EVENT(SELF)->type = type;
+
+        /* Set the task's subtype to the frozen subtype */
+        PARROT_EVENT(SELF)->subtype = subtype;
+
+        /* Set the task's priority to the frozen priority */
+        PARROT_EVENT(SELF)->priority = priority;
+
+        /* Set the task's status to the frozen status */
+        PARROT_EVENT(SELF)->status = status;
+
+    }
+
+/*
+
+=item C<void thawfinish(PMC *info)>
+
+Called after the task has been thawed.
+
+=cut
+
+*/
+
+    VTABLE void thawfinish(PMC *info) {
+        Parrot_Event_attributes * core_struct = PARROT_EVENT(SELF);
+
+        UNUSED(core_struct); /* TODO: Rebuild the task index. */
+    }
+
+}
+
+/*
+
+=back
+
+=head1 SEE ALSO
+
+F<docs/pdds/pdd15_objects.pod>.
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ *   c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */

Modified: branches/gsoc_threads/src/pmc/task.pmc
==============================================================================
--- branches/gsoc_threads/src/pmc/task.pmc	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/src/pmc/task.pmc	Thu Jul 15 04:48:04 2010	(r48093)
@@ -8,7 +8,7 @@
 
 =head1 DESCRIPTION
 
-Implements the basic task behavior for the concurrency scheduler.
+The Task PMC represents a concurrent running "green thread".
 
 =head2 Functions
 
@@ -25,16 +25,10 @@
 /* HEADERIZER END: static */
 
 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. */
-    ATTR STRING       *type;      /* The type of the task. */
-    ATTR STRING       *subtype;   /* The subtype of the task. */
-    ATTR STRING       *status;    /* The status of the task. */
     ATTR Parrot_Interp interp;    /* The interpreter that created the task. */
-    ATTR PMC          *codeblock; /* An (optional) codeblock for the task. */
+    ATTR PMC          *code;      /* An (optional) code for the task. */
     ATTR PMC          *data;      /* Additional data for the task. */
-    ATTR char         *cb_data;   /* Additional data for a callback event. */
 
 /*
 
@@ -53,19 +47,10 @@
         PObj_custom_mark_SET(SELF);
 
         /* Set up the core struct. */
-        core_struct->id          = 0;
-        core_struct->type        = CONST_STRING(INTERP, "");
-        core_struct->subtype     = CONST_STRING(INTERP, "");
-        core_struct->priority    = 0;
-        core_struct->status      = CONST_STRING(INTERP, "created");
-        core_struct->birthtime   = 0.0;
-        core_struct->codeblock   = PMCNULL;
-        core_struct->data        = PMCNULL;
-        core_struct->interp      = INTERP;
-
-        /* Make sure the flag is cleared by default */
-        TASK_terminate_runloop_CLEAR(SELF);
-
+        core_struct->birthtime = Parrot_floatval_time();
+        core_struct->code      = PMCNULL;
+        core_struct->data      = PMCNULL;
+        core_struct->interp    = INTERP;
     }
 
 /*
@@ -76,35 +61,17 @@
 
 =over 4
 
-=item C<id>
-
-An C<Integer> representing the task's unique identifier.
-
-=item C<type>
-
-A C<String> representing the type of the task.
-
-=item C<subtype>
-
-A C<String> representing the subtype of the task. (Used mostly by events and
-exceptions to identify appropriate handlers.)
-
-=item C<priority>
-
-An C<Integer> representing the task's priority, from 0 to 100.
-
-=item C<status>
-
-A C<String> representing the task's status, one of C<created>, C<invoked>,
-C<inprocess>, or C<completed>.
-
 =item C<birthtime>
 
-The time at which this Task was inserted into the task list.
+The time at which this Task was created.
 
 =item C<code>
 
-A C<Sub> or descendant PMC related to this task.
+An C<invokable> PMC related to this task.
+
+=item C<data>
+
+Some data that will be passed to C<code> when invoked.
 
 =item C<interp>
 
@@ -124,61 +91,35 @@
             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_INVALID_OPERATION,
                 "Task initializer must be a Hash");
 
-        core_struct = (Parrot_Task_attributes *) PMC_data(SELF);
-
-        /* Set flags for custom GC mark. */
-        PObj_custom_mark_SET(SELF);
-
-        /* Set up the core struct. */
+        SELF.init();
 
-        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "id"));
-        if (! PMC_IS_NULL(elem))
-            core_struct->id = VTABLE_get_integer(INTERP, elem);
-        else
-            core_struct->id = 0;
+        core_struct = (Parrot_Task_attributes *) PMC_data(SELF);
 
-        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "type"));
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "birthtime"));
         if (! PMC_IS_NULL(elem))
-            core_struct->type = VTABLE_get_string(INTERP, elem);
-        else
-            core_struct->type = CONST_STRING(INTERP, "");
+            core_struct->birthtime = VTABLE_get_number(INTERP, elem);
 
-        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "subtype"));
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "code"));
         if (! PMC_IS_NULL(elem))
-            core_struct->subtype = VTABLE_get_string(INTERP, elem);
-        else
-            core_struct->subtype = CONST_STRING(INTERP, "");
+            core_struct->code = elem;
 
-        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "priority"));
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "data"));
         if (! PMC_IS_NULL(elem))
-            core_struct->priority = VTABLE_get_integer(INTERP, elem);
-        else
-            core_struct->priority = 0;
+            core_struct->data = elem;
 
-        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "status"));
+        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "interp"));
         if (! PMC_IS_NULL(elem))
-            core_struct->status = VTABLE_get_string(INTERP, elem);
-        else
-            core_struct->status = CONST_STRING(INTERP, "created");
-
-        elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "birthtime"));
-        if (! PMC_IS_NULL(elem))
-            core_struct->birthtime = VTABLE_get_number(INTERP, elem);
-        else
-            core_struct->birthtime = 0.0;
-
-        core_struct->codeblock = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "code"));
-        core_struct->interp = (Parrot_Interp)VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "data"));
+            core_struct->interp = elem;
     }
 
 /*
 
 =item C<opcode_t *invoke(void *next)>
 
-Invokes whatever is in the Task's associated codeblock.
+Invokes whatever is in the Task's associated code.
 
 If the Task's data attribute is not null, pass it to the
-codeblock as the first argument.
+code as the first argument.
 
 =cut
 
@@ -187,14 +128,14 @@
     VTABLE opcode_t *invoke(void *next) {
         Parrot_Task_attributes *const task = PARROT_TASK(SELF);
 
-        if (PMC_IS_NULL(task->codeblock))
+        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->codeblock, "->");
+            Parrot_pcc_invoke_sub_from_c_args(interp, task->code, "->");
         }
         else {
-            Parrot_pcc_invoke_sub_from_c_args(interp, task->codeblock, "P->", task->data);
+            Parrot_pcc_invoke_sub_from_c_args(interp, task->code, "P->", task->data);
         }
 
         return (opcode_t*) next;
@@ -218,14 +159,12 @@
         Parrot_Task_attributes * const new_struct = PARROT_TASK(copy);
         Parrot_Task_attributes * const old_struct = PARROT_TASK(SELF);
 
-        new_struct->codeblock = VTABLE_clone(INTERP, old_struct->codeblock);
-        new_struct->data      = old_struct->data;
-        new_struct->type      = old_struct->type;
-        new_struct->subtype   = old_struct->subtype;
-        new_struct->priority  = old_struct->priority;
+        new_struct->code = VTABLE_clone(INTERP, old_struct->code);
+        new_struct->data = VTABLE_clone(INTERP, old_struct->data);
 
         return copy;
     }
+
 /*
 
 =item C<PMC *get_attr_str(STRING *name)>
@@ -239,30 +178,16 @@
         Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
         PMC *value;
 
-        if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "id"))) {
-            value = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
-                    core_struct->id);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "type"))) {
-            value = Parrot_pmc_new(INTERP, enum_class_String);
-            VTABLE_set_string_native(INTERP, value, core_struct->type);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "subtype"))) {
-            value = Parrot_pmc_new(INTERP, enum_class_String);
-            VTABLE_set_string_native(INTERP, value, core_struct->subtype);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "priority"))) {
-            value = Parrot_pmc_new_init_int(INTERP, enum_class_Integer,
-                    core_struct->priority);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "status"))) {
-            value = Parrot_pmc_new(INTERP, enum_class_String);
-            VTABLE_set_string_native(INTERP, value, core_struct->status);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "birthtime"))) {
+        if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "birthtime"))) {
             value = Parrot_pmc_new(INTERP, enum_class_Float);
             VTABLE_set_number_native(INTERP, value, core_struct->birthtime);
         }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "code"))) {
+            value = core_struct->code;
+        }
+        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "data"))) {
+            value = core_struct->data;
+        }
         else {
             value = PMCNULL;
         }
@@ -279,29 +204,15 @@
 =cut
 
 */
+
     VTABLE void set_attr_str(STRING *name, PMC *value) {
         Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
 
-        if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "id"))) {
-            core_struct->id = VTABLE_get_integer(INTERP, value);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "type"))) {
-            core_struct->type = VTABLE_get_string(INTERP, value);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "subtype"))) {
-            core_struct->subtype = VTABLE_get_string(INTERP, value);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "priority"))) {
-            core_struct->priority = VTABLE_get_integer(INTERP, value);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "status"))) {
-            core_struct->status = VTABLE_get_string(INTERP, value);
-        }
-        else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "birthtime"))) {
+        if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "birthtime"))) {
             core_struct->birthtime = VTABLE_get_number(INTERP, value);
         }
         else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "code"))) {
-            core_struct->codeblock = value;
+            core_struct->code = value;
         }
         else if (Parrot_str_equal(INTERP, name, CONST_STRING(INTERP, "data"))) {
             core_struct->data = value;
@@ -310,65 +221,6 @@
 
 /*
 
-=item C<INTVAL get_integer()>
-
-Retrieves the task ID for this task.
-
-=cut
-
-*/
-    VTABLE INTVAL get_integer() {
-        Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
-        return core_struct->id;
-    }
-
-/*
-
-=item C<void set_integer_native(INTVAL value)>
-
-Sets the task ID of the task.
-
-=cut
-
-*/
-
-    VTABLE void set_integer_native(INTVAL value) {
-        Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
-        core_struct->id = value;
-    }
-
-/*
-
-=item C<void set_number_native(FLOATVAL value)>
-
-Sets the birthtime of the task.
-
-=cut
-
-*/
-
-    VTABLE void set_number_native(FLOATVAL value) {
-        Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
-        core_struct->birthtime = value;
-    }
-
-/*
-
-=item C<void set_string_native(STRING *value)>
-
-Sets the type of the task.
-
-=cut
-
-*/
-
-    VTABLE void set_string_native(STRING *value) {
-        Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
-        core_struct->type = value;
-    }
-
-/*
-
 =item C<PMC *share_ro()>
 
 Set this PMC as shared.
@@ -387,8 +239,8 @@
         shared_self = pt_shared_fixup(INTERP, SELF);
         shared_struct = PARROT_TASK(shared_self);
 
-        if (!PMC_IS_NULL(shared_struct->codeblock))
-            shared_struct->codeblock = pt_shared_fixup(INTERP, shared_struct->codeblock);
+        if (!PMC_IS_NULL(shared_struct->code))
+            shared_struct->code = pt_shared_fixup(INTERP, shared_struct->code);
 
         if (!PMC_IS_NULL(shared_struct->data))
             shared_struct->data = pt_shared_fixup(INTERP, shared_struct->data);
@@ -409,10 +261,7 @@
         if (PARROT_TASK(SELF)) {
             Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
 
-            Parrot_gc_mark_STRING_alive(INTERP, core_struct->type);
-            Parrot_gc_mark_STRING_alive(INTERP, core_struct->subtype);
-            Parrot_gc_mark_STRING_alive(INTERP, core_struct->status);
-            Parrot_gc_mark_PMC_alive(INTERP, core_struct->codeblock);
+            Parrot_gc_mark_PMC_alive(INTERP, core_struct->code);
             Parrot_gc_mark_PMC_alive(INTERP, core_struct->data);
         }
     }
@@ -431,7 +280,8 @@
 
     VTABLE void visit(PMC *info) {
         /* 1) visit code block */
-        VISIT_PMC_ATTR(INTERP, info, SELF, Task, codeblock);
+        VISIT_PMC_ATTR(INTERP, info, SELF, Task, code);
+        VISIT_PMC_ATTR(INTERP, info, SELF, Task, data);
     }
 
 /*
@@ -447,23 +297,7 @@
     VTABLE void freeze(PMC *info) {
         const Parrot_Task_attributes * const core_struct = PARROT_TASK(SELF);
 
-        /* 1) freeze task id */
-        VTABLE_push_integer(INTERP, info, core_struct->id);
-
-        /* 2) freeze task birthtime */
         VTABLE_push_float(INTERP, info, core_struct->birthtime);
-
-        /* 3) freeze task priority */
-        VTABLE_push_integer(INTERP, info, core_struct->priority);
-
-        /* 4) freeze task type */
-        VTABLE_push_string(INTERP, info, core_struct->type);
-
-        /* 5) freeze task subtype */
-        VTABLE_push_string(INTERP, info, core_struct->subtype);
-
-        /* 6) freeze task status */
-        VTABLE_push_string(INTERP, info, core_struct->status);
     }
 
 /*
@@ -477,45 +311,13 @@
 */
 
     VTABLE void thaw(PMC *info) {
-        /* 1. thaw task id */
-        const INTVAL id = VTABLE_shift_integer(INTERP, info);
-
-        /* 2. thaw task birthtime */
         const FLOATVAL birthtime = VTABLE_shift_float(INTERP, info);
 
-        /* 3. thaw task priority */
-        const INTVAL priority = VTABLE_shift_integer(INTERP, info);
-
-        /* 4. thaw task type */
-        STRING * const type = VTABLE_shift_string(INTERP, info);
-
-        /* 5. thaw task subtype */
-        STRING * const subtype = VTABLE_shift_string(INTERP, info);
-
-        /* 6. thaw task status */
-        STRING * const status = VTABLE_shift_string(INTERP, info);
-
         /* Allocate the task's core data struct and set custom flags. */
         SELF.init();
 
-        /* Set the task's id to the frozen id */
-        PARROT_TASK(SELF)->id = id;
-
         /* Set the task's birthtime to the frozen birthtime */
         PARROT_TASK(SELF)->birthtime = birthtime;
-
-        /* Set the task's type to the frozen type */
-        PARROT_TASK(SELF)->type = type;
-
-        /* Set the task's subtype to the frozen subtype */
-        PARROT_TASK(SELF)->subtype = subtype;
-
-        /* Set the task's priority to the frozen priority */
-        PARROT_TASK(SELF)->priority = priority;
-
-        /* Set the task's status to the frozen status */
-        PARROT_TASK(SELF)->status = status;
-
     }
 
 /*
@@ -531,7 +333,7 @@
     VTABLE void thawfinish(PMC *info) {
         Parrot_Task_attributes * core_struct = PARROT_TASK(SELF);
 
-        UNUSED(core_struct); /* TODO: Rebuild the task index. */
+        UNUSED(core_struct); /* Do nothing */
     }
 
 }

Modified: branches/gsoc_threads/src/pmc/timer.pmc
==============================================================================
--- branches/gsoc_threads/src/pmc/timer.pmc	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/src/pmc/timer.pmc	Thu Jul 15 04:48:04 2010	(r48093)
@@ -56,7 +56,9 @@
 /* HEADERIZER BEGIN: static */
 /* HEADERIZER END: static */
 
-pmclass Timer extends Task provides event provides invokable auto_attrs {
+pmclass Timer provides invokable auto_attrs {
+    ATTR PMC     *code;      /* The sub to execute */
+    ATTR FLOATVAL birthtime; /* When the timer was created */
     ATTR FLOATVAL duration;  /* The duration of the timer pause */
     ATTR FLOATVAL interval;  /* How often to repeat */
     ATTR INTVAL   repeat;    /* Whether to repeat:
@@ -82,13 +84,13 @@
         PObj_custom_mark_SET(SELF);
 
         /* Set up the core struct. */
-        core_struct->type        = CONST_STRING(INTERP, "timer");
-        core_struct->codeblock   = PMCNULL;
-        core_struct->duration    = 0.0;
-        core_struct->interval    = 0.0;
-        core_struct->repeat      = 0;
-        core_struct->started     = 0;
-        core_struct->running     = 0;
+        core_struct->code      = PMCNULL;
+        core_struct->birthtime = 0.0;
+        core_struct->duration  = 0.0;
+        core_struct->interval  = 0.0;
+        core_struct->repeat    = 0;
+        core_struct->started   = 0;
+        core_struct->running   = 0;
     }
 
 /*
@@ -149,13 +151,15 @@
 */
 
     VTABLE PMC *clone() {
-        PMC * const copy = SUPER();
+        PMC * const copy = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
+
         Parrot_Timer_attributes * const new_struct = PARROT_TIMER(copy);
         Parrot_Timer_attributes * const old_struct = PARROT_TIMER(SELF);
 
         new_struct->duration  = old_struct->duration;
         new_struct->interval  = old_struct->interval;
         new_struct->repeat    = old_struct->repeat;
+        new_struct->code      = old_struct->code;
 
         return copy;
     }
@@ -203,7 +207,7 @@
     VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
         if (key == PARROT_TIMER_HANDLER) {
             const Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
-            return core_struct->codeblock;
+            return core_struct->code;
         }
 
         return PMCNULL;
@@ -285,7 +289,7 @@
 
     VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
         if (key == PARROT_TIMER_HANDLER) {
-            SET_ATTR_codeblock(INTERP, SELF, value);
+            SET_ATTR_code(INTERP, SELF, value);
         }
     }
 
@@ -327,8 +331,8 @@
         }
         else {
             /* This is the timer triggering. */
-            if (!PMC_IS_NULL(timer->codeblock)) {
-                Parrot_pcc_invoke_sub_from_c_args(interp, timer->codeblock, "->");
+            if (!PMC_IS_NULL(timer->code)) {
+                Parrot_pcc_invoke_sub_from_c_args(interp, timer->code, "->");
             }
 
             /* Repeat semantics as documented. */
@@ -376,6 +380,23 @@
                     key);
         }
     }
+
+/*
+
+=item C<void mark()>
+
+Mark any referenced strings and PMCs.
+
+=cut
+
+*/
+    VTABLE void mark() {
+        if (PARROT_TIMER(SELF)) {
+            Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
+            Parrot_gc_mark_PMC_alive(INTERP, core_struct->code);
+        }
+    }
+
 }
 
 /*

Modified: branches/gsoc_threads/src/scheduler.c
==============================================================================
--- branches/gsoc_threads/src/scheduler.c	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/src/scheduler.c	Thu Jul 15 04:48:04 2010	(r48093)
@@ -115,8 +115,8 @@
 
     PMC* main_task = Parrot_pmc_new(interp, enum_class_Task);
     Parrot_Task_attributes *tdata = PARROT_TASK(main_task);
-    tdata->codeblock = main;
-    tdata->data      = argv;
+    tdata->code = main;
+    tdata->data = argv;
 
     Parrot_cx_schedule_task(interp, main_task);
 
@@ -488,241 +488,6 @@
 
 /*
 
-=item C<void Parrot_cx_add_handler_local(PARROT_INTERP, PMC *handler)>
-
-Add a handler to the current context's list of handlers.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_cx_add_handler_local(PARROT_INTERP, ARGIN(PMC *handler))
-{
-    ASSERT_ARGS(Parrot_cx_add_handler_local)
-    if (PMC_IS_NULL(Parrot_pcc_get_handlers(interp, interp->ctx)))
-        Parrot_pcc_set_handlers(interp, interp->ctx,
-                                Parrot_pmc_new(interp, enum_class_ResizablePMCArray));
-
-    VTABLE_unshift_pmc(interp, Parrot_pcc_get_handlers(interp, interp->ctx), handler);
-
-}
-
-/*
-
-=item C<void Parrot_cx_delete_handler_local(PARROT_INTERP, STRING
-*handler_type)>
-
-Remove the top task handler of a particular type from the context's list of
-handlers.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_cx_delete_handler_local(PARROT_INTERP, ARGIN(STRING *handler_type))
-{
-    ASSERT_ARGS(Parrot_cx_delete_handler_local)
-    PMC *handlers  = Parrot_pcc_get_handlers(interp, interp->ctx);
-
-    if (PMC_IS_NULL(handlers))
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "No handler to delete.");
-
-    if (STRING_IS_NULL(handler_type) || STRING_IS_EMPTY(handler_type))
-        VTABLE_shift_pmc(interp, handlers);
-    else {
-        /* Loop from newest handler to oldest handler. */
-        STRING      *exception_str = CONST_STRING(interp, "exception");
-        STRING      *event_str     = CONST_STRING(interp, "event");
-        STRING      *handler_str   = CONST_STRING(interp, "ExceptionHandler");
-        const INTVAL elements      = VTABLE_elements(interp, handlers);
-        INTVAL       index;
-        typedef enum { Hunknown,  Hexception, Hevent } Htype;
-
-        const Htype htype =
-            Parrot_str_equal(interp, handler_type, exception_str) ?
-            Hexception :
-            Parrot_str_equal(interp, handler_type, event_str) ?
-                Hevent :
-                Hunknown;
-        STRING * const handler_name = (htype == Hexception) ? handler_str : (STRING *)NULL;
-
-        for (index = 0; index < elements; ++index) {
-            PMC * const handler = VTABLE_get_pmc_keyed_int(interp, handlers, index);
-            if (!PMC_IS_NULL(handler)) {
-                switch (htype) {
-                  case Hexception:
-                    if (VTABLE_isa(interp, handler, handler_name)) {
-                        VTABLE_set_pmc_keyed_int(interp, handlers, index, PMCNULL);
-                        return;
-                    }
-                    break;
-                  case Hevent:
-                    if (handler->vtable->base_type == enum_class_EventHandler) {
-                        VTABLE_set_pmc_keyed_int(interp, handlers, index, PMCNULL);
-                        return;
-                    }
-                    break;
-                  default:
-                    break;
-                }
-            }
-        }
-
-        Parrot_ex_throw_from_c_args(interp, NULL,
-            EXCEPTION_INVALID_OPERATION, "No handler to delete.");
-    }
-}
-
-
-/*
-
-=item C<INTVAL Parrot_cx_count_handlers_local(PARROT_INTERP, STRING
-*handler_type)>
-
-Count the number of active handlers of a particular type from the
-context's list of handlers.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-Parrot_cx_count_handlers_local(PARROT_INTERP, ARGIN(STRING *handler_type))
-{
-    ASSERT_ARGS(Parrot_cx_count_handlers_local)
-    PMC * const handlers = Parrot_pcc_get_handlers(interp, interp->ctx);
-    INTVAL elements;
-
-    if (PMC_IS_NULL(handlers))
-        return 0;
-
-    elements = VTABLE_elements(interp, handlers);
-
-    if (STRING_IS_NULL(handler_type) || STRING_IS_EMPTY(handler_type))
-        return elements;
-
-    /* Loop from newest handler to oldest handler. */
-    {
-        STRING      *exception_str = CONST_STRING(interp, "exception");
-        STRING      *event_str     = CONST_STRING(interp, "event");
-        STRING      *handler_str   = CONST_STRING(interp, "ExceptionHandler");
-        INTVAL       count = 0;
-        INTVAL       index;
-        typedef enum { Hunknown,  Hexception, Hevent } Htype;
-
-        const Htype htype =
-            (Parrot_str_equal(interp, handler_type, exception_str)) ?
-            Hexception :
-            (Parrot_str_equal(interp, handler_type, event_str)) ?
-                Hevent :
-                Hunknown;
-        STRING * const handler_name = (htype == Hexception) ? handler_str : (STRING *)NULL;
-
-        for (index = 0; index < elements; ++index) {
-            PMC * const handler = VTABLE_get_pmc_keyed_int(interp, handlers, index);
-            if (!PMC_IS_NULL(handler)) {
-                switch (htype) {
-                  case Hexception:
-                    if (VTABLE_isa(interp, handler, handler_name))
-                        ++count;
-                    break;
-                  case Hevent:
-                    if (handler->vtable->base_type == enum_class_EventHandler)
-                        ++count;
-                    break;
-                  default:
-                    break;
-                }
-            }
-        }
-        return count;
-    }
-}
-
-
-/*
-
-=item C<void Parrot_cx_add_handler(PARROT_INTERP, PMC *handler)>
-
-Add a task handler to scheduler's list of handlers.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_cx_add_handler(PARROT_INTERP, ARGIN(PMC *handler))
-{
-    ASSERT_ARGS(Parrot_cx_add_handler)
-    STRING * const add_handler = CONST_STRING(interp, "add_handler");
-    if (!interp->scheduler)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Scheduler was not initialized for this interpreter.\n");
-
-    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, add_handler, "P->", handler);
-}
-
-/*
-
-=item C<void Parrot_cx_delete_handler_typed(PARROT_INTERP, STRING
-*handler_type)>
-
-Remove the top task handler of a particular type from the scheduler's list of
-handlers.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-void
-Parrot_cx_delete_handler_typed(PARROT_INTERP, ARGIN(STRING *handler_type))
-{
-    ASSERT_ARGS(Parrot_cx_delete_handler_typed)
-    if (!interp->scheduler)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Scheduler was not initialized for this interpreter.\n");
-
-    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, CONST_STRING(interp, "delete_handler"), "S->", handler_type);
-}
-
-/*
-
-=item C<INTVAL Parrot_cx_count_handlers_typed(PARROT_INTERP, STRING
-*handler_type)>
-
-Count the number of active handlers of a particular type (event, exception) in
-the concurrency scheduler.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-INTVAL
-Parrot_cx_count_handlers_typed(PARROT_INTERP, ARGIN(STRING *handler_type))
-{
-    ASSERT_ARGS(Parrot_cx_count_handlers_typed)
-    INTVAL count = 0;
-
-    if (!interp->scheduler)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Scheduler was not initialized for this interpreter.\n");
-
-    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, CONST_STRING(interp, "count_handlers"), "S->I", handler_type, &count);
-
-    return count;
-}
-
-/*
-
 =back
 
 =head2 Scheduler Message Interface Functions
@@ -802,155 +567,6 @@
 
 /*
 
-=back
-
-=head2 Task Interface Functions
-
-Functions that are used to interface with a specific task in the concurrency scheduler.
-
-=over 4
-
-=item C<PMC * Parrot_cx_find_handler_for_task(PARROT_INTERP, PMC *task)>
-
-Retrieve a handler appropriate to a given task. If the scheduler has no
-appropriate handler, returns PMCNULL.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-PMC *
-Parrot_cx_find_handler_for_task(PARROT_INTERP, ARGIN(PMC *task))
-{
-    ASSERT_ARGS(Parrot_cx_find_handler_for_task)
-    PMC *handler = PMCNULL;
-#if CX_DEBUG
-    fprintf(stderr, "searching for handler\n");
-#endif
-
-    if (!interp->scheduler)
-        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
-            "Scheduler was not initialized for this interpreter.\n");
-
-    Parrot_pcc_invoke_method_from_c_args(interp, interp->scheduler, CONST_STRING(interp, "find_handler"), "P->P", task, &handler);
-
-#if CX_DEBUG
-    fprintf(stderr, "done searching for handler\n");
-#endif
-
-    return handler;
-}
-
-/*
-
-=item C<PMC * Parrot_cx_find_handler_local(PARROT_INTERP, PMC *task)>
-
-Retrieve a handler appropriate to a given task from the local context. If the
-context has no appropriate handler, returns PMCNULL.
-
-=cut
-
-*/
-
-PARROT_EXPORT
-PARROT_CAN_RETURN_NULL
-PMC *
-Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
-{
-    ASSERT_ARGS(Parrot_cx_find_handler_local)
-
-    /*
-     * Quick&dirty way to avoid infinite recursion
-     * when an exception is thrown while looking
-     * for a handler
-     */
-    static int already_doing = 0;
-    static PMC * keep_context = NULL;
-
-    PMC            *context;
-    PMC            *iter        = PMCNULL;
-    STRING * const  handled_str = CONST_STRING(interp, "handled");
-    STRING * const  iter_str    = CONST_STRING(interp, "handler_iter");
-
-    if (already_doing) {
-        Parrot_io_eprintf(interp,
-            "** Exception caught while looking for a handler, trying next **\n");
-        if (! keep_context)
-            return NULL;
-        /*
-         * Note that we are now trying to handle the new exception,
-         * not the initial task argument (exception or whatever).
-         */
-        context = Parrot_pcc_get_caller_ctx(interp, keep_context);
-        keep_context = NULL;
-        if (context && !PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
-            iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
-        else
-            iter = PMCNULL;
-    }
-    else {
-        ++already_doing;
-
-        /* Exceptions store the handler iterator for rethrow, other kinds of
-         * tasks don't (though they could). */
-        if (task->vtable->base_type == enum_class_Exception
-        && VTABLE_get_integer_keyed_str(interp, task, handled_str) == -1) {
-            iter    = VTABLE_get_attr_str(interp, task, iter_str);
-            context = (PMC *)VTABLE_get_pointer(interp, task);
-        }
-        else {
-            context = CURRENT_CONTEXT(interp);
-            if (!PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
-                iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
-        }
-    }
-
-    while (context) {
-        keep_context = context;
-        /* Loop from newest handler to oldest handler. */
-        while (!PMC_IS_NULL(iter) && VTABLE_get_bool(interp, iter)) {
-            PMC * const handler = VTABLE_shift_pmc(interp, iter);
-
-            if (!PMC_IS_NULL(handler)) {
-                INTVAL valid_handler = 0;
-                if (handler->vtable->base_type == enum_class_Object)
-                    Parrot_pcc_invoke_method_from_c_args(interp, handler, CONST_STRING(interp, "can_handle"),
-                        "P->I", task, &valid_handler);
-                else
-                    Parrot_pcc_invoke_method_from_c_args(interp, handler, CONST_STRING(interp, "can_handle"),
-                        "P->I", task, &valid_handler);
-
-                if (valid_handler) {
-                    if (task->vtable->base_type == enum_class_Exception) {
-                        /* Store iterator and context for a later rethrow. */
-                        VTABLE_set_attr_str(interp, task, CONST_STRING(interp, "handler_iter"), iter);
-                        VTABLE_set_pointer(interp, task, context);
-                    }
-                    --already_doing;
-                    keep_context = NULL;
-                    return handler;
-                }
-            }
-        }
-
-        /* Continue the search in the next context up the chain. */
-        context = Parrot_pcc_get_caller_ctx(interp, context);
-        if (context && !PMC_IS_NULL(Parrot_pcc_get_handlers(interp, context)))
-            iter = VTABLE_get_iter(interp, Parrot_pcc_get_handlers(interp, context));
-        else
-            iter = PMCNULL;
-    }
-
-    /* Reached the end of the context chain without finding a handler. */
-
-    --already_doing;
-    return PMCNULL;
-}
-
-/*
-
 =item C<void Parrot_cx_schedule_alarm(PARROT_INTERP, PMC *alarm)>
 
 Schedule an alarm.

Modified: branches/gsoc_threads/t/native_pbc/annotations.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: branches/gsoc_threads/t/native_pbc/integer.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: branches/gsoc_threads/t/native_pbc/number.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Modified: branches/gsoc_threads/t/native_pbc/string.pbc
==============================================================================
Binary file (source and/or target). No diff available.

Copied and modified: branches/gsoc_threads/t/pmc/event.t (from r48070, branches/gsoc_threads/t/pmc/task.t)
==============================================================================
--- branches/gsoc_threads/t/pmc/task.t	Sun Jul 11 03:48:25 2010	(r48070, copy source)
+++ branches/gsoc_threads/t/pmc/event.t	Thu Jul 15 04:48:04 2010	(r48093)
@@ -10,21 +10,21 @@
 
 =head1 NAME
 
-t/pmc/task.t - Concurrent Task
+t/pmc/event.t - Concurrent Event
 
 =head1 SYNOPSIS
 
-    % prove t/pmc/task.t
+    % prove t/pmc/event.t
 
 =head1 DESCRIPTION
 
-Tests the task PMC used by the concurrency scheduler.
+Tests the event PMC used by the concurrency scheduler.
 
 =cut
 
-pir_output_is( <<'CODE', <<'OUT', "create a task and set attributes" );
+pir_output_is( <<'CODE', <<'OUT', "create an event and set attributes" );
   .sub main :main
-    $P0 = new ['Task']
+    $P0 = new ['Event']
     $P1 = getattribute $P0, 'status'
     print $P1
     print "\n"
@@ -79,7 +79,7 @@
 1.1
 OUT
 
-pir_output_is( <<'CODE', <<'OUT', 'create a task and set attributes in init' );
+pir_output_is( <<'CODE', <<'OUT', 'create an event and set attributes in init' );
   .sub main :main
     .local pmc data
     data = new ['Hash']
@@ -104,7 +104,7 @@
     $P2 = 1.1
     data['birthtime'] = $P2
 
-    $P0 = new ['Task'], data
+    $P0 = new ['Event'], data
 
     $P3 = getattribute $P0, 'status'
     say $P3
@@ -130,9 +130,9 @@
 1.1
 OUT
 
-pir_output_is( <<'CODE', <<'OUT', "freeze and thaw a task" );
+pir_output_is( <<'CODE', <<'OUT', "freeze and thaw an event" );
   .sub main :main
-    $P0 = new ['Task']
+    $P0 = new ['Event']
 
     $P2 = new ['String']
     $P2 = "inprocess"

Deleted: branches/gsoc_threads/t/pmc/task.t
==============================================================================
--- branches/gsoc_threads/t/pmc/task.t	Thu Jul 15 04:48:04 2010	(r48092)
+++ /dev/null	00:00:00 1970	(deleted)
@@ -1,194 +0,0 @@
-#! perl
-# Copyright (C) 2007, Parrot Foundation.
-# $Id$
-
-use strict;
-use warnings;
-use lib qw( . lib ../lib ../../lib );
-use Test::More;
-use Parrot::Test tests => 3;
-
-=head1 NAME
-
-t/pmc/task.t - Concurrent Task
-
-=head1 SYNOPSIS
-
-    % prove t/pmc/task.t
-
-=head1 DESCRIPTION
-
-Tests the task PMC used by the concurrency scheduler.
-
-=cut
-
-pir_output_is( <<'CODE', <<'OUT', "create a task and set attributes" );
-  .sub main :main
-    $P0 = new ['Task']
-    $P1 = getattribute $P0, 'status'
-    print $P1
-    print "\n"
-
-    $P2 = new ['String']
-    $P2 = "inprocess"
-    setattribute $P0, 'status', $P2
-
-    $P3 = getattribute $P0, 'status'
-    print $P3
-    print "\n"
-
-    $P2 = new ['String']
-    $P2 = "event"
-    setattribute $P0, 'type', $P2
-
-    $P3 = getattribute $P0, 'type'
-    print $P3
-    print "\n"
-
-    $P2 = new ['Integer']
-    $P2 = 10
-    setattribute $P0, 'priority', $P2
-
-    $P3 = getattribute $P0, 'priority'
-    print $P3
-    print "\n"
-
-    $P2 = new ['Integer']
-    $P2 = 7405
-    setattribute $P0, 'id', $P2
-
-    $P3 = getattribute $P0, 'id'
-    print $P3
-    print "\n"
-
-    $P2 = new ['Float']
-    $P2 = 1.1
-    setattribute $P0, 'birthtime', $P2
-
-    $P3 = getattribute $P0, 'birthtime'
-    print $P3
-    print "\n"
-    end
-  .end
-CODE
-created
-inprocess
-event
-10
-7405
-1.1
-OUT
-
-pir_output_is( <<'CODE', <<'OUT', 'create a task and set attributes in init' );
-  .sub main :main
-    .local pmc data
-    data = new ['Hash']
-
-    $P2 = new ['String']
-    $P2 = 'inprocess'
-    data['status'] = $P2
-
-    $P2 = new ['String']
-    $P2 = 'event'
-    data['type'] = $P2
-
-    $P2 = new ['Integer']
-    $P2 = 10
-    data['priority'] = $P2
-
-    $P2 = new ['Integer']
-    $P2 = 7405
-    data['id'] = $P2
-
-    $P2 = new ['Float']
-    $P2 = 1.1
-    data['birthtime'] = $P2
-
-    $P0 = new ['Task'], data
-
-    $P3 = getattribute $P0, 'status'
-    say $P3
-
-    $P3 = getattribute $P0, 'type'
-    say $P3
-
-    $P3 = getattribute $P0, 'priority'
-    say $P3
-
-    $P3 = getattribute $P0, 'id'
-    say $P3
-
-    $P3 = getattribute $P0, 'birthtime'
-    say $P3
-    end
-  .end
-CODE
-inprocess
-event
-10
-7405
-1.1
-OUT
-
-pir_output_is( <<'CODE', <<'OUT', "freeze and thaw a task" );
-  .sub main :main
-    $P0 = new ['Task']
-
-    $P2 = new ['String']
-    $P2 = "inprocess"
-    setattribute $P0, 'status', $P2
-
-    $P2 = new ['String']
-    $P2 = "event"
-    setattribute $P0, 'type', $P2
-
-    $P2 = new ['Integer']
-    $P2 = 10
-    setattribute $P0, 'priority', $P2
-
-    $P2 = new ['Integer']
-    $P2 = 7405
-    setattribute $P0, 'id', $P2
-
-    $P2 = new ['Float']
-    $P2 = 1.1
-    setattribute $P0, 'birthtime', $P2
-
-    $S0  = freeze $P0
-    $P10 = thaw $S0
-
-    $P3 = getattribute $P10, 'status'
-    print $P3
-    print "\n"
-
-    $P3 = getattribute $P10, 'type'
-    print $P3
-    print "\n"
-
-    $P3 = getattribute $P10, 'priority'
-    print $P3
-    print "\n"
-
-    $P3 = getattribute $P10, 'id'
-    print $P3
-    print "\n"
-
-    $P3 = getattribute $P10, 'birthtime'
-    print $P3
-    print "\n"
-    end
-  .end
-CODE
-inprocess
-event
-10
-7405
-1.1
-OUT
-
-# Local Variables:
-#   mode: cperl
-#   cperl-indent-level: 4
-#   fill-column: 100
-# End:
-# vim: expandtab shiftwidth=4:

Modified: branches/gsoc_threads/t/pmc/timer.t
==============================================================================
--- branches/gsoc_threads/t/pmc/timer.t	Thu Jul 15 00:44:40 2010	(r48092)
+++ branches/gsoc_threads/t/pmc/timer.t	Thu Jul 15 04:48:04 2010	(r48093)
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 6;
+use Parrot::Test tests => 5;
 use Parrot::Config;
 
 =head1 NAME
@@ -177,29 +177,6 @@
 OUT
 }
 
-pir_output_is( << 'CODE', << 'OUTPUT', "check whether interface is done" );
-
-.sub _main
-    .local pmc pmc1
-    pmc1 = new ['Timer']
-    .local int bool1
-    does bool1, pmc1, "scalar"
-    print bool1
-    print "\n"
-    does bool1, pmc1, "event"
-    print bool1
-    print "\n"
-    does bool1, pmc1, "no_interface"
-    print bool1
-    print "\n"
-    end
-.end
-CODE
-0
-1
-0
-OUTPUT
-
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4


More information about the parrot-commits mailing list