Permalink
Browse files

[gsoc_threads] Alarms work, at least the easy way.

git-svn-id: https://svn.parrot.org/parrot/branches/gsoc_threads@47951 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
NatTuck committed Jul 1, 2010
1 parent eff168b commit 9f3e20df856f74ae2277ae9496a8f5a6e5a44656
@@ -94,6 +94,28 @@ Parrot_usleep(unsigned int microseconds)
/*
+=item C<FLOATVAL Parrot_floatval_sleep(void)>
+
+Parrot wrapper around standard library C<time()> function, returning a FLOATVAL.
+
+=cut
+
+*/
+
+void
+Parrot_floatval_sleep(FLOATVAL time)
+{
+ if (time > 1000) {
+ /* prevent integer overflow when converting to microseconds */
+ const int seconds = floor(time);
+ Parrot_sleep(seconds);
+ time -= seconds;
+ }
+ Parrot_usleep((UINTVAL) time*1000000);
+}
+
+/*
+
=item C<struct tm * Parrot_gmtime_r(const time_t *t, struct tm *tm)>
Parrot wrapper around standard library C<gmtime_r()> function.
@@ -10,7 +10,6 @@ Copyright (C) 2010, Parrot Foundation.
typedef struct Parrot_alarm_queue {
FLOATVAL when;
- int alarm_set;
struct Parrot_alarm_queue *next;
} Parrot_alarm_queue;
View
@@ -15,6 +15,8 @@
#include "parrot/parrot.h"
+#define PARROT_TASK_SWITCH_QUANTUM 0.02
+
/* HEADERIZER BEGIN: src/scheduler.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
@@ -81,6 +83,12 @@ PMC * Parrot_cx_find_handler_local(PARROT_INTERP, ARGIN(PMC *task))
__attribute__nonnull__(1)
__attribute__nonnull__(2);
+PARROT_EXPORT
+void Parrot_cx_handle_alarms(PARROT_INTERP, ARGMOD(PMC *scheduler))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*scheduler);
+
PARROT_EXPORT
void Parrot_cx_handle_tasks(PARROT_INTERP, ARGMOD(PMC *scheduler))
__attribute__nonnull__(1)
@@ -113,6 +121,17 @@ void Parrot_cx_schedule_callback(PARROT_INTERP,
__attribute__nonnull__(2)
__attribute__nonnull__(3);
+PARROT_EXPORT
+void Parrot_cx_schedule_immediate(PARROT_INTERP, ARGIN(PMC *sub))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
+PARROT_EXPORT
+void Parrot_cx_schedule_next_task(PARROT_INTERP, ARGMOD(PMC *scheduler))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2)
+ FUNC_MODIFIES(*scheduler);
+
PARROT_EXPORT
void Parrot_cx_schedule_repeat(PARROT_INTERP, ARGIN(PMC *task))
__attribute__nonnull__(1)
@@ -211,6 +230,9 @@ void Parrot_cx_timer_invoke(PARROT_INTERP, ARGIN(PMC *timer))
#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_alarms __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(scheduler))
#define ASSERT_ARGS_Parrot_cx_handle_tasks __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(scheduler))
@@ -228,6 +250,12 @@ void Parrot_cx_timer_invoke(PARROT_INTERP, ARGIN(PMC *timer))
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(user_data) \
, PARROT_ASSERT_ARG(ext_data))
+#define ASSERT_ARGS_Parrot_cx_schedule_immediate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(sub))
+#define ASSERT_ARGS_Parrot_cx_schedule_next_task __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(scheduler))
#define ASSERT_ARGS_Parrot_cx_schedule_repeat __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(task))
@@ -22,6 +22,8 @@ typedef enum {
SCHEDULER_terminate_requested_FLAG = PObj_private2_FLAG
} scheduler_flags_enum;
+void Parrot_pmc_list_insert_by_number(PARROT_INTERP, PMC *list, PMC *value);
+
#define SCHEDULER_get_FLAGS(o) (PObj_get_FLAGS(o))
#define SCHEDULER_flag_TEST(flag, o) (SCHEDULER_get_FLAGS(o) & SCHEDULER_ ## flag ## _FLAG)
#define SCHEDULER_flag_SET(flag, o) (SCHEDULER_get_FLAGS(o) |= SCHEDULER_ ## flag ## _FLAG)
View
@@ -85,8 +85,6 @@ set_posix_alarm(FLOATVAL wait)
itmr.it_interval.tv_sec = 0;
itmr.it_interval.tv_usec = 0;
- fprintf(stderr, "setitimer(%.02lf): sec = %d; usec = %d\n", wait, sec, usec);
-
if(setitimer(ITIMER_REAL, &itmr, 0) == -1) {
perror("setitimer failed in set_posix_alarm");
exit(EXIT_FAILURE);
@@ -108,8 +106,6 @@ Parrot_alarm_callback(SHIM(int sig_number))
FLOATVAL now, wait;
Parrot_alarm_queue* qp;
- fprintf(stderr, "Got Parrot_timers_alarm_callback()\n");
-
/* Not atomic; only one thread ever writes this value */
alarm_serial += 1;
@@ -121,10 +117,9 @@ Parrot_alarm_callback(SHIM(int sig_number))
alarm_queue = qp;
}
- if(alarm_queue != NULL && alarm_queue->alarm_set == 0) {
+ if(alarm_queue != NULL) {
wait = alarm_queue->when - now;
set_posix_alarm(wait);
- qp->alarm_set = 1;
}
}
@@ -176,7 +171,6 @@ Parrot_alarm_set(FLOATVAL when) {
if(alarm_queue == NULL || when < alarm_queue->when) {
new_alarm->next = alarm_queue;
- new_alarm->alarm_set = 1;
alarm_queue = new_alarm;
set_posix_alarm(when - now);
return;
@@ -188,7 +182,6 @@ Parrot_alarm_set(FLOATVAL when) {
}
new_alarm->next = *qpp;
- new_alarm->alarm_set = 0;
*qpp = new_alarm;
}
View
@@ -636,11 +636,14 @@ gc_ms_finalize_memory_pools(PARROT_INTERP, ARGIN(Memory_Pools * const mem_pools)
/* keep the scheduler and its kids alive for Task-like PMCs to destroy
* themselves; run a sweep to collect them */
+ /* TODO: Figure out if this stuff was important */
+#ifdef PARROT_CX_BUILD_OLD_STUFF
if (interp->scheduler) {
Parrot_gc_mark_PMC_alive(interp, interp->scheduler);
VTABLE_mark(interp, interp->scheduler);
Parrot_gc_sweep_pool(interp, mem_pools, mem_pools->pmc_pool);
}
+#endif
/* now sweep everything that's left */
Parrot_gc_sweep_pool(interp, mem_pools, mem_pools->pmc_pool);
View
@@ -48,6 +48,10 @@ Initializes the alarm.
*/
VTABLE void init() {
+ Parrot_Alarm_attributes *data = PARROT_ALARM(SELF);
+ data->alarm_time = 0.0;
+ data->alarm_sub = PMCNULL;
+
PObj_custom_mark_SET(SELF);
}
View
@@ -480,10 +480,6 @@ Insert an item into a sorted list by its num value.
=cut
*/
-void debug_my_face() {
- fprintf(stderr, "");
-};
-
PARROT_EXPORT
void
Parrot_pmc_list_insert_by_number(PARROT_INTERP, PMC *list, PMC *value) {
View
@@ -38,7 +38,8 @@ pmclass Scheduler auto_attrs {
ATTR PMC *messages; /* A message queue used for communication
between schedulers. */
- ATTR PMC *alarms; /* Array of future alarms ordered by time */
+ ATTR PMC *task_queue; /* List of tasks/green threads waiting to run */
+ ATTR PMC *alarms; /* List of future alarms ordered by time */
ATTR Parrot_mutex msg_lock; /* Lock to synchronize the message queue. */
ATTR Parrot_Interp interp; /* A link to the scheduler's interpreter. */
@@ -69,6 +70,7 @@ Initializes a concurrency scheduler object.
core_struct->wait_index = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
core_struct->handlers = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
core_struct->messages = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+ core_struct->task_queue = Parrot_pmc_new(INTERP, enum_class_PMCList);
core_struct->alarms = Parrot_pmc_new(INTERP, enum_class_PMCList);
core_struct->interp = INTERP;
MUTEX_INIT(core_struct->msg_lock);
@@ -281,12 +283,8 @@ Marks any referenced strings and PMCs as live.
Parrot_gc_mark_PMC_alive(INTERP, core_struct->wait_index);
Parrot_gc_mark_PMC_alive(INTERP, core_struct->handlers);
Parrot_gc_mark_PMC_alive(INTERP, core_struct->messages);
-
- if(PObj_is_PMC_TEST(core_struct->alarms)) {
- Parrot_gc_mark_PMC_alive(INTERP, core_struct->alarms);
- } else {
- fprintf(stderr, "Why is this thing not a PMC?\n");
- }
+ Parrot_gc_mark_PMC_alive(INTERP, core_struct->task_queue);
+ Parrot_gc_mark_PMC_alive(INTERP, core_struct->alarms);
}
}
Oops, something went wrong.

0 comments on commit 9f3e20d

Please sign in to comment.