Author: Armin Rigo <[email protected]>
Branch: c7-refactor
Changeset: r713:d8932faafda2
Date: 2014-02-09 14:51 +0100
http://bitbucket.org/pypy/stmgc/changeset/d8932faafda2/
Log: Start a refactoring step. Goal: the user program includes only
"stmgc.h", and compiles only "stmgc.c".
diff --git a/c7/stmgc.h b/c7/stmgc.h
new file mode 100644
--- /dev/null
+++ b/c7/stmgc.h
@@ -0,0 +1,147 @@
+#ifndef _STMGC_H
+#define _STMGC_H
+
+
+/* ==================== INTERNAL ==================== */
+
+/* See "API" below. */
+
+
+#include <stddef.h>
+#include <stdint.h>
+#include <assert.h>
+#include <limits.h>
+
+#if LONG_MAX == 2147483647
+# error "Requires a 64-bit environment"
+#endif
+
+#if BYTE_ORDER == 1234
+# define LENDIAN 1 // little endian
+#elif BYTE_ORDER == 4321
+# define LENDIAN 0 // big endian
+#else
+# error "Unsupported endianness"
+#endif
+
+
+enum {
+ /* set if the write-barrier slowpath needs to trigger. set on all
+ old objects if there was no write-barrier on it in the same
+ transaction and no collection inbetween. */
+ GCFLAG_WRITE_BARRIER = (1 << 0),
+};
+
+
+#define TLPREFIX __attribute__((address_space(256)))
+
+typedef TLPREFIX struct object_s object_t;
+typedef TLPREFIX struct stm_pub_region_info_s stm_pub_region_info_t;
+typedef TLPREFIX struct stm_read_marker_s stm_read_marker_t;
+typedef TLPREFIX char stm_char;
+typedef void* stm_jmpbufptr_t[5]; /* for use with __builtin_setjmp() */
+
+struct stm_read_marker_s {
+ uint8_t rm;
+};
+
+struct stm_pub_region_info_s {
+ uint8_t transaction_read_version;
+ stm_char *nursery_current;
+ uint64_t nursery_block_end;
+};
+#define STM_PRINFO ((stm_pub_region_info_t *)4352)
+
+struct stm_thread_local_s {
+ object_t **shadowstack, **shadowstack_base;
+ stm_jmpbufptr_t jmpbuf;
+ /* internal fields follow */
+ int _flags;
+ struct stm_thread_local_s *_prev, *_next;
+} stm_thread_local_t;
+
+/* this should use llvm's coldcc calling convention,
+ but it's not exposed to C code so far */
+void _stm_write_slowpath(object_t *);
+
+
+/* ==================== HELPERS ==================== */
+#ifdef NDEBUG
+#define OPT_ASSERT(cond) do { if (!(cond)) __builtin_unreachable(); } while (0)
+#else
+#define OPT_ASSERT(cond) assert(cond)
+#endif
+#define LIKELY(x) __builtin_expect(x, true)
+#define UNLIKELY(x) __builtin_expect(x, false)
+#define IMPLY(a, b) (!(a) || (b))
+
+
+/* ==================== API ==================== */
+
+/* Structure of objects
+ --------------------
+
+ Objects manipulated by the user program, and managed by this library,
+ must start with a "struct object_s" field. Pointers to any user object
+ must use the "TLPREFIX struct foo *" type --- don't forget TLPREFIX.
+ The best is to use typedefs like above.
+
+ The object_s part contains some fields reserved for the STM library.
+ Right now this is only one byte.
+*/
+
+struct object_s {
+ uint8_t stm_flags; /* reserved for the STM library */
+};
+
+static inline void stm_read(object_t *obj)
+{
+ ((stm_read_marker_t *)(((uintptr_t)obj) >> 4))->rm =
+ STM_PRINFO->transaction_read_version;
+}
+
+static inline void stm_write(object_t *obj)
+{
+ if (UNLIKELY(obj->stm_flags & GCFLAG_WRITE_BARRIER))
+ _stm_write_slowpath(obj);
+}
+
+/* must be provided by the user of this library */
+extern ssize_t stmcb_size(struct object_s *);
+extern void stmcb_trace(struct object_s *, void (object_t **));
+
+
+stm_char *_stm_allocate_slowpath(ssize_t);
+
+static inline object_t *stm_allocate(ssize_t size)
+{
+ assert((size % 8) == 0);
+ assert(size >= 16);
+
+ stm_char *p = STM_PRINFO->nursery_current;
+ stm_char *end = p + size;
+ STM_PRINFO->nursery_current = end;
+ if (UNLIKELY((uint64_t)end > STM_PRINFO->nursery_block_end))
+ p = _stm_allocate_slowpath(size);
+ return (object_t *)p;
+}
+
+object_t *stm_allocate_prebuilt(ssize_t size);
+
+void stm_setup(void);
+void stm_teardown(void);
+void stm_register_thread_local(stm_thread_local_t *tl);
+void stm_unregister_thread_local(stm_thread_local_t *tl);
+
+void stm_start_transaction(stm_thread_local_t *tl);
+void stm_start_inevitable_transaction(stm_thread_local_t *tl);
+void stm_commit_transaction(void);
+void stm_abort_transaction(void);
+void stm_become_inevitable(char* msg);
+
+stm_thread_local_t *_stm_test_switch(stm_thread_local_t *tl);
+
+
+/* ==================== END ==================== */
+
+#endif
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit