Author: Remi Meier <[email protected]>
Branch: c7
Changeset: r632:73b59ed9cf7c
Date: 2014-01-17 18:55 +0100
http://bitbucket.org/pypy/stmgc/changeset/73b59ed9cf7c/
Log: add demo2 and remove stuff
diff --git a/c7/Makefile b/c7/Makefile
new file mode 100644
--- /dev/null
+++ b/c7/Makefile
@@ -0,0 +1,27 @@
+#
+# Makefile for the demos.
+#
+
+DEBUG_EXE = debug-demo2
+BUILD_EXE = build-demo2
+RELEASE_EXE = release-demo2
+
+debug: $(DEBUG_EXE) # with prints and asserts
+build: $(BUILD_EXE) # without prints, but with asserts
+release: $(RELEASE_EXE) # without prints nor asserts
+
+clean:
+ rm -f $(BUILD_EXE) $(DEBUG_EXE) $(RELEASE_EXE)
+
+
+H_FILES = core.h list.h pagecopy.h
+
+C_FILES = core.c list.c pagecopy.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 $< -o build-$* -Wall ${C_FILES}
diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -552,7 +552,9 @@
localchar_t *collect_and_reserve(size_t size)
{
+ _stm_start_safe_point();
minor_collect();
+ _stm_stop_safe_point();
localchar_t *current = _STM_TL2->nursery_current;
_STM_TL2->nursery_current = current + size;
@@ -570,6 +572,7 @@
localchar_t *current = _STM_TL2->nursery_current;
localchar_t *new_current = current + size;
_STM_TL2->nursery_current = new_current;
+ assert((uintptr_t)new_current < (1L << 32));
if ((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096) {
current = collect_and_reserve(size);
}
@@ -686,7 +689,7 @@
{
assert(!pthread_rwlock_trywrlock(&rwlock_shared));
assert(!pthread_rwlock_unlock(&rwlock_shared));
-
+
wait_until_updated();
stm_list_free(_STM_TL2->modified_objects);
_STM_TL2->modified_objects = NULL;
@@ -764,15 +767,6 @@
if (UNLIKELY(old_rv == 0xff))
reset_transaction_read_version();
- int old_wv = _STM_TL1->transaction_write_version;
- _STM_TL1->transaction_write_version = old_wv + 1;
- if (UNLIKELY(old_wv == 0xffff)) {
- /* We run out of 16-bit numbers before we do the next major
- collection, which resets it. XXX This case seems unlikely
- for now, but check if it could become a bottleneck at some
- point. */
- stm_major_collection();
- }
wait_until_updated();
assert(stm_list_is_empty(_STM_TL2->modified_objects));
diff --git a/c7/core.h b/c7/core.h
--- a/c7/core.h
+++ b/c7/core.h
@@ -58,7 +58,6 @@
struct _thread_local1_s {
jmpbufptr_t *jmpbufptr;
uint8_t transaction_read_version;
- uint16_t transaction_write_version;
object_t **shadow_stack;
object_t **shadow_stack_base;
};
diff --git a/c7/demo2.c b/c7/demo2.c
new file mode 100644
--- /dev/null
+++ b/c7/demo2.c
@@ -0,0 +1,249 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+#include "core.h"
+
+
+#define LIST_LENGTH 2000
+
+typedef TLPREFIX struct node_s node_t;
+typedef node_t* nodeptr_t;
+typedef object_t* objptr_t;
+
+struct node_s {
+ struct object_s hdr;
+ long value;
+ nodeptr_t next;
+};
+
+
+size_t stmcb_size(struct object_s *ob)
+{
+ return sizeof(struct node_s);
+}
+
+void stmcb_trace(struct object_s *obj, void visit(object_t **))
+{
+ struct node_s *n;
+ n = (struct node_s*)obj;
+ visit((object_t **)&n->next);
+}
+
+
+nodeptr_t global_chained_list = NULL;
+
+
+long check_sorted()
+{
+ nodeptr_t r_n;
+ long prev, sum;
+ jmpbufptr_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;
+
+ if (prev >= r_n->value) {
+ stm_stop_transaction();
+ return -1;
+ }
+
+ prev = r_n->value;
+ }
+
+ stm_stop_transaction();
+ return sum;
+ }
+ goto back;
+}
+
+nodeptr_t swap_nodes(nodeptr_t prev)
+{
+ jmpbufptr_t here;
+
+ assert(prev != NULL);
+ back:
+ if (__builtin_setjmp(here) == 0) {
+ stm_start_transaction(&here);
+
+ stm_read((objptr_t)prev);
+ 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_stop_transaction();
+ return current;
+ }
+ goto back;
+}
+
+
+
+
+void bubble_run()
+{
+ nodeptr_t r_current;
+
+ r_current = global_chained_list;
+ while (r_current) {
+ r_current = swap_nodes(r_current);
+ }
+}
+
+
+/* initialize list with values in decreasing order */
+void setup_list()
+{
+ int i;
+ nodeptr_t w_newnode, w_prev;
+
+ stm_start_transaction(NULL);
+
+ 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);
+
+ w_prev = global_chained_list;
+ for (i = 0; i < LIST_LENGTH; i++) {
+ stm_push_root((objptr_t)w_prev);
+ w_newnode = (nodeptr_t)stm_allocate(sizeof(struct node_s));
+
+ w_prev = (nodeptr_t)stm_pop_root();
+ w_newnode->value = LIST_LENGTH - i;
+ w_newnode->next = NULL;
+
+ stm_write((objptr_t)w_prev);
+ w_prev->next = w_newnode;
+ w_prev = w_newnode;
+ }
+
+ stm_stop_transaction();
+
+ global_chained_list = (nodeptr_t)stm_pop_root();
+
+ 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_thread();
+ sem_post(&initialized);
+ status = sem_wait(&go);
+ assert(status == 0);
+
+ }
+
+ while (check_sorted() == -1) {
+ bubble_run();
+ }
+
+ if (arg != NULL) {
+ status = sem_post(&done);
+ assert(status == 0);
+ }
+ return NULL;
+}
+
+void final_check(void)
+{
+ long sum;
+
+ printf("final check\n");
+
+ sum = check_sorted();
+
+ // little Gauss:
+ assert(sum == (1 + LIST_LENGTH) * (LIST_LENGTH / 2));
+
+ printf("check ok\n");
+}
+
+
+void newthread(void*(*func)(void*), void *arg)
+{
+ pthread_t th;
+ int status = pthread_create(&th, NULL, func, arg);
+ if (status != 0)
+ abort();
+ pthread_detach(th);
+ printf("started new thread\n");
+}
+
+
+
+int main(void)
+{
+ int status;
+
+ status = sem_init(&initialized, 0, 0);
+ assert(status == 0);
+ status = sem_init(&go, 0, 0);
+ assert(status == 0);
+
+ stm_setup();
+ stm_setup_thread();
+
+ newthread(demo2, (void*)1);
+
+ status = sem_wait(&initialized);
+ assert(status == 0);
+
+ setup_list();
+
+ status = sem_post(&go);
+ assert(status == 0);
+
+ demo2(NULL);
+
+ status = sem_wait(&done);
+ assert(status == 0);
+
+ final_check();
+
+ return 0;
+}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit