[pypy-commit] pypy continulet-jit: In-progress: add some notion of stacklet id.
arigo
noreply at buildbot.pypy.org
Sun Oct 16 11:49:19 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: continulet-jit
Changeset: r48077:b0e1da0656a9
Date: 2011-10-16 11:49 +0200
http://bitbucket.org/pypy/pypy/changeset/b0e1da0656a9/
Log: In-progress: add some notion of stacklet id. Not composable at all,
but seems to be needed for the JIT's virtualizables and
virtualrefs...
diff --git a/pypy/translator/c/src/stacklet/stacklet.c b/pypy/translator/c/src/stacklet/stacklet.c
--- a/pypy/translator/c/src/stacklet/stacklet.c
+++ b/pypy/translator/c/src/stacklet/stacklet.c
@@ -34,6 +34,8 @@
/************************************************************/
struct stacklet_s {
+ stacklet_id id; /* first field */
+
/* The portion of the real stack claimed by this paused tealet. */
char *stack_start; /* the "near" end of the stack */
char *stack_stop; /* the "far" end of the stack */
@@ -60,6 +62,7 @@
stacklet_run_fn, void *) = NULL;
struct stacklet_thread_s {
+ stacklet_id g_current_id; /* first field */
struct stacklet_s *g_stack_chain_head; /* NULL <=> running main */
char *g_current_stack_stop;
char *g_current_stack_marker;
@@ -67,6 +70,10 @@
struct stacklet_s *g_target;
};
+struct stacklet_id_s {
+ stacklet_handle stacklet;
+};
+
/***************************************************************/
static void g_save(struct stacklet_s* g, char* stop
@@ -128,6 +135,9 @@
return -1;
stacklet = thrd->g_source;
+ stacklet->id = thrd->g_current_id;
+ if (stacklet->id != NULL)
+ stacklet->id->stacklet = stacklet;
stacklet->stack_start = old_stack_pointer;
stacklet->stack_stop = thrd->g_current_stack_stop;
stacklet->stack_saved = 0;
@@ -227,6 +237,9 @@
memcpy(g->stack_start - stack_saved, g+1, stack_saved);
#endif
thrd->g_current_stack_stop = g->stack_stop;
+ thrd->g_current_id = g->id;
+ if (thrd->g_current_id != NULL)
+ thrd->g_current_id->stacklet = NULL;
free(g);
return EMPTY_STACKLET_HANDLE;
}
@@ -235,18 +248,33 @@
stacklet_run_fn run, void *run_arg)
{
struct stacklet_s *result;
+ stacklet_id sid1 = thrd->g_current_id;
+ stacklet_id sid = malloc(sizeof(struct stacklet_id_s));
+ if (sid == NULL) {
+ thrd->g_source = NULL;
+ return;
+ }
/* The following call returns twice! */
result = (struct stacklet_s *) _stacklet_switchstack(g_initial_save_state,
g_restore_state,
thrd);
- if (result == NULL && thrd->g_source != NULL) {
- /* First time it returns. Only g_initial_save_state() has run
- and has created 'g_source'. Call run(). */
+ if (result == NULL) {
+ /* First time it returns. */
+ if (thrd->g_source == NULL) { /* out of memory */
+ free(sid);
+ return;
+ }
+ /* Only g_initial_save_state() has run and has created 'g_source'.
+ Call run(). */
+ sid->stacklet = NULL;
+ thrd->g_current_id = sid;
+ fprintf(stderr, "new sid: %p\n", sid);
thrd->g_current_stack_stop = thrd->g_current_stack_marker;
result = run(thrd->g_source, run_arg);
/* Then switch to 'result'. */
+ free(sid);
thrd->g_target = result;
_stacklet_switchstack(g_destroy_state, g_restore_state, thrd);
@@ -254,6 +282,8 @@
abort();
}
/* The second time it returns. */
+ assert(thrd->g_current_id == sid1);
+ fprintf(stderr, "continue with sid: %p\n", sid1);
}
/************************************************************/
diff --git a/pypy/translator/c/src/stacklet/stacklet.h b/pypy/translator/c/src/stacklet/stacklet.h
--- a/pypy/translator/c/src/stacklet/stacklet.h
+++ b/pypy/translator/c/src/stacklet/stacklet.h
@@ -59,4 +59,14 @@
*/
char **_stacklet_translate_pointer(stacklet_handle context, char **ptr);
+/* The "stacklet id" is NULL for main stacklets; for other stacklets it is a
+ * value that remain valid and unchanged if the stacklet is suspended and
+ * resumed. WARNING: DON'T USE unless you have no other choice, because
+ * it is not "composable" at all.
+ */
+typedef struct stacklet_id_s *stacklet_id;
+#define _stacklet_id_of_stacklet(stacklet) (*(stacklet_id*)(stacklet))
+#define _stacklet_id_current(thrd) (*(stacklet_id*)(thrd))
+stacklet_handle _stacklet_with_id(stacklet_thread_handle thrd, stacklet_id id);
+
#endif /* _STACKLET_H_ */
diff --git a/pypy/translator/c/src/stacklet/tests.c b/pypy/translator/c/src/stacklet/tests.c
--- a/pypy/translator/c/src/stacklet/tests.c
+++ b/pypy/translator/c/src/stacklet/tests.c
@@ -627,6 +627,66 @@
#endif
/************************************************************/
+struct test_id_s {
+ stacklet_id id1;
+ stacklet_id id2;
+} tid;
+
+stacklet_handle stacklet_id_callback_1(stacklet_handle h, void *arg)
+{
+ stacklet_id myid = _stacklet_id_current(thrd);
+ h = stacklet_switch(thrd, h);
+
+ tid.id1 = _stacklet_id_current(thrd);
+ assert(tid.id1 != NULL);
+ assert(tid.id1 == myid);
+ assert(status == 0);
+ status = 1;
+
+ return stacklet_switch(thrd, h);
+}
+
+stacklet_handle stacklet_id_callback_2(stacklet_handle h, void *arg)
+{
+ stacklet_id myid = _stacklet_id_current(thrd);
+ h = stacklet_switch(thrd, h);
+
+ tid.id2 = _stacklet_id_current(thrd);
+ assert(tid.id2 != NULL);
+ assert(tid.id2 == myid);
+ assert(status == 1);
+ status = 2;
+
+ return stacklet_switch(thrd, h);
+}
+
+void test_stacklet_id(void)
+{
+ status = 0;
+ stacklet_handle h1 = stacklet_new(thrd, stacklet_id_callback_1, NULL);
+ stacklet_handle h2 = stacklet_new(thrd, stacklet_id_callback_2, NULL);
+
+ assert(_stacklet_id_current(thrd) == NULL);
+
+ assert(status == 0);
+ h1 = stacklet_switch(thrd, h1);
+
+ assert(status == 1);
+ h2 = stacklet_switch(thrd, h2);
+
+ assert(status == 2);
+ assert(_stacklet_id_of_stacklet(h1) == tid.id1);
+ assert(_stacklet_id_of_stacklet(h2) == tid.id2);
+ assert(_stacklet_id_current(thrd) == NULL);
+
+ h1 = stacklet_switch(thrd, h1);
+ assert(h1 == EMPTY_STACKLET_HANDLE);
+ h2 = stacklet_switch(thrd, h2);
+ assert(h2 == EMPTY_STACKLET_HANDLE);
+}
+
+/************************************************************/
+
#define TEST(name) { name, #name }
typedef struct {
@@ -649,6 +709,7 @@
TEST(test_double),
TEST(test_random),
#endif
+ TEST(test_stacklet_id),
{ NULL, NULL }
};
More information about the pypy-commit
mailing list