-
Notifications
You must be signed in to change notification settings - Fork 138
/
alarm.pmc
230 lines (151 loc) · 4.51 KB
/
alarm.pmc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
src/pmc/alarm.pmc - Alarm PMC
=head1 SYNOPSIS
.include 'alarm.pasm'
new P0, 'Alarm'
set P0[.PARROT_ALARM_TIME], N_time # A FLOATVAL
set P0[.PARROT_ALARM_SUB], P_sub # set handler sub PMC
invoke P0 # schedule the alarm
=head1 DESCRIPTION
Sometime after N_time, P_sub will be called exactly once. Notice that due to
various factors, the alarm is not guaranteed to execute at N_time, but only
a short time thereafter. The length of "a short time" is very system dependent.
=head2 Functions
=over 4
=cut
*/
#include "parrot/scheduler_private.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass Alarm provides invokable auto_attrs {
ATTR FLOATVAL alarm_time; /* The time when the alarm should trigger */
ATTR PMC *alarm_task; /* The Task or Sub PMC to execute */
/*
=item C<void init()>
Initializes the alarm.
=cut
*/
VTABLE void init() {
Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
data->alarm_time = 0.0;
data->alarm_task = PMCNULL;
PObj_custom_mark_SET(SELF);
}
/*
=item C<PMC *clone()>
Create a copy of the alarm.
=cut
*/
VTABLE PMC *clone() :no_wb {
PMC * const copy = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
Parrot_Alarm_attributes * const new_struct = PARROT_ALARM(copy);
Parrot_Alarm_attributes * const old_struct = PARROT_ALARM(SELF);
new_struct->alarm_time = old_struct->alarm_time;
new_struct->alarm_task = old_struct->alarm_task;
return copy;
}
/*
=item C<PMC *get_pmc_keyed_int(INTVAL key)>
Returns the PMC associated with C<key>.
=cut
*/
VTABLE PMC *get_pmc_keyed_int(INTVAL key) :no_wb {
switch (key) {
case PARROT_ALARM_TASK:
return PARROT_ALARM(SELF)->alarm_task;
case PARROT_ALARM_TIME: {
PMC * const floatval = Parrot_pmc_new(INTERP, enum_class_Float);
VTABLE_set_number_native(INTERP, floatval, PARROT_ALARM(SELF)->alarm_time);
return floatval;
}
default:
return PMCNULL;
}
}
/*
=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
Returns the number associated with C<key>.
=cut
*/
VTABLE FLOATVAL get_number_keyed_int(INTVAL key) :no_wb {
UNUSED(INTERP)
if (key == PARROT_ALARM_TIME)
return PARROT_ALARM(SELF)->alarm_time;
return 0.0;
}
/*
=item C<FLOATVAL get_number()>
Having the alarm numify to the time is convienient for sorting.
=cut
*/
VTABLE FLOATVAL get_number() :no_wb {
UNUSED(INTERP)
return PARROT_ALARM(SELF)->alarm_time;
}
/*
=item C<void set_pmc_keyed_int(INTVAL key, PMC *value)>
Sets the PMC associated with C<key> to C<*value>.
=cut
*/
VTABLE void set_pmc_keyed_int(INTVAL key, PMC *value) :manual_wb {
if (key == PARROT_ALARM_TASK) {
SET_ATTR_alarm_task(INTERP, SELF, value);
PARROT_GC_WRITE_BARRIER(INTERP, SELF);
}
}
/*
=item C<opcode_t *invoke(void *next)>
Schedules the alarm and adds it to the alarm queue.
=cut
*/
VTABLE opcode_t *invoke(void *next) :no_wb {
Parrot_cx_schedule_alarm(INTERP, SELF);
return (opcode_t *)next;
}
/*
=item C<void set_number_keyed_int(INTVAL key, FLOATVAL value)>
Sets the floating-point value associated with C<key> to C<value>.
=cut
*/
VTABLE void set_number_keyed_int(INTVAL key, FLOATVAL value) :manual_wb {
if (key == PARROT_ALARM_TIME) {
SET_ATTR_alarm_time(INTERP, SELF, value);
PARROT_GC_WRITE_BARRIER(INTERP, SELF);
}
}
/*
Required functions for GC and Freeze / Thaw.
*/
VTABLE void mark() :no_wb {
PMC *sub;
GET_ATTR_alarm_task(INTERP, SELF, sub);
Parrot_gc_mark_PMC_alive(INTERP, sub);
}
VTABLE void visit(PMC *info) :no_wb {
PMC *sub;
GET_ATTR_alarm_task(INTERP, SELF, sub);
VISIT_PMC(INTERP, info, sub);
SUPER(info);
}
VTABLE void freeze(PMC *info) :no_wb {
SUPER(info);
VTABLE_push_integer(INTERP, info, VTABLE_elements(INTERP, SELF));
}
VTABLE void thaw(PMC *info) :manual_wb {
SUPER(info);
SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
}
}
/*
=back
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/