[pypy-commit] stmgc bag: Align the bag's segment data to 64 bytes boundaries to prevent false sharing
arigo
noreply at buildbot.pypy.org
Sat Jan 24 12:02:06 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: bag
Changeset: r1583:4c2c1694892d
Date: 2015-01-24 12:02 +0100
http://bitbucket.org/pypy/stmgc/changeset/4c2c1694892d/
Log: Align the bag's segment data to 64 bytes boundaries to prevent false
sharing
diff --git a/c7/stm/bag.c b/c7/stm/bag.c
--- a/c7/stm/bag.c
+++ b/c7/stm/bag.c
@@ -41,23 +41,32 @@
*/
-struct stm_bag_seg_s {
- uintptr_t *deque_left, *deque_middle, *deque_right;
- struct list_s *abort_list;
- uint64_t start_time; /* the transaction's unique_start_time */
-};
+typedef union {
+ struct {
+ uintptr_t *deque_left, *deque_middle, *deque_right;
+ struct list_s *abort_list;
+ uint64_t start_time; /* the transaction's unique_start_time */
+ };
+ char alignment[64]; /* 64-bytes alignment, to prevent false sharing */
+} stm_bag_seg_t;
struct stm_bag_s {
- struct stm_bag_seg_s by_segment[STM_NB_SEGMENTS];
+ stm_bag_seg_t by_segment[STM_NB_SEGMENTS];
};
stm_bag_t *stm_bag_create(void)
{
int i;
- stm_bag_t *bag = malloc(sizeof(stm_bag_t));
- assert(bag);
+ stm_bag_t *bag;
+ void *mem;
+
+ assert(sizeof(stm_bag_seg_t) == 64);
+ if (posix_memalign(&mem, sizeof(stm_bag_seg_t), sizeof(stm_bag_t)) != 0)
+ stm_fatalerror("out of memory in stm_bag_create"); /* XXX */
+
+ bag = (stm_bag_t *)mem;
for (i = 0; i < STM_NB_SEGMENTS; i++) {
- struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ stm_bag_seg_t *bs = &bag->by_segment[i];
struct deque_block_s *block = deque_new_block();
bs->deque_left = &block->items[0];
bs->deque_middle = &block->items[0];
@@ -72,7 +81,7 @@
{
int i;
for (i = 0; i < STM_NB_SEGMENTS; i++) {
- struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ stm_bag_seg_t *bs = &bag->by_segment[i];
struct deque_block_s *block = deque_block(bs->deque_left);
while (block != NULL) {
struct deque_block_s *nextblock = block->next;
@@ -84,7 +93,7 @@
s_mutex_lock();
for (i = 0; i < STM_NB_SEGMENTS; i++) {
- struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ stm_bag_seg_t *bs = &bag->by_segment[i];
struct stm_segment_info_s *pub = get_segment(i + 1);
stm_thread_local_t *tl = pub->running_thread;
if (tl->associated_segment_num == i + 1) {
@@ -96,7 +105,7 @@
free(bag);
}
-static void bag_add(struct stm_bag_seg_s *bs, object_t *newobj)
+static void bag_add(stm_bag_seg_t *bs, object_t *newobj)
{
struct deque_block_s *block = deque_block(bs->deque_right);
*bs->deque_right++ = (uintptr_t)newobj;
@@ -110,7 +119,7 @@
static void bag_abort_callback(void *key)
{
- struct stm_bag_seg_s *bs = (struct stm_bag_seg_s *)key;
+ stm_bag_seg_t *bs = (stm_bag_seg_t *)key;
/* remove the "added in this transaction" items */
bs->deque_right = bs->deque_middle;
@@ -123,10 +132,10 @@
bs->deque_middle = bs->deque_right;
}
-static struct stm_bag_seg_s *bag_check_start_time(stm_bag_t *bag)
+static stm_bag_seg_t *bag_check_start_time(stm_bag_t *bag)
{
int i = STM_SEGMENT->segment_num - 1;
- struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ stm_bag_seg_t *bs = &bag->by_segment[i];
if (bs->start_time != STM_PSEGMENT->unique_start_time) {
/* There was a commit or an abort since the last operation
@@ -155,13 +164,13 @@
void stm_bag_add(stm_bag_t *bag, object_t *newobj)
{
- struct stm_bag_seg_s *bs = bag_check_start_time(bag);
+ stm_bag_seg_t *bs = bag_check_start_time(bag);
bag_add(bs, newobj);
}
object_t *stm_bag_try_pop(stm_bag_t *bag)
{
- struct stm_bag_seg_s *bs = bag_check_start_time(bag);
+ stm_bag_seg_t *bs = bag_check_start_time(bag);
if (bs->deque_left == bs->deque_right) {
return NULL;
}
@@ -189,14 +198,14 @@
/* only trace the items added in the current transaction;
the rest is already old and cannot point into the nursery. */
int i = STM_SEGMENT->segment_num - 1;
- struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ stm_bag_seg_t *bs = &bag->by_segment[i];
deque_trace(bs->deque_middle, bs->deque_right, trace);
}
else {
int i;
for (i = 0; i < NB_SEGMENTS; i++) {
- struct stm_bag_seg_s *bs = &bag->by_segment[i];
+ stm_bag_seg_t *bs = &bag->by_segment[i];
deque_trace(bs->deque_left, bs->deque_right, trace);
}
}
More information about the pypy-commit
mailing list