[svn:parrot] r47764 - in branches/gsoc_threads: config/gen/makefiles include/parrot src src/pmc t/pmc
Chandon at svn.parrot.org
Chandon at svn.parrot.org
Tue Jun 22 18:14:51 UTC 2010
Author: Chandon
Date: Tue Jun 22 18:14:50 2010
New Revision: 47764
URL: https://trac.parrot.org/parrot/changeset/47764
Log:
Add alarm mechanism; not yet hooked into anything.
Added:
branches/gsoc_threads/include/parrot/alarm.h
branches/gsoc_threads/include/parrot/alarm_private.h
branches/gsoc_threads/src/alarm.c
branches/gsoc_threads/src/pmc/alarmtest.pmc
branches/gsoc_threads/src/pmc/pmclist.pmc
branches/gsoc_threads/t/pmc/pmclist.t
Modified:
branches/gsoc_threads/config/gen/makefiles/root.in
branches/gsoc_threads/src/main.c
branches/gsoc_threads/src/pmc/scheduler.pmc
branches/gsoc_threads/src/scheduler.c
Modified: branches/gsoc_threads/config/gen/makefiles/root.in
==============================================================================
--- branches/gsoc_threads/config/gen/makefiles/root.in Tue Jun 22 17:37:26 2010 (r47763)
+++ branches/gsoc_threads/config/gen/makefiles/root.in Tue Jun 22 18:14:50 2010 (r47764)
@@ -445,6 +445,7 @@
src/exit$(O) \
src/extend$(O) \
src/extend_vtable$(O) \
+ src/alarm$(O) \
src/gc/alloc_memory$(O) \
src/gc/api$(O) \
src/gc/gc_ms$(O) \
@@ -915,6 +916,10 @@
$(INC_DIR)/scheduler_private.h \
$(INC_DIR)/runcore_api.h
+src/alarm$(O) : $(PARROT_H_HEADERS) src/alarm.c \
+ $(INC_DIR)/alarm.h \
+ $(INC_DIR)/alarm_private.h
+
src/io/core$(O) : $(PARROT_H_HEADERS) src/io/io_private.h src/io/core.c
src/io/socket_api$(O) : $(PARROT_H_HEADERS) src/io/io_private.h \
Added: branches/gsoc_threads/include/parrot/alarm.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_threads/include/parrot/alarm.h Tue Jun 22 18:14:50 2010 (r47764)
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+*/
+
+#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);
+
+PARROT_EXPORT
+void Parrot_alarm_set(FLOATVAL when);
+
+PARROT_EXPORT
+int Parrot_alarm_check(Parrot_alarm_state* last_serial);
+
+void Parrot_alarm_callback(NULLOK(int sig_number));
+void Parrot_alarm_set(FLOATVAL wait);
+#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 */
+
+#endif /* PARROT_ALARM_H_GUARD */
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Added: branches/gsoc_threads/include/parrot/alarm_private.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_threads/include/parrot/alarm_private.h Tue Jun 22 18:14:50 2010 (r47764)
@@ -0,0 +1,24 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+*/
+
+#ifndef PARROT_ALARM_PRIVATE_GUARD_H
+#define PARROT_ALARM_PRIVATE_GUARD_H
+
+#include "parrot.h"
+
+typedef struct Parrot_alarm_queue {
+ FLOATVAL when;
+ int alarm_set;
+ struct Parrot_alarm_queue *next;
+} Parrot_alarm_queue;
+
+#endif /* PARROT_ALARM_PRIVATE_GUARD_H */
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Added: branches/gsoc_threads/src/alarm.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_threads/src/alarm.c Tue Jun 22 18:14:50 2010 (r47764)
@@ -0,0 +1,194 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1 NAME
+
+src/alarm.c - Implements a mechanism for alarms, setting a flag after a delay.
+
+=cut
+
+*/
+
+#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;
+
+/* This file relies on POSIX. Probably need two other versions of it:
+ * one for Windows and one for platforms with no signals or threads. */
+#include <sys/time.h>
+#include <signal.h>
+#include <errno.h>
+
+/* HEADERIZER HFILE: include/parrot/alarm.h */
+
+/*
+=head1 Parrot_alarm_init()
+
+Initialize the alarm queue. This function should only be called from the initial
+pthread. Any other pthreads should make sure to mask out SIGALRM.
+
+=cut
+*/
+
+void Parrot_alarm_callback(SHIM(int sig_number));
+
+PARROT_EXPORT
+void
+Parrot_alarm_init(void)
+{
+ struct sigaction sa;
+ sa.sa_handler = Parrot_alarm_callback;
+ sa.sa_flags = SA_RESTART;
+
+ if(sigaction(SIGALRM, &sa, 0) == -1) {
+ perror("sigaction failed in Parrot_timers_init");
+ exit(EXIT_FAILURE);
+ }
+
+ alarm_serial = 1;
+ alarm_queue = NULL;
+}
+
+/*
+=head1 Parrot_alarm_set(FLOATVAL when)
+
+A helper function to set an alarm.
+
+=cut
+*/
+
+static void
+set_posix_alarm(FLOATVAL wait)
+{
+ const int MIL = 1000000;
+ struct itimerval itmr;
+ int sec, usec;
+
+ sec = (int) wait;
+ usec = (int) ((wait - sec) * MIL);
+
+ itmr.it_value.tv_sec = sec;
+ itmr.it_value.tv_usec = usec;
+ 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);
+ }
+}
+
+
+/*
+=head1 Parrot_alarm_callback()
+
+Callback for SIGALRM. When this is called, a timer should be ready to fire.
+
+=cut
+*/
+
+void
+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;
+
+ // Find the first future item.
+ now = Parrot_floatval_time();
+ while(alarm_queue != NULL && alarm_queue->when < now) {
+ qp = alarm_queue->next;
+ free(alarm_queue);
+ alarm_queue = qp;
+ }
+
+ if(alarm_queue != NULL && alarm_queue->alarm_set == 0) {
+ wait = alarm_queue->when - now;
+ set_posix_alarm(wait);
+ qp->alarm_set = 1;
+ }
+}
+
+/*
+=head1 Parrot_alarm_check(Parrot_alarm_state*)
+
+Has any alarm triggered since we last checked?
+
+Possible design improvement: Alert only the thread that
+set the alarm.
+
+=cut
+*/
+
+PARROT_EXPORT
+int
+Parrot_alarm_check(Parrot_alarm_state* last_serial)
+{
+ if(*last_serial == alarm_serial) {
+ return 0;
+ } else {
+ *last_serial = alarm_serial;
+ return 1;
+ }
+}
+
+/*
+=head1 Parrot_alarm_set(FLOATVAL when)
+
+Sets an alarm to trigger at time 'when'.
+
+=cut
+*/
+
+PARROT_EXPORT
+void
+Parrot_alarm_set(FLOATVAL when) {
+ Parrot_alarm_queue *new_alarm;
+ Parrot_alarm_queue **qpp;
+ FLOATVAL now;
+
+ /* Better late than early */
+ when += 0.0001;
+
+ now = Parrot_floatval_time();
+
+ new_alarm = (Parrot_alarm_queue*) malloc(sizeof(Parrot_alarm_queue));
+ new_alarm->when = 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;
+ }
+
+ qpp = &alarm_queue;
+ while(*qpp != NULL && (*qpp)->when < when) {
+ qpp = &(alarm_queue->next);
+ }
+
+ new_alarm->next = *qpp;
+ new_alarm->alarm_set = 0;
+ *qpp = new_alarm;
+}
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Modified: branches/gsoc_threads/src/main.c
==============================================================================
--- branches/gsoc_threads/src/main.c Tue Jun 22 17:37:26 2010 (r47763)
+++ branches/gsoc_threads/src/main.c Tue Jun 22 18:14:50 2010 (r47764)
@@ -25,6 +25,7 @@
#include "parrot/imcc.h"
#include "parrot/longopt.h"
#include "parrot/runcore_api.h"
+#include "parrot/alarm.h"
#include "pmc/pmc_callcontext.h"
/* For gc_sys_type_enum */
@@ -136,6 +137,9 @@
/* Now initialize interpreter */
initialize_interpreter(interp, (void*)&stacktop);
+ /* Register signal handler for timers */
+ Parrot_alarm_init();
+
/* Parse flags */
sourcefile = parseflags(interp, argc, argv, &pir_argc, &pir_argv, &core, &trace);
Added: branches/gsoc_threads/src/pmc/alarmtest.pmc
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_threads/src/pmc/alarmtest.pmc Tue Jun 22 18:14:50 2010 (r47764)
@@ -0,0 +1,62 @@
+
+#include "parrot/alarm.h"
+
+/* HEADERIZER HFILE: none */
+/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+/* blah */
+
+/* HEADERIZER END: static */
+
+pmclass AlarmTest auto_attrs {
+ ATTR INTVAL id;
+ ATTR INTVAL n;
+ ATTR FLOATVAL set;
+
+ VTABLE void init() {
+ fprintf(stderr, "Made an AlarmTest\n");
+ }
+
+ VTABLE STRING *get_string() {
+ char blah[] = "blah";
+ return Parrot_str_new(interp, blah, strlen(blah));
+ }
+
+ METHOD wonk() {
+ fprintf(stderr, "Wonk\n");
+ }
+
+ METHOD set_alarm(FLOATVAL t) {
+ FLOATVAL now, when;
+ Parrot_AlarmTest_attributes* attrs;
+
+ now = Parrot_floatval_time();
+ when = now + t;
+ Parrot_alarm_set(when);
+
+ attrs = PMC_data_typed(SELF, Parrot_AlarmTest_attributes *);
+ attrs->set = when;
+
+ fprintf(stderr, "At %.06lf set alarm for %.06lf\n", now, when);
+ }
+
+ METHOD check_alarm() {
+ FLOATVAL now;
+ Parrot_AlarmTest_attributes* attrs;
+ INTVAL changed = 0;
+
+ attrs = PMC_data_typed(SELF, Parrot_AlarmTest_attributes *);
+
+ if(Parrot_alarm_check(&(attrs->n))) {
+ now = Parrot_floatval_time();
+
+ fprintf(stderr, "At %.06lf maybe alarm.\n", now);
+
+ if(now > attrs->set)
+ changed = 1;
+ }
+
+ RETURN(INTVAL changed);
+ }
+}
Added: branches/gsoc_threads/src/pmc/pmclist.pmc
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_threads/src/pmc/pmclist.pmc Tue Jun 22 18:14:50 2010 (r47764)
@@ -0,0 +1,481 @@
+/*
+Copyright (C) 2001-2010, Parrot Foundation.
+$Id: resizablepmcarray.pmc 47545 2010-06-10 21:09:12Z Chandon $
+
+=head1 NAME
+
+src/pmc/pmclist.pmc - List of PMCs
+
+=head1 DESCRIPTION
+
+A doubly linked list of PMCs, for when push, pop, shift, and unshift
+all want to be O(1).
+
+=head2 Vtable Functions
+
+=over 4
+
+=cut
+
+*/
+
+/* HEADERIZER HFILE: pmc_pmclist.h */
+/* HEADERIZER BEGIN: blah */
+
+/* blah */
+
+/* HEADERIZER END: blah */
+
+/* HEADERIZER HFILE: none */
+/* HEADERIZER BEGIN: static */
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+
+PARROT_DOES_NOT_RETURN
+static void throw_pop_empty(PARROT_INTERP)
+ __attribute__nonnull__(1);
+
+PARROT_DOES_NOT_RETURN
+static void throw_shift_empty(PARROT_INTERP)
+ __attribute__nonnull__(1);
+
+#define ASSERT_ARGS_throw_pop_empty __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_throw_shift_empty __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp))
+/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
+/* HEADERIZER END: static */
+
+/* It's a doubly linked list */
+typedef struct PMC_List_Item {
+ PMC *data;
+ struct PMC_List_Item *prev;
+ struct PMC_List_Item *next;
+} PMC_List_Item;
+
+pmclass PMCList auto_attrs {
+ ATTR void *head;
+ ATTR void *foot;
+ ATTR INTVAL size;
+
+/*
+=item C<void init()>
+
+Initializes the list.
+
+=cut
+*/
+
+ VTABLE void init() {
+ PObj_custom_mark_SET(SELF);
+ PObj_custom_destroy_SET(SELF);
+
+ SET_ATTR_head(INTERP, SELF, NULL);
+ SET_ATTR_foot(INTERP, SELF, NULL);
+ SET_ATTR_size(INTERP, SELF, 0);
+ }
+
+/*
+=item C<void destroy()>
+
+Free all the list cells.
+
+=cut
+*/
+
+ VTABLE void destroy() {
+ void *tmp;
+ PMC_List_Item *aa;
+ PMC_List_Item *bb;
+
+ GET_ATTR_head(INTERP, SELF, tmp);
+ aa = (PMC_List_Item*) tmp;
+
+ while(aa != NULL) {
+ bb = aa;
+ aa = aa->next;
+ free(bb);
+ }
+ }
+
+/*
+=item C<INTVAL get_integer()>
+
+Returns the size of the list.
+
+=cut
+*/
+
+ VTABLE INTVAL get_integer() {
+ INTVAL size;
+ GET_ATTR_size(INTERP, SELF, size);
+ return size;
+ }
+
+/*
+=item C<PMC *shift_pmc()>
+
+Removes and returns an item from the start of the array.
+
+=cut
+*/
+
+ VTABLE PMC *shift_pmc() {
+ INTVAL size;
+ void *tmp;
+ PMC_List_Item *head;
+ PMC_List_Item *next;
+ PMC_List_Item *item;
+ PMC *data;
+
+ GET_ATTR_size(INTERP, SELF, size);
+
+ if (0 >= size)
+ throw_shift_empty(INTERP);
+
+ GET_ATTR_head(INTERP, SELF, tmp);
+ item = (PMC_List_Item*) tmp;
+ data = item->data;
+
+ size -= 1;
+ SET_ATTR_size(INTERP, SELF, size);
+
+ head = item->next;
+ SET_ATTR_head(INTERP, SELF, head);
+
+ if(head == NULL) {
+ /* size == 0 */
+ SET_ATTR_foot(INTERP, SELF, NULL);
+ } else {
+ head->prev = NULL;
+ }
+
+ if(size == 1) {
+ head->next = NULL;
+ SET_ATTR_foot(INTERP, SELF, head);
+ }
+
+ free(item);
+
+ return data;
+ }
+
+/*
+=item C<void push_pmc(PMC *value)>
+
+Extends the array by adding an element of value C<*value> to the end of
+the array.
+
+=cut
+
+*/
+
+ VTABLE void push_pmc(PMC *value) {
+ INTVAL size;
+ void *tmp;
+ PMC_List_Item *foot;
+ PMC_List_Item *item;
+
+ GET_ATTR_size(INTERP, SELF, size);
+ GET_ATTR_foot(INTERP, SELF, tmp);
+ foot = (PMC_List_Item*) tmp;
+
+ item = (PMC_List_Item*) malloc(sizeof(PMC_List_Item));
+ item->next = NULL;
+ item->prev = foot;
+ item->data = value;
+
+ if(foot)
+ foot->next = item;
+
+ size += 1;
+
+ SET_ATTR_foot(INTERP, SELF, item);
+ SET_ATTR_size(INTERP, SELF, size);
+
+ if(size == 1)
+ SET_ATTR_head(INTERP, SELF, item);
+
+ return;
+ }
+
+/*
+=item C<PMC *pop_pmc()>
+
+Removes and returns the last element in the array.
+
+=cut
+*/
+
+ VTABLE PMC *pop_pmc() {
+ INTVAL size;
+ void *tmp;
+ PMC_List_Item *foot;
+ PMC_List_Item *item;
+ PMC *data;
+
+ GET_ATTR_size(INTERP, SELF, size);
+
+ if (0 >= size)
+ throw_pop_empty(INTERP);
+
+ GET_ATTR_foot(INTERP, SELF, tmp);
+ item = (PMC_List_Item*) tmp;
+ data = item->data;
+
+ size -= 1;
+ SET_ATTR_size(INTERP, SELF, size);
+
+ foot = item->prev;
+ SET_ATTR_foot(INTERP, SELF, foot);
+
+ if(foot == NULL) {
+ /* size == 0 */
+ SET_ATTR_head(INTERP, SELF, NULL);
+ } else {
+ foot->next = NULL;
+ }
+
+ if(size == 1) {
+ foot->prev = NULL;
+ SET_ATTR_head(INTERP, SELF, foot);
+ }
+
+ free(item);
+
+ return data;
+ }
+
+/*
+
+=item C<void unshift_pmc(PMC *value)>
+
+Extends the array by adding an element of value C<*value> to the begin of
+the array.
+
+=cut
+
+*/
+
+ VTABLE void unshift_pmc(PMC *value) {
+ INTVAL size;
+ void *tmp;
+ PMC_List_Item *head;
+ PMC_List_Item *item;
+
+ GET_ATTR_size(INTERP, SELF, size);
+ GET_ATTR_head(INTERP, SELF, tmp);
+ head = (PMC_List_Item*) tmp;
+
+ item = (PMC_List_Item*) malloc(sizeof(PMC_List_Item));
+ item->prev = NULL;
+ item->next = head;
+ item->data = value;
+
+ if(head)
+ head->prev = item;
+
+ size += 1;
+
+ SET_ATTR_head(INTERP, SELF, item);
+ SET_ATTR_size(INTERP, SELF, size);
+
+ if(size == 1)
+ SET_ATTR_foot(INTERP, SELF, item);
+
+ return;
+ }
+
+/*
+
+=item C<PMC *clone()>
+
+Creates and returns a copy of the list.
+
+=cut
+
+*/
+
+ VTABLE PMC *clone() {
+ PMC *copy = Parrot_pmc_new(INTERP, SELF->vtable->base_type);
+ void* tmp;
+ PMC_List_Item *it;
+
+ GET_ATTR_head(INTERP, SELF, tmp);
+ it = (PMC_List_Item*) tmp;
+
+ while(it != NULL) {
+ VTABLE_push_pmc(INTERP, copy, it->data);
+ it = it->next;
+ }
+
+ return copy;
+ }
+
+/*
+
+=item C<STRING *get_repr()>
+
+Returns the Parrot string representation C<ResizablePMCArray>.
+
+=cut
+
+*/
+
+ VTABLE STRING *get_repr() {
+ PMC_List_Item *it;
+ void* tmp;
+ STRING *res = CONST_STRING(INTERP, "[ ");
+
+ GET_ATTR_head(INTERP, SELF, tmp);
+ it = (PMC_List_Item*) tmp;
+
+ while(it != NULL) {
+ res = Parrot_str_concat(INTERP, res, VTABLE_get_repr(INTERP, it->data));
+ it = it->next;
+ }
+
+ return Parrot_str_concat(INTERP, res, CONST_STRING(INTERP, " ]"));
+ }
+
+
+/*
+
+=item C<void visit(PMC *info)>
+
+This is used by freeze/thaw to visit the contents of the array.
+
+C<*info> is the visit info, (see F<include/parrot/pmc_freeze.h>).
+
+=item C<void freeze(PMC *info)>
+
+Used to archive the array.
+
+=item C<void thaw(PMC *info)>
+
+Used to unarchive the array.
+
+=cut
+
+*/
+
+ VTABLE void visit(PMC *info) {
+ PMC_List_Item *it;
+
+ GET_ATTR_head(INTERP, SELF, it);
+ while(it != NULL) {
+ VISIT_PMC(INTERP, info, it->data);
+ it = it->next;
+ }
+
+ 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));
+ }
+
+/*
+
+=item METHOD PMC* shift()
+
+=item METHOD PMC* pop()
+
+Method forms to remove and return a PMC from the beginning or
+end of the array.
+
+=cut
+
+*/
+
+ METHOD shift() {
+ PMC * const value = VTABLE_shift_pmc(INTERP, SELF);
+ RETURN(PMC *value);
+ }
+
+ METHOD pop() {
+ PMC * const value = VTABLE_pop_pmc(INTERP, SELF);
+ RETURN(PMC *value);
+ }
+
+/*
+
+=item METHOD unshift(PMC* value)
+
+=item METHOD push(PMC* value)
+
+Method forms to add a PMC to the beginning or end of the array.
+
+=cut
+
+*/
+
+ METHOD unshift(PMC* value) {
+ VTABLE_unshift_pmc(INTERP, SELF, value);
+ }
+
+ METHOD push(PMC* value) {
+ VTABLE_push_pmc(INTERP, SELF, value);
+ }
+
+}
+
+/*
+
+=back
+
+=head2 Auxiliar functions
+
+=over 4
+
+=item C<static void throw_shift_empty(PARROT_INTERP)>
+
+=item C<static void throw_pop_empty(PARROT_INTERP)>
+
+Throws with the appropiate message.
+
+=cut
+
+*/
+
+PARROT_DOES_NOT_RETURN
+static void
+throw_shift_empty(PARROT_INTERP)
+{
+ ASSERT_ARGS(throw_shift_empty)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "PMCList: Can't shift from an empty array!");
+}
+
+PARROT_DOES_NOT_RETURN
+static void
+throw_pop_empty(PARROT_INTERP)
+{
+ ASSERT_ARGS(throw_pop_empty)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
+ "PMCList: Can't pop from an empty array!");
+}
+
+/*
+
+=back
+
+=head1 See also
+
+F<docs/pdds/pdd17_basic_types.pod>.
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Modified: branches/gsoc_threads/src/pmc/scheduler.pmc
==============================================================================
--- branches/gsoc_threads/src/pmc/scheduler.pmc Tue Jun 22 17:37:26 2010 (r47763)
+++ branches/gsoc_threads/src/pmc/scheduler.pmc Tue Jun 22 18:14:50 2010 (r47764)
@@ -454,6 +454,8 @@
STRING * const iter_str = CONST_STRING(INTERP, "handler_iter");
PMC *iter;
+ fprintf(stderr, "Derf\n");
+
/* Exceptions store the handler iterator for rethrow, other kinds of
* tasks don't (though they could). */
if (task->vtable->base_type == enum_class_Exception
Modified: branches/gsoc_threads/src/scheduler.c
==============================================================================
--- branches/gsoc_threads/src/scheduler.c Tue Jun 22 17:37:26 2010 (r47763)
+++ branches/gsoc_threads/src/scheduler.c Tue Jun 22 18:14:50 2010 (r47764)
@@ -70,12 +70,21 @@
*/
+static int interp_count = 0;
+
void
Parrot_cx_init_scheduler(PARROT_INTERP)
{
ASSERT_ARGS(Parrot_cx_init_scheduler)
+/*
+ if(interp_count++ > 1) {
+ fprintf(stderr, "More than one interp?\n");
+ exit(0);
+ }
+*/
+
if (!interp->parent_interpreter) {
PMC *scheduler;
Added: branches/gsoc_threads/t/pmc/pmclist.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/gsoc_threads/t/pmc/pmclist.t Tue Jun 22 18:14:50 2010 (r47764)
@@ -0,0 +1,185 @@
+#!./parrot
+# Copyright (C) 2001-2009, Parrot Foundation.
+# $Id$
+
+.sub main :main
+ .include 'test_more.pir'
+
+ plan(9)
+
+ empty_exceptions()
+ push_five()
+ push_two_pop_two()
+ unshift_two_shift_two()
+ push_shift()
+ unshift_pop()
+.end
+
+.sub empty_exceptions
+ $P0 = new 'PMCList'
+
+ push_eh pop_good
+ $P1 = pop $P0
+ pop_eh
+
+ ok(0, "pop empty")
+ goto try_shift
+
+pop_good:
+ ok(1, "pop empty")
+
+try_shift:
+
+ $P0 = new 'PMCList'
+
+ push_eh shift_good
+ $P1 = pop $P0
+ pop_eh
+
+ ok(0, "shift empty")
+ .return()
+
+shift_good:
+ ok(1, "shift empty")
+.end
+
+.sub push_many
+ .param pmc a
+ .param int n
+
+ if n < 1 goto done
+
+ $P0 = new 'Integer'
+ $P0 = n
+ push a, $P0
+
+ $N0 = n - 1
+ push_many(a, $N0)
+
+done:
+ .return()
+.end
+
+.sub push_five
+ $P0 = new 'PMCList'
+
+ push_eh fail
+ push_many($P0, 5)
+ pop_eh
+
+ $I0 = $P0
+
+ if $I0 != 5 goto fail
+ ok(1, "push five")
+
+ .return()
+
+fail:
+ ok(0, "push five")
+.end
+
+.sub push_two_pop_two
+ $P0 = new 'PMCList'
+
+ push_many($P0, 2)
+
+ $P1 = pop $P0
+ $I0 = $P0
+
+ if $I0 == 1 goto size_good
+
+ ok(0, "push two pop one")
+ goto try_value
+
+size_good:
+ ok(1, "push two pop one")
+
+try_value:
+ $P1 = pop $P0
+ $I0 = $P1
+
+ if $I0 == 2 goto value_good
+ ok(0, "push two pop two")
+ .return()
+
+value_good:
+ ok(1, "push two pop two")
+.end
+
+.sub unshift_two_shift_two
+ $P0 = new 'PMCList'
+
+ $P1 = new 'Integer', 2
+ unshift $P0, $P1
+
+ $P1 = new 'Integer', 1
+ unshift $P0, $P1
+
+ $P1 = shift $P0
+ $I0 = $P0
+
+ if $I0 == 1 goto size_good
+
+ ok(0, "unshift shift size")
+ goto try_value
+
+size_good:
+ ok(1, "unshift shift size")
+
+try_value:
+ $P1 = shift $P0
+ $I0 = $P1
+
+ if $I0 == 2 goto value_good
+ ok(0, "unshift shift value")
+ .return()
+
+value_good:
+ ok(1, "unshift shift value")
+.end
+
+.sub push_shift
+ $P0 = new 'PMCList'
+
+ $P1 = new 'Integer', 5
+ push $P0, $P1
+
+ $P1 = new 'Integer', 6
+ push $P0, $P1
+
+ $P1 = shift $P0
+ $I0 = $P1
+
+ if $I0 == 5 goto value_good
+ ok(0, "push shift")
+ .return()
+
+value_good:
+ ok(1, "push shift")
+.end
+
+.sub unshift_pop
+ $P0 = new 'PMCList'
+
+ $P1 = new 'Integer', 5
+ unshift $P0, $P1
+
+ $P1 = new 'Integer', 6
+ unshift $P0, $P1
+
+ $P1 = pop $P0
+ $I0 = $P1
+
+ if $I0 == 5 goto value_good
+ ok(0, "unshift pop")
+ .return()
+
+value_good:
+ ok(1, "unshift pop")
+.end
+
+# Local Variables:
+# mode: pir
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:
More information about the parrot-commits
mailing list