[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