2 Copyright (C) 2001-2007, The Perl Foundation.
7 src/pmc/task.pmc - A concurrent task
11 Implements the basic task behavior for the concurrency scheduler.
21 #include "parrot/parrot.h"
22 #include "parrot/scheduler_private.h"
24 pmclass Task need_ext {
25 ATTR INTVAL id; /* The task ID. */
26 ATTR INTVAL priority; /* The priority of the task. */
27 ATTR FLOATVAL birthtime; /* The creation time stamp of the task. */
28 ATTR STRING *type; /* The type of the task. */
29 ATTR STRING *subtype; /* The subtype of the task. */
30 ATTR STRING *status; /* The status of the task. */
31 ATTR Parrot_Interp interp; /* The interpreter that created the task. */
32 ATTR PMC *codeblock; /* An (optional) codeblock for the task. */
33 ATTR PMC *data; /* Additional data for the task. */
34 ATTR char *cb_data; /* Additional data for a callback event. */
40 Initialize a concurrency task object.
47 Parrot_Task * const core_struct = mem_allocate_zeroed_typed(Parrot_Task);
49 /* Set flags for custom DOD mark and destroy. */
50 PObj_custom_mark_SET(SELF);
51 PObj_active_destroy_SET(SELF);
53 /* Set up the core struct. */
54 PMC_data(SELF) = core_struct;
56 core_struct->type = CONST_STRING(interp, "");
57 core_struct->subtype = CONST_STRING(interp, "");
58 core_struct->priority = 0;
59 core_struct->status = CONST_STRING(interp, "created");
60 core_struct->birthtime = 0.0;
61 core_struct->codeblock = PMCNULL;
62 core_struct->data = PMCNULL;
63 core_struct->interp = INTERP;
65 /* Make sure the flag is cleared by default */
66 TASK_terminate_runloop_CLEAR(SELF);
72 =item C<void init_pmc(PMC *data)>
74 Initializes a new Task with a C<Hash> PMC with any or all of the keys:
80 An C<Integer> representing the task's unique identifier.
84 A C<String> representing the type of the task.
88 A C<String> representing the subtype of the task. (Used mostly by events and
89 exceptions to identify appropriate handlers.)
93 An C<Integer> representing the task's priority, from 0 to 100.
97 A C<String> representing the task's status, one of C<created>, C<invoked>,
98 C<inprocess>, or C<completed>.
102 The time at which this Task was inserted into the task list.
106 A C<Sub> or descendent PMC related to this task.
110 An interpreter in which to execute this task.
118 VTABLE void init_pmc(PMC *data) {
120 Parrot_Task *core_struct;
122 if (! VTABLE_isa(INTERP, data, CONST_STRING(INTERP, "Hash")))
123 real_exception(INTERP, NULL, INVALID_OPERATION,
124 "Task initializer must be a Hash");
126 core_struct = mem_allocate_zeroed_typed(Parrot_Task);
128 /* Set flags for custom DOD mark and destroy. */
129 PObj_custom_mark_SET(SELF);
130 PObj_active_destroy_SET(SELF);
132 /* Set up the core struct. */
133 PMC_data(SELF) = core_struct;
135 elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "id"));
136 if (! PMC_IS_NULL(elem))
137 core_struct->id = VTABLE_get_integer(INTERP, elem);
141 elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "type"));
142 if (! PMC_IS_NULL(elem))
143 core_struct->type = VTABLE_get_string(INTERP, elem);
145 core_struct->type = CONST_STRING(INTERP, "");
147 elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "subtype"));
148 if (! PMC_IS_NULL(elem))
149 core_struct->subtype = VTABLE_get_string(INTERP, elem);
151 core_struct->subtype = CONST_STRING(INTERP, "");
153 elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "priority"));
154 if (! PMC_IS_NULL(elem))
155 core_struct->priority = VTABLE_get_integer(INTERP, elem);
157 core_struct->priority = 0;
159 elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "status"));
160 if (! PMC_IS_NULL(elem))
161 core_struct->status = VTABLE_get_string(INTERP, elem);
163 core_struct->status = CONST_STRING(INTERP, "created");
165 elem = VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "birthtime"));
166 if (! PMC_IS_NULL(elem))
167 core_struct->birthtime = VTABLE_get_number(INTERP, elem);
169 core_struct->birthtime = 0.0;
171 core_struct->codeblock =
172 VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "code"));
173 core_struct->interp = (Parrot_Interp)
174 VTABLE_get_pmc_keyed_str(INTERP, data, CONST_STRING(INTERP, "data"));
179 =item C<PMC *clone()>
181 Create a copy of the task, resetting status, ID, and birthtime.
187 VTABLE PMC *clone() {
188 /* Create the new task PMC, of the same type of this one (we may
189 * have been subclassed). */
190 PMC * const copy = pmc_new(interp, SELF->vtable->base_type);
191 Parrot_Task * const new_struct = PARROT_TASK(copy);
192 Parrot_Task * const old_struct = PARROT_TASK(SELF);
194 new_struct->codeblock = VTABLE_clone(interp, old_struct->codeblock);
195 new_struct->data = old_struct->data;
196 new_struct->type = old_struct->type;
197 new_struct->subtype = old_struct->subtype;
198 new_struct->priority = old_struct->priority;
204 =item C<PMC *get_attr_str(STRING *name)>
206 Gets the value of an attribute for this task.
211 VTABLE PMC *get_attr_str(STRING *name) {
212 Parrot_Task * const core_struct = PARROT_TASK(SELF);
215 if (string_equal(interp, name, CONST_STRING(interp, "id")) == 0) {
216 value = pmc_new(interp, enum_class_Integer);
217 VTABLE_set_integer_native(interp, value, core_struct->id);
219 else if (string_equal(interp, name, CONST_STRING(interp, "type")) == 0) {
220 value = pmc_new(interp, enum_class_String);
221 VTABLE_set_string_native(interp, value, core_struct->type);
223 else if (string_equal(interp, name, CONST_STRING(interp, "subtype")) == 0) {
224 value = pmc_new(interp, enum_class_String);
225 VTABLE_set_string_native(interp, value, core_struct->subtype);
227 else if (string_equal(interp, name, CONST_STRING(interp, "priority")) == 0) {
228 value = pmc_new(interp, enum_class_Integer);
229 VTABLE_set_integer_native(interp, value, core_struct->priority);
231 else if (string_equal(interp, name, CONST_STRING(interp, "status")) == 0) {
232 value = pmc_new(interp, enum_class_String);
233 VTABLE_set_string_native(interp, value, core_struct->status);
235 else if (string_equal(interp, name, CONST_STRING(interp, "birthtime")) == 0) {
236 value = pmc_new(interp, enum_class_Float);
237 VTABLE_set_number_native(interp, value, core_struct->birthtime);
248 =item C<void set_attr_str(STRING *name, PMC *value)>
250 Sets the value of an attribute for this task.
255 VTABLE void set_attr_str(STRING *name, PMC *value) {
256 Parrot_Task * const core_struct = PARROT_TASK(SELF);
258 if (string_equal(interp, name, CONST_STRING(interp, "id")) == 0) {
259 core_struct->id = VTABLE_get_integer(interp, value);
261 else if (string_equal(interp, name, CONST_STRING(interp, "type")) == 0) {
262 core_struct->type = VTABLE_get_string(interp, value);
264 else if (string_equal(interp, name, CONST_STRING(interp, "subtype")) == 0) {
265 core_struct->subtype = VTABLE_get_string(interp, value);
267 else if (string_equal(interp, name, CONST_STRING(interp, "priority")) == 0) {
268 core_struct->priority = VTABLE_get_integer(interp, value);
270 else if (string_equal(interp, name, CONST_STRING(interp, "status")) == 0) {
271 core_struct->status = VTABLE_get_string(interp, value);
273 else if (string_equal(interp, name, CONST_STRING(interp, "birthtime")) == 0) {
274 core_struct->birthtime = VTABLE_get_number(interp, value);
276 else if (string_equal(interp, name, CONST_STRING(interp, "code")) == 0) {
277 core_struct->codeblock = value;
279 else if (string_equal(interp, name, CONST_STRING(interp, "data")) == 0) {
280 core_struct->data = value;
286 =item C<INTVAL get_integer()>
288 Retrieves the task ID for this task.
293 VTABLE INTVAL get_integer() {
294 const Parrot_Task * const core_struct = PARROT_TASK(SELF);
295 return core_struct->id;
300 =item C<void set_integer_native(INTVAL value)>
302 Sets the task ID of the task.
308 VTABLE void set_integer_native(INTVAL value) {
309 Parrot_Task * const core_struct = PARROT_TASK(SELF);
310 core_struct->id = value;
315 =item C<void set_number_native(FLOATVAL value)>
317 Sets the birthtime of the task.
323 VTABLE void set_number_native(FLOATVAL value) {
324 Parrot_Task * const core_struct = PARROT_TASK(SELF);
325 core_struct->birthtime = value;
330 =item C<void set_string_native(STRING *value)>
332 Sets the type of the task.
338 VTABLE void set_string_native(STRING *value) {
339 Parrot_Task * const core_struct = PARROT_TASK(SELF);
340 core_struct->type = value;
345 =item C<PMC *share_ro()>
347 Set this PMC as shared.
353 VTABLE PMC *share_ro() {
355 Parrot_Task *shared_struct;
357 if (PObj_is_PMC_shared_TEST(SELF))
360 shared_self = pt_shared_fixup(INTERP, SELF);
361 shared_struct = PARROT_TASK(shared_self);
363 if (!PMC_IS_NULL(shared_struct->codeblock))
364 shared_struct->codeblock = pt_shared_fixup(INTERP, shared_struct->codeblock);
366 if (!PMC_IS_NULL(shared_struct->data))
367 shared_struct->data = pt_shared_fixup(INTERP, shared_struct->data);
374 =item C<void destroy()>
376 Free the task's underlying struct.
381 VTABLE void destroy() {
382 mem_sys_free(PMC_data(SELF));
389 Mark any referenced strings and PMCs.
395 if (PARROT_TASK(SELF)) {
396 Parrot_Task * const core_struct = PARROT_TASK(SELF);
398 if (core_struct->codeblock)
399 pobject_lives(interp, (PObj*)core_struct->codeblock);
400 if (core_struct->data)
401 pobject_lives(interp, (PObj*)core_struct->data);
407 =item C<void visit(visit_info *info)>
409 This is used by freeze/thaw to visit the contents of the task.
411 C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
417 VTABLE void visit(visit_info *info) {
418 Parrot_Task * const core_struct = PARROT_TASK(SELF);
421 /* 1) visit code block */
422 pos = &core_struct->codeblock;
423 info->thaw_ptr = pos;
424 (info->visit_pmc_now)(INTERP, *pos, info);
429 =item C<void freeze(visit_info *info)>
431 Used to archive the task.
437 VTABLE void freeze(visit_info *info) {
438 IMAGE_IO * const io = info->image_io;
439 const Parrot_Task * const core_struct = PARROT_TASK(SELF);
441 /* 1) freeze task id */
442 VTABLE_push_integer(INTERP, io, core_struct->id);
444 /* 2) freeze task birthtime */
445 VTABLE_push_float(INTERP, io, core_struct->birthtime);
447 /* 3) freeze task priority */
448 VTABLE_push_integer(INTERP, io, core_struct->priority);
450 /* 4) freeze task type */
451 VTABLE_push_string(INTERP, io, core_struct->type);
453 /* 5) freeze task subtype */
454 VTABLE_push_string(INTERP, io, core_struct->subtype);
456 /* 6) freeze task status */
457 VTABLE_push_string(INTERP, io, core_struct->status);
462 =item C<void thaw(visit_info *info)>
464 Used to unarchive the task.
470 VTABLE void thaw(visit_info *info) {
471 IMAGE_IO * const io = info->image_io;
473 /* 1. thaw task id */
474 const INTVAL id = VTABLE_shift_integer(INTERP, io);
476 /* 2. thaw task birthtime */
477 const FLOATVAL birthtime = VTABLE_shift_float(INTERP, io);
479 /* 3. thaw task priority */
480 const INTVAL priority = VTABLE_shift_integer(INTERP, io);
482 /* 4. thaw task type */
483 STRING * const type = VTABLE_shift_string(INTERP, io);
485 /* 5. thaw task subtype */
486 STRING * const subtype = VTABLE_shift_string(INTERP, io);
488 /* 6. thaw task status */
489 STRING * const status = VTABLE_shift_string(INTERP, io);
491 /* Allocate the task's core data struct and set custom flags. */
494 /* Set the task's id to the frozen id */
495 PARROT_TASK(SELF)->id = id;
497 /* Set the task's birthtime to the frozen birthtime */
498 PARROT_TASK(SELF)->birthtime = birthtime;
500 /* Set the task's type to the frozen type */
501 PARROT_TASK(SELF)->type = type;
503 /* Set the task's subtype to the frozen subtype */
504 PARROT_TASK(SELF)->subtype = subtype;
506 /* Set the task's priority to the frozen priority */
507 PARROT_TASK(SELF)->priority = priority;
509 /* Set the task's status to the frozen status */
510 PARROT_TASK(SELF)->status = status;
516 =item C<void thawfinish(visit_info *info)>
518 Called after the task has been thawed.
524 void thawfinish(visit_info *info) {
525 Parrot_Task * core_struct = PARROT_TASK(SELF);
527 UNUSED(core_struct); /* TODO: Rebuild the task index. */
538 F<docs/pdds/pdd15_objects.pod>.
546 * c-file-style: "parrot"
548 * vim: expandtab shiftwidth=4: