2 Copyright (C) 2001-2008, Parrot Foundation.
7 src/pmc/timer.pmc - Timer
12 set P0[.PARROT_TIMER_SEC], I_seconds # whole seconds
13 set P0[.PARROT_TIMER_USEC], I_micro seconds # and/or micro seconds
14 set P0[.PARROT_TIMER_NSEC], N_seconds_frac # or fraction in seconds
15 set P0[.PARROT_TIMER_REPEAT], I_repeat # 0 = one shot ...
16 set P0[.PARROT_TIMER_HANDLER], P_sub # set handler sub PMC
17 invoke P0 # start timer
18 set P0[.PARROT_TIMER_RUNNING], 1 # same
20 new P0, 'Timer', P1 # set everything
22 set I0, P0[.PARROT_TIMER_SEC] # query current timer status
23 set N0, P0[.PARROT_TIMER_NSEC]
25 set P0[.PARROT_TIMER_RUNNING], 0 # turn timer off
30 This is the Timer base class
32 Running timers are kept in a linked list. Each timer has a tick count,
33 which gets decremented if the system timer expires. If the tick count
34 reaches zero, the timer handler gets invoked via Parrot's event handling
37 The Timer resolution is operating system dependent. It's only guaranteed
38 that the Timer will fire some time after the programmed interval.
40 The Timer stops after invoking the handler (repeat + 1) times. To create a
41 Timer that will run forever, set "repeat" to -1. Turning the Timer off
42 preserves set values; the Timer is not destroyed.
44 When setting both C<PARROT_TIMER_SEC> and C<PARROT_TIMER_USEC> it must
45 be done in that sequence, whole seconds first. If a timer is constructed
46 with an initializer and it should be run immediately, the
47 C<PARROT_TIMER_RUNNING> value has to be in the last key of the
58 #include "parrot/scheduler_private.h"
60 pmclass Timer extends Task provides event auto_attrs {
61 ATTR FLOATVAL duration; /* The duration of the timer pause */
62 ATTR FLOATVAL interval; /* How often to repeat */
63 ATTR INTVAL repeat; /* Whether to repeat:
64 * 0 = run once (no repeat), -1 = forever */
70 Initializes the timer.
77 Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
79 /* Set flags for custom GC mark and destroy. */
80 PObj_custom_mark_SET(SELF);
81 PObj_custom_destroy_SET(SELF);
83 /* Set up the core struct. */
85 core_struct->type = CONST_STRING(interp, "timer");
86 core_struct->subtype = CONST_STRING(interp, "");
87 core_struct->priority = 0;
88 core_struct->status = CONST_STRING(interp, "created");
89 core_struct->birthtime = 0.0;
90 core_struct->codeblock = PMCNULL;
91 core_struct->interp = INTERP;
92 core_struct->duration = 0.0;
93 core_struct->interval = 0.0;
94 core_struct->repeat = 0;
96 /* Make sure the flag is cleared by default */
97 TASK_terminate_runloop_CLEAR(SELF);
102 =item C<void init_pmc(PMC *init)>
104 See F<docs/pdds/pdd02_vtables.pod> for initializers.
110 VTABLE void init_pmc(PMC *init) {
111 const INTVAL n = VTABLE_get_integer(INTERP, init);
116 for (i = 0; i < n; i += 2) {
117 const INTVAL key = VTABLE_get_integer_keyed_int(INTERP, init, i);
119 case PARROT_TIMER_SEC:
120 case PARROT_TIMER_USEC:
121 case PARROT_TIMER_REPEAT:
122 case PARROT_TIMER_RUNNING:
124 const INTVAL val = VTABLE_get_integer_keyed_int(INTERP, init, i+1);
125 SELF.set_integer_keyed_int(key, val);
128 case PARROT_TIMER_NSEC:
130 const FLOATVAL nval = VTABLE_get_number_keyed_int(INTERP, init, i+1);
131 SELF.set_number_keyed_int(key, nval);
134 case PARROT_TIMER_HANDLER:
136 PMC * const pval = VTABLE_get_pmc_keyed_int(INTERP, init, i+1);
137 SELF.set_pmc_keyed_int(key, pval);
148 =item C<PMC *clone()>
150 Create a copy of the timer, resetting status, id, and birthtime.
156 VTABLE PMC *clone() {
157 PMC * const copy = SUPER();
158 Parrot_Timer_attributes * const new_struct = PARROT_TIMER(copy);
159 Parrot_Timer_attributes * const old_struct = PARROT_TIMER(SELF);
161 new_struct->duration = old_struct->duration;
162 new_struct->interval = old_struct->interval;
163 new_struct->repeat = old_struct->repeat;
170 =item C<void destroy()>
178 VTABLE void destroy() {
179 Parrot_cx_delete_task(INTERP, SELF);
184 =item C<INTVAL get_integer_keyed_int(INTVAL key)>
186 Returns the timer info for C<key>.
192 VTABLE INTVAL get_integer_keyed_int(INTVAL key) {
193 Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
194 const FLOATVAL absolute_time = core_struct->birthtime + core_struct->duration;
197 case PARROT_TIMER_SEC:
198 return (INTVAL)absolute_time;
199 case PARROT_TIMER_USEC:
200 return (INTVAL)((absolute_time - (INTVAL)absolute_time) *1000000.0);
201 case PARROT_TIMER_REPEAT:
202 return (INTVAL) core_struct->repeat;
203 case PARROT_TIMER_INTERVAL:
204 return (INTVAL) core_struct->interval;
205 case PARROT_TIMER_RUNNING:
214 =item C<PMC *get_pmc_keyed_int(INTVAL key)>
216 Returns the PMC associated with C<key>.
222 VTABLE PMC *get_pmc_keyed_int(INTVAL key) {
223 if (key == PARROT_TIMER_HANDLER) {
224 const Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
225 return core_struct->codeblock;
233 =item C<FLOATVAL get_number_keyed_int(INTVAL key)>
235 Returns the number associated with C<key>.
241 VTABLE FLOATVAL get_number_keyed_int(INTVAL key) {
242 Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
245 case PARROT_TIMER_NSEC:
246 return core_struct->birthtime + core_struct->duration;
247 case PARROT_TIMER_INTERVAL:
248 return core_struct->interval;
258 =item C<void set_integer_keyed_int(INTVAL key, INTVAL value)>
260 Sets the value associated with C<key> to C<value>.
266 VTABLE void set_integer_keyed_int(INTVAL key, INTVAL value) {
267 Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
270 case PARROT_TIMER_SEC:
271 core_struct->duration = value;
273 case PARROT_TIMER_USEC:
274 core_struct->duration += value / 1000000.0;
276 case PARROT_TIMER_REPEAT:
277 core_struct->repeat = value;
279 case PARROT_TIMER_INTERVAL:
280 core_struct->interval = value;
282 case PARROT_TIMER_RUNNING:
284 Parrot_cx_schedule_task(INTERP, SELF);
286 Parrot_cx_delete_task(INTERP, SELF);
289 Parrot_ex_throw_from_c_args(INTERP, NULL,
290 EXCEPTION_INVALID_OPERATION,
291 "Unknown timer type in Timer.set_integer_keyed_int: %d",
298 =item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
300 Sets the PMC associated with C<key> to C<*value>.
306 VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) {
307 if (key == PARROT_TIMER_HANDLER) {
309 Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
310 core_struct->codeblock = value;
312 SET_ATTR_codeblock(interp, SELF, value);
318 =item C<opcode_t *invoke(void *next)>
320 Adds the timer to the event queue.
326 VTABLE opcode_t *invoke(void *next) {
327 Parrot_cx_schedule_task(INTERP, SELF);
328 return (opcode_t *)next;
333 =item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
335 Sets the floating-point value associated with C<key> to C<value>.
341 VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) {
342 Parrot_Timer_attributes * const core_struct = PARROT_TIMER(SELF);
345 case PARROT_TIMER_NSEC:
346 core_struct->duration = value;
348 case PARROT_TIMER_INTERVAL:
349 core_struct->interval = value;
352 Parrot_ex_throw_from_c_args(INTERP, NULL,
353 EXCEPTION_INVALID_OPERATION,
354 "Unknown timer attribute in Timer.set_number_keyed_int: %d",
370 * c-file-style: "parrot"
372 * vim: expandtab shiftwidth=4: