summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-10-06 23:19:22 +0200
committerThomas Haller <thaller@redhat.com>2020-10-06 23:36:11 +0200
commit8e286c32dcf45d04e728ef974db4c0b161a23347 (patch)
treeaa38d28bfc4d76dcd758f99fce094e8ab860cee2
parent9c8275bedcc98d789fa83d2817b9e8ff58f3e7b6 (diff)
downloadNetworkManager-8e286c32dcf45d04e728ef974db4c0b161a23347.tar.gz
fix build on m68k/sh4 archs and require minimal struct aligment to only 4 bytesth/c-rbtree-32arch
Building on m68k and sh4 architectures fails with static assertions: shared/c-rbtree/src/c-rbtree.c:39:1: error: static assertion failed: "Invalid RBNode alignment" 39 | static_assert(alignof(CRBNode) <= alignof(max_align_t), "Invalid RBNode alignment"); | ^~~~~~~~~~~~~ shared/c-rbtree/src/c-rbtree.c:41:1: error: static assertion failed: "Invalid RBTree alignment" 41 | static_assert(alignof(CRBTree) <= alignof(max_align_t), "Invalid RBTree alignment"); | ^~~~~~~~~~~~~ make[3]: *** [Makefile:13261: shared/c-rbtree/src/libcrbtree_la-c-rbtree.lo] Error 1 make[3]: *** Waiting for unfinished jobs.... I presume that is, because on those architectures "max_align_t" is only aligned to 4 bytes. The previous alignment to 8 bytes was to reserve 4 flags, and ensure that all valid pointers have these lower bits unset. Since one flag was actually unused, we only need to reserve 3 bits and can accept an alignment to 4 bytes only. Also, while at it don't use "unsigned long" but uintptr_t type. Since this is supposed to be a C11 library, we can rely on <stdint.h> to provide that type for us (on any architecture we care about). This is an ABI break, but I think that is acceptable, since c-rbtree is usually statically linked.
-rw-r--r--shared/c-rbtree/src/c-rbtree-private.h6
-rw-r--r--shared/c-rbtree/src/c-rbtree.c12
-rw-r--r--shared/c-rbtree/src/c-rbtree.h14
3 files changed, 16 insertions, 16 deletions
diff --git a/shared/c-rbtree/src/c-rbtree-private.h b/shared/c-rbtree/src/c-rbtree-private.h
index c9befbf37c..61ebe20e46 100644
--- a/shared/c-rbtree/src/c-rbtree-private.h
+++ b/shared/c-rbtree/src/c-rbtree-private.h
@@ -18,12 +18,12 @@ static inline void *c_rbnode_raw(CRBNode *n) {
return (void *)(n->__parent_and_flags & ~C_RBNODE_FLAG_MASK);
}
-static inline unsigned long c_rbnode_flags(CRBNode *n) {
+static inline uintptr_t c_rbnode_flags(CRBNode *n) {
return n->__parent_and_flags & C_RBNODE_FLAG_MASK;
}
static inline _Bool c_rbnode_is_red(CRBNode *n) {
- return c_rbnode_flags(n) & C_RBNODE_RED;
+ return !!(c_rbnode_flags(n) & C_RBNODE_RED);
}
static inline _Bool c_rbnode_is_black(CRBNode *n) {
@@ -31,5 +31,5 @@ static inline _Bool c_rbnode_is_black(CRBNode *n) {
}
static inline _Bool c_rbnode_is_root(CRBNode *n) {
- return c_rbnode_flags(n) & C_RBNODE_ROOT;
+ return !!(c_rbnode_flags(n) & C_RBNODE_ROOT);
}
diff --git a/shared/c-rbtree/src/c-rbtree.c b/shared/c-rbtree/src/c-rbtree.c
index aacdcc2913..bba68640d1 100644
--- a/shared/c-rbtree/src/c-rbtree.c
+++ b/shared/c-rbtree/src/c-rbtree.c
@@ -31,15 +31,15 @@
#include "c-rbtree-private.h"
/*
- * We use alignas(8) to enforce 64bit alignment of structure fields. This is
+ * We use alignas() to enforce at least 32 bit 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.
*/
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
@@ -363,8 +363,8 @@ static inline void c_rbtree_store(CRBNode **ptr, CRBNode *addr) {
* applied. But since both fields share its backing memory, this helper
* function is provided.
*/
-static inline void c_rbnode_set_parent_and_flags(CRBNode *n, CRBNode *p, unsigned long flags) {
- n->__parent_and_flags = (unsigned long)p | flags;
+static inline void c_rbnode_set_parent_and_flags(CRBNode *n, CRBNode *p, uintptr_t flags) {
+ n->__parent_and_flags = ((uintptr_t)p) | flags;
}
/*
@@ -403,7 +403,7 @@ static inline CRBTree *c_rbnode_pop_root(CRBNode *n) {
static inline CRBTree *c_rbnode_push_root(CRBNode *n, CRBTree *t) {
if (t) {
if (n)
- n->__parent_and_flags = (unsigned long)t
+ n->__parent_and_flags = ((uintptr_t)t)
| c_rbnode_flags(n)
| C_RBNODE_ROOT;
c_rbtree_store(&t->root, n);
diff --git a/shared/c-rbtree/src/c-rbtree.h b/shared/c-rbtree/src/c-rbtree.h
index cb33fcf7a8..afdd152655 100644
--- a/shared/c-rbtree/src/c-rbtree.h
+++ b/shared/c-rbtree/src/c-rbtree.h
@@ -29,15 +29,15 @@ extern "C" {
#include <assert.h>
#include <stdalign.h>
#include <stddef.h>
+#include <stdint.h>
typedef struct CRBNode CRBNode;
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_RED ((uintptr_t)0x1U)
+#define C_RBNODE_ROOT ((uintptr_t)0x2U)
+#define C_RBNODE_FLAG_MASK ((uintptr_t)0x3U)
/**
* struct CRBNode - Node of a Red-Black Tree
@@ -60,12 +60,12 @@ typedef struct CRBTree CRBTree;
* C_RBNODE_INIT.
*/
struct CRBNode {
- alignas(8) unsigned long __parent_and_flags;
+ alignas(sizeof(uintptr_t) > 4 ? sizeof(uintptr_t) : 4) uintptr_t __parent_and_flags;
CRBNode *left;
CRBNode *right;
};
-#define C_RBNODE_INIT(_var) { .__parent_and_flags = (unsigned long)&(_var) }
+#define C_RBNODE_INIT(_var) { .__parent_and_flags = (uintptr_t)&(_var) }
CRBNode *c_rbnode_leftmost(CRBNode *n);
CRBNode *c_rbnode_rightmost(CRBNode *n);
@@ -90,7 +90,7 @@ void c_rbnode_unlink_stale(CRBNode *n);
* To initialize an RB-Tree, set it to NULL / all zero.
*/
struct CRBTree {
- alignas(8) CRBNode *root;
+ alignas(sizeof(uintptr_t) > 4 ? sizeof(uintptr_t) : 4) CRBNode *root;
};
#define C_RBTREE_INIT {}