Permalink
Browse files

Progress on alarms / timers.

git-svn-id: https://svn.parrot.org/parrot/branches/gsoc_threads@47926 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
1 parent eb03064 commit fb0dfd8a0afd3b108ac95198e8572ff4cf4f6d26 @NatTuck NatTuck committed Jun 30, 2010
View
@@ -6,27 +6,26 @@ Copyright (C) 2010, Parrot Foundation.
#ifndef PARROT_ALARM_H_GUARD
#define PARROT_ALARM_H_GUARD
-typedef unsigned int Parrot_alarm_state;
-
/* HEADERIZER BEGIN: src/alarm.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
PARROT_EXPORT
-void Parrot_alarm_init(void);
+int Parrot_alarm_check(ARGMOD(UINTVAL* last_serial))
+ __attribute__nonnull__(1)
+ FUNC_MODIFIES(* last_serial);
PARROT_EXPORT
-void Parrot_alarm_set(FLOATVAL when);
+void Parrot_alarm_init(void);
PARROT_EXPORT
-int Parrot_alarm_check(Parrot_alarm_state* last_serial);
+void Parrot_alarm_set(FLOATVAL when);
void Parrot_alarm_callback(NULLOK(int sig_number));
-void Parrot_alarm_set(FLOATVAL wait);
+#define ASSERT_ARGS_Parrot_alarm_check __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(last_serial))
#define ASSERT_ARGS_Parrot_alarm_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_Parrot_alarm_set __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_Parrot_alarm_triggered __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
#define ASSERT_ARGS_Parrot_alarm_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
-#define ASSERT_ARGS_Parrot_alarm_set __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/alarm.c */
@@ -269,6 +269,8 @@ struct parrot_interp_t {
int current_runloop_level; /* for reentering run loop */
int current_runloop_id;
+ UINTVAL last_alarm; /* has an alarm triggered? */
+
struct _Thread_data *thread_data; /* thread specific items */
UINTVAL recursion_limit; /* Sub call resursion limit */
View
@@ -101,6 +101,11 @@ void Parrot_cx_runloop_end(PARROT_INTERP)
__attribute__nonnull__(1);
PARROT_EXPORT
+void Parrot_cx_schedule_alarm(PARROT_INTERP, ARGIN(PMC *alarm))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
+PARROT_EXPORT
void Parrot_cx_schedule_callback(PARROT_INTERP,
ARGIN(PMC *user_data),
ARGIN(char *ext_data))
@@ -216,6 +221,9 @@ void Parrot_cx_timer_invoke(PARROT_INTERP, ARGIN(PMC *timer))
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_Parrot_cx_runloop_end __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_Parrot_cx_schedule_alarm __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(alarm))
#define ASSERT_ARGS_Parrot_cx_schedule_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(user_data) \
@@ -263,10 +271,23 @@ typedef enum {
PARROT_TIMER_INTERVAL,
PARROT_TIMER_RUNNING,
PARROT_TIMER_HANDLER,
- PARROT_TIMER_MAX
+ PARROT_TIMER_MAX,
+ PARROT_ALARM_TIME,
+ PARROT_ALARM_SUB
} parrot_timer_enum_t;
/* &end_gen */
+/* Alarm PMC interface constants */
+/* &gen_from_enum(alarm.pasm) */
+/* TODO: Figure out how to actually gen alarm.pasm
+typedef enum {
+ PARROT_ALARM_TIME,
+ PARROT_ALARM_SUB
+} parrot_alarm_enum_t;
+*/
+/* &end_gen */
+
+
#endif /* PARROT_SCHEDULER_H_GUARD */
View
@@ -13,12 +13,9 @@ src/alarm.c - Implements a mechanism for alarms, setting a flag after a delay.
#include "parrot/alarm_private.h"
#include "parrot/alarm.h"
-/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
-/* HEADERIZER END: src/alarm.c */
-
/* Some per-process state */
static Parrot_alarm_queue* alarm_queue;
-static volatile unsigned int alarm_serial;
+static volatile UINTVAL alarm_serial;
/* This file relies on POSIX. Probably need two other versions of it:
* one for Windows and one for platforms with no signals or threads. */
@@ -28,6 +25,15 @@ static volatile unsigned int alarm_serial;
/* HEADERIZER HFILE: include/parrot/alarm.h */
+/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+static void set_posix_alarm(FLOATVAL wait);
+#define ASSERT_ARGS_set_posix_alarm __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+/* HEADERIZER END: static */
+
+
/*
=head1 Parrot_alarm_init()
@@ -123,7 +129,7 @@ Parrot_alarm_callback(SHIM(int sig_number))
}
/*
-=head1 Parrot_alarm_check(Parrot_alarm_state*)
+=head1 Parrot_alarm_check(UINTVAL*)
Has any alarm triggered since we last checked?
@@ -135,7 +141,7 @@ set the alarm.
PARROT_EXPORT
int
-Parrot_alarm_check(Parrot_alarm_state* last_serial)
+Parrot_alarm_check(ARGMOD(UINTVAL* last_serial))
{
if(*last_serial == alarm_serial) {
return 0;
View
@@ -153,6 +153,7 @@ Branch forward or backward by the amount in $1.
=cut
inline op branch(in LABEL) :base_loop :flow {
+ Parrot_cx_check_tasks(interp, interp->scheduler);
goto OFFSET($1);
}
View
@@ -14231,12 +14231,14 @@ return (opcode_t *)cur_opcode + 2;}
opcode_t *
Parrot_branch_i(opcode_t *cur_opcode, PARROT_INTERP) {
- const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);return (opcode_t *)cur_opcode + IREG(1);
+ const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
+ Parrot_cx_check_tasks(interp, interp->scheduler);return (opcode_t *)cur_opcode + IREG(1);
}
opcode_t *
Parrot_branch_ic(opcode_t *cur_opcode, PARROT_INTERP) {
- const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);return (opcode_t *)cur_opcode + cur_opcode[1];
+ const Parrot_Context * const CUR_CTX = Parrot_pcc_get_context_struct(interp, interp->ctx);
+ Parrot_cx_check_tasks(interp, interp->scheduler);return (opcode_t *)cur_opcode + cur_opcode[1];
}
opcode_t *
@@ -25027,7 +25029,7 @@ static op_lib_t core_op_lib = {
PARROT_FUNCTION_CORE, /* core_type = PARROT_XX_CORE */
0, /* flags */
2, /* major_version */
- 4, /* minor_version */
+ 5, /* minor_version */
0, /* patch_version */
1083, /* op_count */
core_op_info_table, /* op_info_table */
View
@@ -0,0 +1,223 @@
+/*
+Copyright (C) 2001-2008, Parrot Foundation.
+$Id: timer.pmc 47645 2010-06-15 17:35:18Z Chandon $
+
+=head1 NAME
+
+src/pmc/alarm.pmc - Alarm
+
+=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.
+
+=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;
+ ATTR PMC *alarm_sub;
+
+/*
+
+=item C<void init()>
+
+Initializes the alarm.
+
+=cut
+
+*/
+
+ VTABLE void init() {
+ PObj_custom_mark_SET(SELF);
+ }
+
+/*
+
+=item C<PMC *clone()>
+
+Create a copy of the alarm.
+
+=cut
+
+*/
+
+ VTABLE PMC *clone() {
+ PMC *copy = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
+
+ Parrot_Alarm_attributes *new_struct = PARROT_ALARM(copy);
+ Parrot_Alarm_attributes *old_struct = PARROT_ALARM(SELF);
+
+ new_struct->alarm_time = old_struct->alarm_time;
+ new_struct->alarm_sub = old_struct->alarm_sub;
+
+ 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) {
+ if (key == PARROT_ALARM_SUB) {
+ const Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
+ return data->alarm_sub;
+ }
+
+ return PMCNULL;
+ }
+
+/*
+
+=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
+
+Returns the number associated with C<key>.
+
+=cut
+
+*/
+
+ VTABLE FLOATVAL get_pmc_keyed_int(INTVAL key) {
+ if (key == PARROT_ALARM_TIME) {
+ const Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
+ return data->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() {
+ const Parrot_Alarm_attributes * const data = PARROT_ALARM(SELF);
+ return data->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) {
+ if (key == PARROT_ALARM_SUB) {
+ SET_ATTR_alarm_sub(INTERP, SELF, value);
+ }
+ }
+
+/*
+
+=item C<opcode_t *invoke(void *next)>
+
+Schedules the alarm and adds it to the alarm queue.
+
+=cut
+
+*/
+
+ VTABLE opcode_t *invoke(void *next) {
+ 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) {
+ if (key == PARROT_ALARM_TIME) {
+ SET_ATTR_alarm_time(INTERP, SELF, value);
+ }
+ }
+
+/*
+
+Required functions for GC and Freeze / Thaw.
+
+*/
+
+ VTABLE void mark() {
+ PMC *sub;
+ GET_ATTR_alarm_sub(INTERP, SELF, sub);
+ Parrot_gc_mark_PMC_alive(INTERP, sub);
+ }
+
+ VTABLE void visit(PMC *info) {
+ PMC *sub;
+ GET_ATTR_alarm_sub(INTERP, SELF, sub);
+ VISIT_PMC(INTERP, info, sub);
+ SUPER(info);
+ }
+
+ VTABLE void freeze(PMC *info) {
+ SUPER(info);
+ VTABLE_push_integer(INTERP, info, VTABLE_elements(INTERP, SELF));
+ }
+
+ VTABLE void thaw(PMC *info) {
+ SUPER(info);
+ SELF.set_integer_native(VTABLE_shift_integer(INTERP, info));
+ }
+}
+
+
+
+
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Oops, something went wrong.

0 comments on commit fb0dfd8

Please sign in to comment.