[pypy-commit] stmgc c7-refactor: Adapt demo2.c.
arigo
noreply at buildbot.pypy.org
Wed Feb 19 06:43:33 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r771:c07b26b32fb1
Date: 2014-02-19 06:43 +0100
http://bitbucket.org/pypy/stmgc/changeset/c07b26b32fb1/
Log: Adapt demo2.c.
diff --git a/c7/Makefile b/c7/Makefile
--- a/c7/Makefile
+++ b/c7/Makefile
@@ -14,16 +14,14 @@
rm -f $(BUILD_EXE) $(DEBUG_EXE) $(RELEASE_EXE)
-H_FILES = core.h list.h pagecopy.h reader_writer_lock.h stmsync.h pages.h nursery.h largemalloc.h
+H_FILES = stmgc.h stm/*.h
+C_FILES = stmgc.c stm/*.c
-C_FILES = core.c list.c pagecopy.c reader_writer_lock.c stmsync.c pages.c nursery.c largemalloc.c
-DEBUG = -g
-
-
-# note that we don't say -DNDEBUG, so that asserts should still be compiled in
-# also, all debug code with extra checks but not the debugprints
-build-%: %.c ${H_FILES} ${C_FILES}
- clang -pthread -g -O1 $< -o build-$* -Wall ${C_FILES}
-release-%: %.c ${H_FILES} ${C_FILES}
- clang -pthread -g -DNDEBUG -O2 $< -o release-$* -Wall ${C_FILES}
+# note that 'build' is optimized but still contains all asserts
+debug-%: %.c ${H_FILES} ${C_FILES}
+ clang -pthread -g $< -o debug-$* -Wall -Werror stmgc.c
+build-%: %.c ${H_FILES} ${C_FILES}
+ clang -pthread -g -O1 $< -o build-$* -Wall stmgc.c
+release-%: %.c ${H_FILES} ${C_FILES}
+ clang -pthread -g -DNDEBUG -O2 $< -o release-$* -Wall stmgc.c
diff --git a/c7/demo2.c b/c7/demo2.c
--- a/c7/demo2.c
+++ b/c7/demo2.c
@@ -4,8 +4,7 @@
#include <pthread.h>
#include <semaphore.h>
-#include "core.h"
-#include "stmsync.h"
+#include "stmgc.h"
#define LIST_LENGTH 6000
#define BUNCH 400
@@ -20,8 +19,13 @@
nodeptr_t next;
};
+__thread stm_thread_local_t stm_thread_local;
-size_t stmcb_size(struct object_s *ob)
+#define PUSH_ROOT(p) (void)0 // XXX...
+#define POP_ROOT(p) (void)0 // XXX...
+
+
+ssize_t stmcb_size_rounded_up(struct object_s *ob)
{
return sizeof(struct node_s);
}
@@ -34,97 +38,88 @@
}
-nodeptr_t global_chained_list = NULL;
+nodeptr_t global_chained_list;
-long check_sorted()
+long check_sorted(void)
{
nodeptr_t r_n;
long prev, sum;
- jmpbufptr_t here;
+ stm_jmpbuf_t here;
- back:
- if (__builtin_setjmp(here) == 0) {
- stm_start_transaction(&here);
-
- stm_read((objptr_t)global_chained_list);
- r_n = global_chained_list;
- assert(r_n->value == -1);
-
- prev = -1;
- sum = 0;
- while (r_n->next) {
- r_n = r_n->next;
- stm_read((objptr_t)r_n);
- sum += r_n->value;
+ STM_START_TRANSACTION(&stm_thread_local, here);
- _stm_start_safe_point(0);
- _stm_stop_safe_point(0);
- if (prev >= r_n->value) {
- stm_stop_transaction();
- return -1;
- }
-
- prev = r_n->value;
+ stm_read((objptr_t)global_chained_list);
+ r_n = global_chained_list;
+ assert(r_n->value == -1);
+
+ prev = -1;
+ sum = 0;
+ while (r_n->next) {
+ r_n = r_n->next;
+ stm_read((objptr_t)r_n);
+ sum += r_n->value;
+
+ stm_safe_point();
+ if (prev >= r_n->value) {
+ stm_commit_transaction();
+ return -1;
}
- stm_stop_transaction();
- return sum;
+ prev = r_n->value;
}
- goto back;
+
+ stm_commit_transaction();
+ return sum;
}
nodeptr_t swap_nodes(nodeptr_t initial)
{
- jmpbufptr_t here;
+ stm_jmpbuf_t here;
assert(initial != NULL);
- back:
- if (__builtin_setjmp(here) == 0) {
- stm_start_transaction(&here);
- nodeptr_t prev = initial;
- stm_read((objptr_t)prev);
-
- int i;
- for (i=0; i<BUNCH; i++) {
- nodeptr_t current = prev->next;
- if (current == NULL) {
- stm_stop_transaction();
- return NULL;
- }
- stm_read((objptr_t)current);
- nodeptr_t next = current->next;
- if (next == NULL) {
- stm_stop_transaction();
- return NULL;
- }
- stm_read((objptr_t)next);
-
- if (next->value < current->value) {
- stm_write((objptr_t)prev);
- stm_write((objptr_t)current);
- stm_write((objptr_t)next);
-
- prev->next = next;
- current->next = next->next;
- next->next = current;
- _stm_start_safe_point(0);
- _stm_stop_safe_point(0);
- }
- prev = current;
+ STM_START_TRANSACTION(&stm_thread_local, here);
+
+ nodeptr_t prev = initial;
+ stm_read((objptr_t)prev);
+
+ int i;
+ for (i=0; i<BUNCH; i++) {
+ nodeptr_t current = prev->next;
+ if (current == NULL) {
+ stm_commit_transaction();
+ return NULL;
}
+ stm_read((objptr_t)current);
+ nodeptr_t next = current->next;
+ if (next == NULL) {
+ stm_commit_transaction();
+ return NULL;
+ }
+ stm_read((objptr_t)next);
- stm_stop_transaction();
- return prev;
+ if (next->value < current->value) {
+ stm_write((objptr_t)prev);
+ stm_write((objptr_t)current);
+ stm_write((objptr_t)next);
+
+ prev->next = next;
+ current->next = next->next;
+ next->next = current;
+
+ stm_safe_point();
+ }
+ prev = current;
}
- goto back;
+
+ stm_commit_transaction();
+ return prev;
}
-
-void bubble_run()
+void bubble_run(void)
{
nodeptr_t r_current;
@@ -136,25 +131,25 @@
/* initialize list with values in decreasing order */
-void setup_list()
+void setup_list(void)
{
int i;
nodeptr_t w_newnode, w_prev;
- stm_start_transaction(NULL);
+ stm_start_inevitable_transaction(&stm_thread_local);
global_chained_list = (nodeptr_t)stm_allocate(sizeof(struct node_s));
global_chained_list->value = -1;
global_chained_list->next = NULL;
-
- stm_push_root((objptr_t)global_chained_list);
-
+
+ PUSH_ROOT(global_chained_list);
+
w_prev = global_chained_list;
for (i = 0; i < LIST_LENGTH; i++) {
- stm_push_root((objptr_t)w_prev);
+ PUSH_ROOT(w_prev);
w_newnode = (nodeptr_t)stm_allocate(sizeof(struct node_s));
-
- w_prev = (nodeptr_t)stm_pop_root();
+
+ POP_ROOT(w_prev);
w_newnode->value = LIST_LENGTH - i;
w_newnode->next = NULL;
@@ -163,44 +158,31 @@
w_prev = w_newnode;
}
- _stm_minor_collect(); /* hack.. */
- global_chained_list = (nodeptr_t)stm_pop_root();
-
- stm_stop_transaction();
+ //_stm_minor_collect(); /* hack.. */
+ //POP_ROOT(global_chained_list); --- remains in the shadowstack
-
-
+ stm_commit_transaction();
+
+
printf("setup ok\n");
}
static sem_t done;
-static sem_t go;
-static sem_t initialized;
void *demo2(void *arg)
{
-
int status;
- if (arg != NULL) {
- /* we still need to initialize */
- stm_setup_pthread();
- sem_post(&initialized);
- status = sem_wait(&go);
- assert(status == 0);
- }
-
+ stm_register_thread_local(&stm_thread_local);
+
while (check_sorted() == -1) {
bubble_run();
}
- if (arg != NULL) {
- status = sem_post(&done);
- assert(status == 0);
- stm_teardown_pthread();
- }
-
+ assert(stm_thread_local.shadowstack == stm_thread_local.shadowstack_base);
+ stm_unregister_thread_local(&stm_thread_local);
+ status = sem_post(&done); assert(status == 0);
return NULL;
}
@@ -236,32 +218,22 @@
{
int status;
- status = sem_init(&initialized, 0, 0);
- assert(status == 0);
- status = sem_init(&go, 0, 0);
- assert(status == 0);
-
+ status = sem_init(&done, 0, 0); assert(status == 0);
+
stm_setup();
- stm_setup_pthread();
-
- newthread(demo2, (void*)1);
-
- status = sem_wait(&initialized);
- assert(status == 0);
+ stm_register_thread_local(&stm_thread_local);
setup_list();
- status = sem_post(&go);
- assert(status == 0);
-
- demo2(NULL);
-
- status = sem_wait(&done);
- assert(status == 0);
-
+ newthread(demo2, (void*)1);
+ newthread(demo2, (void*)2);
+
+ status = sem_wait(&done); assert(status == 0);
+ status = sem_wait(&done); assert(status == 0);
+
final_check();
- stm_teardown_pthread();
+ stm_unregister_thread_local(&stm_thread_local);
stm_teardown();
return 0;
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -199,7 +199,7 @@
/* may collect! */
STM_SEGMENT->nursery_current -= size_rounded_up; /* restore correct val */
- if (collectable_safe_point())
+ if (_stm_collectable_safe_point())
return (stm_char *)stm_allocate(size_rounded_up);
if (size_rounded_up < MEDIUM_OBJECT) {
diff --git a/c7/stm/nursery.h b/c7/stm/nursery.h
--- a/c7/stm/nursery.h
+++ b/c7/stm/nursery.h
@@ -3,6 +3,10 @@
#define NSE_SIGNAL 1
#define NSE_SIGNAL_DONE 2
+#if _STM_NSE_SIGNAL != NSE_SIGNAL
+# error "adapt _STM_NSE_SIGNAL"
+#endif
+
/* Rules for 'v_nursery_section_end':
- Its main purpose is to be read by the owning thread in stm_allocate().
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -266,7 +266,7 @@
return true;
}
-static bool collectable_safe_point(void)
+bool _stm_collectable_safe_point(void)
{
bool any_operation = false;
restart:;
diff --git a/c7/stm/sync.h b/c7/stm/sync.h
--- a/c7/stm/sync.h
+++ b/c7/stm/sync.h
@@ -17,4 +17,3 @@
/* see the source for an exact description */
static bool try_wait_for_other_safe_points(int requested_safe_point_kind);
-static bool collectable_safe_point(void);
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -82,6 +82,7 @@
stm_char *_stm_allocate_slowpath(ssize_t);
void _stm_become_inevitable(char*);
void _stm_start_transaction(stm_thread_local_t *, stm_jmpbuf_t *);
+bool _stm_collectable_safe_point(void);
#ifdef STM_TESTS
bool _stm_was_read(object_t *obj);
@@ -100,6 +101,7 @@
#endif
#define _STM_GCFLAG_WRITE_BARRIER_CALLED 0x80
+#define _STM_NSE_SIGNAL 1
#define STM_FLAGS_PREBUILT 0
@@ -208,13 +210,13 @@
void stm_register_thread_local(stm_thread_local_t *tl);
void stm_unregister_thread_local(stm_thread_local_t *tl);
-/* Starting and ending transactions. You should only call stm_read(),
- stm_write() and stm_allocate() from within a transaction. Use
- the macro STM_START_TRANSACTION() to start a transaction that
+/* Starting and ending transactions. stm_read(), stm_write() and
+ stm_allocate() should only be called from within a transaction.
+ Use the macro STM_START_TRANSACTION() to start a transaction that
can be restarted using the 'jmpbuf' (a local variable of type
stm_jmpbuf_t). */
#define STM_START_TRANSACTION(tl, jmpbuf) ({ \
- int _restart = __builtin_setjmp(&jmpbuf); \
+ int _restart = __builtin_setjmp(jmpbuf); \
_stm_start_transaction(tl, &jmpbuf); \
_restart; \
})
@@ -239,6 +241,13 @@
_stm_become_inevitable(msg);
}
+/* Forces a safe-point if needed. Normally not needed: this is
+ automatic if you call stm_allocate(). */
+static inline void stm_safe_point(void) {
+ if (STM_SEGMENT->v_nursery_section_end == _STM_NSE_SIGNAL)
+ _stm_collectable_safe_point();
+}
+
/* ==================== END ==================== */
More information about the pypy-commit
mailing list