about summary refs log tree commit diff
path: root/shared/c-rbtree/src
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2021-01-11 18:07:03 +0100
committerSebastien Bacher <seb128@ubuntu.com>2021-01-11 18:15:57 +0100
commit2567f558da3eb9911678227d4aeb15162e707d89 (patch)
tree13c80b0e091c8ba585b14b966cda998f95f1936d /shared/c-rbtree/src
parent02d99ffd62ede29cffcb45fcbe33d044b7406d3a (diff)
parentf54032b30e1ddd84f10a339e0caf493772e049a7 (diff)
Merge branch 'debian/master' into ubuntu/master
Diffstat (limited to 'shared/c-rbtree/src')
-rw-r--r--shared/c-rbtree/src/c-rbtree.c14
-rw-r--r--shared/c-rbtree/src/c-rbtree.h15
2 files changed, 19 insertions, 10 deletions
diff --git a/shared/c-rbtree/src/c-rbtree.c b/shared/c-rbtree/src/c-rbtree.c
index aacdcc29..2f0e608f 100644
--- a/shared/c-rbtree/src/c-rbtree.c
+++ b/shared/c-rbtree/src/c-rbtree.c
@@ -31,15 +31,17 @@
 #include "c-rbtree-private.h"
 
 /*
- * We use alignas(8) to enforce 64bit alignment of structure fields. This is
- * according to ISO-C11, so we rely on the compiler to implement this. However,
- * at the same time we don't want to exceed native malloc() alignment on target
- * platforms. Hence, we also verify against max_align_t.
+ * We use the lower 2 bits of CRBNode pointers to store flags. Make sure
+ * CRBNode is 4-byte aligned, so the lower 2 bits are actually unused. We also
+ * sometimes store a pointer to the root-node, so make sure this one is also 4
+ * byte aligned.
+ * Note that there are actually some architectures where `max_align_t` is 4, so
+ * we do not have much wiggle-room to extend this flag-set.
  */
 static_assert(alignof(CRBNode) <= alignof(max_align_t), "Invalid RBNode alignment");
-static_assert(alignof(CRBNode) >= 8, "Invalid CRBNode alignment");
+static_assert(alignof(CRBNode) >= 4, "Invalid CRBNode alignment");
 static_assert(alignof(CRBTree) <= alignof(max_align_t), "Invalid RBTree alignment");
-static_assert(alignof(CRBTree) >= 8, "Invalid CRBTree alignment");
+static_assert(alignof(CRBTree) >= 4, "Invalid CRBTree alignment");
 
 /**
  * c_rbnode_leftmost() - return leftmost child
diff --git a/shared/c-rbtree/src/c-rbtree.h b/shared/c-rbtree/src/c-rbtree.h
index cb33fcf7..d4d0fe45 100644
--- a/shared/c-rbtree/src/c-rbtree.h
+++ b/shared/c-rbtree/src/c-rbtree.h
@@ -36,8 +36,7 @@ typedef struct CRBTree CRBTree;
 /* implementation detail */
 #define C_RBNODE_RED                    (0x1UL)
 #define C_RBNODE_ROOT                   (0x2UL)
-#define C_RBNODE_UNUSED3                (0x4UL)
-#define C_RBNODE_FLAG_MASK              (0x7UL)
+#define C_RBNODE_FLAG_MASK              (0x3UL)
 
 /**
  * struct CRBNode - Node of a Red-Black Tree
@@ -60,7 +59,11 @@ typedef struct CRBTree CRBTree;
  * C_RBNODE_INIT.
  */
 struct CRBNode {
-        alignas(8) unsigned long __parent_and_flags;
+        union {
+                unsigned long __parent_and_flags;
+                /* enforce >=4-byte alignment for @__parent_and_flags */
+                alignas(4) unsigned char __align_dummy;
+        };
         CRBNode *left;
         CRBNode *right;
 };
@@ -90,7 +93,11 @@ void c_rbnode_unlink_stale(CRBNode *n);
  * To initialize an RB-Tree, set it to NULL / all zero.
  */
 struct CRBTree {
-        alignas(8) CRBNode *root;
+        union {
+                CRBNode *root;
+                /* enforce >=4-byte alignment for @root */
+                alignas(4) unsigned char __align_dummy;
+        };
 };
 
 #define C_RBTREE_INIT {}