C99 forbids flex array members in nested structs

Even when they are at the end.  GCC & Clang allow it, but not all
compilers do.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2019-07-07 10:31:14 +02:00 committed by eboasson
parent ecbee32422
commit 3afce30c37
7 changed files with 88 additions and 80 deletions

View file

@ -95,10 +95,10 @@ nn_entityid_t nn_ntoh_entityid (nn_entityid_t e);
nn_guid_t nn_hton_guid (nn_guid_t g); nn_guid_t nn_hton_guid (nn_guid_t g);
nn_guid_t nn_ntoh_guid (nn_guid_t g); nn_guid_t nn_ntoh_guid (nn_guid_t g);
void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset); void bswap_sequence_number_set_hdr (nn_sequence_number_set_header_t *snset);
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset); void bswap_sequence_number_set_bitmap (nn_sequence_number_set_header_t *snset, uint32_t *bits);
void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset); void bswap_fragment_number_set_hdr (nn_fragment_number_set_header_t *fnset);
void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset); void bswap_fragment_number_set_bitmap (nn_fragment_number_set_header_t *fnset, uint32_t *bits);
#if defined (__cplusplus) #if defined (__cplusplus)
} }

View file

@ -32,25 +32,28 @@ typedef struct {
#define NN_SEQUENCE_NUMBER_UNKNOWN_HIGH -1 #define NN_SEQUENCE_NUMBER_UNKNOWN_HIGH -1
#define NN_SEQUENCE_NUMBER_UNKNOWN_LOW 0 #define NN_SEQUENCE_NUMBER_UNKNOWN_LOW 0
#define NN_SEQUENCE_NUMBER_UNKNOWN ((seqno_t) (((uint64_t)NN_SEQUENCE_NUMBER_UNKNOWN_HIGH << 32) | NN_SEQUENCE_NUMBER_UNKNOWN_LOW)) #define NN_SEQUENCE_NUMBER_UNKNOWN ((seqno_t) (((uint64_t)NN_SEQUENCE_NUMBER_UNKNOWN_HIGH << 32) | NN_SEQUENCE_NUMBER_UNKNOWN_LOW))
typedef struct nn_sequence_number_set { /* C99 disallows flex array in nested struct, so only put the
header in. (GCC and Clang allow it, but there are other
compilers in the world as well.) */
typedef struct nn_sequence_number_set_header {
nn_sequence_number_t bitmap_base; nn_sequence_number_t bitmap_base;
uint32_t numbits; uint32_t numbits;
uint32_t bits[]; } nn_sequence_number_set_header_t;
} nn_sequence_number_set_t;
/* SequenceNumberSet size is base (2 words) + numbits (1 word) + /* SequenceNumberSet size is base (2 words) + numbits (1 word) +
bitmap ((numbits+31)/32 words), and this at 4 bytes/word */ bitmap ((numbits+31)/32 words), and this at 4 bytes/word */
#define NN_SEQUENCE_NUMBER_SET_MAX_BITS (256u)
#define NN_SEQUENCE_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32))) #define NN_SEQUENCE_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32)))
#define NN_SEQUENCE_NUMBER_SET_SIZE(numbits) (offsetof (nn_sequence_number_set_t, bits) + NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits)) #define NN_SEQUENCE_NUMBER_SET_SIZE(numbits) (sizeof (nn_sequence_number_set_header_t) + NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits))
typedef unsigned nn_fragment_number_t; typedef unsigned nn_fragment_number_t;
typedef struct nn_fragment_number_set { typedef struct nn_fragment_number_set_header {
nn_fragment_number_t bitmap_base; nn_fragment_number_t bitmap_base;
uint32_t numbits; uint32_t numbits;
uint32_t bits[]; } nn_fragment_number_set_header_t;
} nn_fragment_number_set_t;
/* FragmentNumberSet size is base (2 words) + numbits (1 word) + /* FragmentNumberSet size is base (2 words) + numbits (1 word) +
bitmap ((numbits+31)/32 words), and this at 4 bytes/word */ bitmap ((numbits+31)/32 words), and this at 4 bytes/word */
#define NN_FRAGMENT_NUMBER_SET_MAX_BITS (256u)
#define NN_FRAGMENT_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32))) #define NN_FRAGMENT_NUMBER_SET_BITS_SIZE(numbits) ((unsigned) (4 * (((numbits) + 31) / 32)))
#define NN_FRAGMENT_NUMBER_SET_SIZE(numbits) (offsetof (nn_fragment_number_set_t, bits) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits)) #define NN_FRAGMENT_NUMBER_SET_SIZE(numbits) (sizeof (nn_fragment_number_set_header_t) + NN_FRAGMENT_NUMBER_SET_BITS_SIZE (numbits))
typedef int32_t nn_count_t; typedef int32_t nn_count_t;
#define DDSI_COUNT_MIN (-2147483647 - 1) #define DDSI_COUNT_MIN (-2147483647 - 1)
#define DDSI_COUNT_MAX (2147483647) #define DDSI_COUNT_MAX (2147483647)
@ -224,11 +227,12 @@ typedef struct AckNack {
SubmessageHeader_t smhdr; SubmessageHeader_t smhdr;
nn_entityid_t readerId; nn_entityid_t readerId;
nn_entityid_t writerId; nn_entityid_t writerId;
nn_sequence_number_set_t readerSNState; nn_sequence_number_set_header_t readerSNState;
uint32_t bits[];
/* nn_count_t count; */ /* nn_count_t count; */
} AckNack_t; } AckNack_t;
#define ACKNACK_FLAG_FINAL 0x02u #define ACKNACK_FLAG_FINAL 0x02u
#define ACKNACK_SIZE(numbits) (offsetof (AckNack_t, readerSNState) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits) + 4) #define ACKNACK_SIZE(numbits) (offsetof (AckNack_t, bits) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits) + 4)
#define ACKNACK_SIZE_MAX ACKNACK_SIZE (256u) #define ACKNACK_SIZE_MAX ACKNACK_SIZE (256u)
typedef struct Gap { typedef struct Gap {
@ -236,9 +240,10 @@ typedef struct Gap {
nn_entityid_t readerId; nn_entityid_t readerId;
nn_entityid_t writerId; nn_entityid_t writerId;
nn_sequence_number_t gapStart; nn_sequence_number_t gapStart;
nn_sequence_number_set_t gapList; nn_sequence_number_set_header_t gapList;
uint32_t bits[];
} Gap_t; } Gap_t;
#define GAP_SIZE(numbits) (offsetof (Gap_t, gapList) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits)) #define GAP_SIZE(numbits) (offsetof (Gap_t, bits) + NN_SEQUENCE_NUMBER_SET_SIZE (numbits))
#define GAP_SIZE_MAX GAP_SIZE (256u) #define GAP_SIZE_MAX GAP_SIZE (256u)
typedef struct InfoTS { typedef struct InfoTS {
@ -272,7 +277,8 @@ typedef struct NackFrag {
nn_entityid_t readerId; nn_entityid_t readerId;
nn_entityid_t writerId; nn_entityid_t writerId;
nn_sequence_number_t writerSN; nn_sequence_number_t writerSN;
nn_fragment_number_set_t fragmentNumberState; nn_fragment_number_set_header_t fragmentNumberState;
uint32_t bits[];
/* nn_count_t count; */ /* nn_count_t count; */
} NackFrag_t; } NackFrag_t;
#define NACKFRAG_SIZE(numbits) (offsetof (NackFrag_t, fragmentNumberState) + NN_FRAGMENT_NUMBER_SET_SIZE (numbits) + 4) #define NACKFRAG_SIZE(numbits) (offsetof (NackFrag_t, fragmentNumberState) + NN_FRAGMENT_NUMBER_SET_SIZE (numbits) + 4)

View file

@ -46,16 +46,16 @@ struct nn_rmsg_chunk {
/* Size is 0 after initial allocation, must be set with /* Size is 0 after initial allocation, must be set with
nn_rmsg_setsize after receiving a packet from the kernel and nn_rmsg_setsize after receiving a packet from the kernel and
before processing it. */ before processing it. */
uint32_t size;
/* to ensure reasonable alignment of payload[] */
union { union {
uint32_t size;
/* to ensure reasonable alignment of payload */
int64_t l; int64_t l;
double d; double d;
void *p; void *p;
} u; } u;
/* payload array stretched to whatever it really is */
unsigned char payload[]; /* unsigned char payload[] -- disallowed by C99 because of nesting */
}; };
struct nn_rmsg { struct nn_rmsg {
@ -95,7 +95,7 @@ struct nn_rmsg {
struct nn_rmsg_chunk chunk; struct nn_rmsg_chunk chunk;
}; };
#define NN_RMSG_PAYLOAD(m) ((m)->chunk.payload) #define NN_RMSG_PAYLOAD(m) ((unsigned char *) (&(m)->chunk + 1))
#define NN_RMSG_PAYLOADOFF(m, o) (NN_RMSG_PAYLOAD (m) + (o)) #define NN_RMSG_PAYLOADOFF(m, o) (NN_RMSG_PAYLOAD (m) + (o))
struct receiver_state { struct receiver_state {
@ -213,7 +213,7 @@ struct nn_defrag *nn_defrag_new (enum nn_defrag_drop_mode drop_mode, uint32_t ma
void nn_defrag_free (struct nn_defrag *defrag); void nn_defrag_free (struct nn_defrag *defrag);
struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata *rdata, const struct nn_rsample_info *sampleinfo); struct nn_rsample *nn_defrag_rsample (struct nn_defrag *defrag, struct nn_rdata *rdata, const struct nn_rsample_info *sampleinfo);
void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1); void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1);
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set *map, uint32_t maxsz); int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz);
struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples); struct nn_reorder *nn_reorder_new (enum nn_reorder_mode mode, uint32_t max_samples);
void nn_reorder_free (struct nn_reorder *r); void nn_reorder_free (struct nn_reorder *r);
@ -222,7 +222,7 @@ struct nn_rdata *nn_rsample_fragchain (struct nn_rsample *rsample);
nn_reorder_result_t nn_reorder_rsample (struct nn_rsample_chain *sc, struct nn_reorder *reorder, struct nn_rsample *rsampleiv, int *refcount_adjust, int delivery_queue_full_p); nn_reorder_result_t nn_reorder_rsample (struct nn_rsample_chain *sc, struct nn_reorder *reorder, struct nn_rsample *rsampleiv, int *refcount_adjust, int delivery_queue_full_p);
nn_reorder_result_t nn_reorder_gap (struct nn_rsample_chain *sc, struct nn_reorder *reorder, struct nn_rdata *rdata, seqno_t min, seqno_t maxp1, int *refcount_adjust); nn_reorder_result_t nn_reorder_gap (struct nn_rsample_chain *sc, struct nn_reorder *reorder, struct nn_rdata *rdata, seqno_t min, seqno_t maxp1, int *refcount_adjust);
int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq); int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq);
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set *map, uint32_t maxsz, int notail); unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail);
seqno_t nn_reorder_next_seq (const struct nn_reorder *reorder); seqno_t nn_reorder_next_seq (const struct nn_reorder *reorder);
struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg); struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg);

View file

@ -53,28 +53,28 @@ nn_guid_t nn_ntoh_guid (nn_guid_t g)
return g; return g;
} }
void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset) void bswap_sequence_number_set_hdr (nn_sequence_number_set_header_t *snset)
{ {
bswapSN (&snset->bitmap_base); bswapSN (&snset->bitmap_base);
snset->numbits = bswap4u (snset->numbits); snset->numbits = bswap4u (snset->numbits);
} }
void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset) void bswap_sequence_number_set_bitmap (nn_sequence_number_set_header_t *snset, uint32_t *bits)
{ {
const uint32_t n = (snset->numbits + 31) / 32; const uint32_t n = (snset->numbits + 31) / 32;
for (uint32_t i = 0; i < n; i++) for (uint32_t i = 0; i < n; i++)
snset->bits[i] = bswap4u (snset->bits[i]); bits[i] = bswap4u (bits[i]);
} }
void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset) void bswap_fragment_number_set_hdr (nn_fragment_number_set_header_t *fnset)
{ {
fnset->bitmap_base = bswap4u (fnset->bitmap_base); fnset->bitmap_base = bswap4u (fnset->bitmap_base);
fnset->numbits = bswap4u (fnset->numbits); fnset->numbits = bswap4u (fnset->numbits);
} }
void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset) void bswap_fragment_number_set_bitmap (nn_fragment_number_set_header_t *fnset, uint32_t *bits)
{ {
const uint32_t n = (fnset->numbits + 31) / 32; const uint32_t n = (fnset->numbits + 31) / 32;
for (uint32_t i = 0; i < n; i++) for (uint32_t i = 0; i < n; i++)
fnset->bits[i] = bswap4u (fnset->bits[i]); bits[i] = bswap4u (bits[i]);
} }

View file

@ -320,8 +320,8 @@ static uint32_t max_rmsg_size_w_hdr (uint32_t max_rmsg_size)
allocate for the worst case, and may waste a few bytes here or allocate for the worst case, and may waste a few bytes here or
there. */ there. */
return return
max_uint32 ((uint32_t) offsetof (struct nn_rmsg, chunk.payload), max_uint32 ((uint32_t) (offsetof (struct nn_rmsg, chunk) + sizeof (struct nn_rmsg_chunk)),
(uint32_t) offsetof (struct nn_rmsg_chunk, payload)) (uint32_t) sizeof (struct nn_rmsg_chunk))
+ max_rmsg_size; + max_rmsg_size;
} }
@ -512,7 +512,7 @@ static void init_rmsg_chunk (struct nn_rmsg_chunk *chunk, struct nn_rbuf *rbuf)
{ {
chunk->rbuf = rbuf; chunk->rbuf = rbuf;
chunk->next = NULL; chunk->next = NULL;
chunk->size = 0; chunk->u.size = 0;
ddsrt_atomic_inc32 (&rbuf->n_live_rmsg_chunks); ddsrt_atomic_inc32 (&rbuf->n_live_rmsg_chunks);
} }
@ -544,10 +544,10 @@ void nn_rmsg_setsize (struct nn_rmsg *rmsg, uint32_t size)
ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rmsg->chunk.rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (ddsrt_atomic_ld32 (&rmsg->refcount) == RMSG_REFCOUNT_UNCOMMITTED_BIAS); assert (ddsrt_atomic_ld32 (&rmsg->refcount) == RMSG_REFCOUNT_UNCOMMITTED_BIAS);
assert (rmsg->chunk.size == 0); assert (rmsg->chunk.u.size == 0);
assert (size8 <= rmsg->chunk.rbuf->max_rmsg_size); assert (size8 <= rmsg->chunk.rbuf->max_rmsg_size);
assert (rmsg->lastchunk == &rmsg->chunk); assert (rmsg->lastchunk == &rmsg->chunk);
rmsg->chunk.size = size8; rmsg->chunk.u.size = size8;
#if USE_VALGRIND #if USE_VALGRIND
VALGRIND_MEMPOOL_CHANGE (rmsg->chunk.rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + rmsg->chunk.size); VALGRIND_MEMPOOL_CHANGE (rmsg->chunk.rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + rmsg->chunk.size);
#endif #endif
@ -587,7 +587,7 @@ static void commit_rmsg_chunk (struct nn_rmsg_chunk *chunk)
{ {
struct nn_rbuf *rbuf = chunk->rbuf; struct nn_rbuf *rbuf = chunk->rbuf;
DDS_LOG(DDS_LC_RADMIN, "commit_rmsg_chunk(%p)\n", (void *) chunk); DDS_LOG(DDS_LC_RADMIN, "commit_rmsg_chunk(%p)\n", (void *) chunk);
rbuf->freeptr = chunk->payload + chunk->size; rbuf->freeptr = (unsigned char *) (chunk + 1) + chunk->u.size;
} }
void nn_rmsg_commit (struct nn_rmsg *rmsg) void nn_rmsg_commit (struct nn_rmsg *rmsg)
@ -602,11 +602,11 @@ void nn_rmsg_commit (struct nn_rmsg *rmsg)
completed before we got to commit. */ completed before we got to commit. */
struct nn_rmsg_chunk *chunk = rmsg->lastchunk; struct nn_rmsg_chunk *chunk = rmsg->lastchunk;
DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) refcount 0x%"PRIx32" last-chunk-size %"PRIu32"\n", DDS_LOG(DDS_LC_RADMIN, "rmsg_commit(%p) refcount 0x%"PRIx32" last-chunk-size %"PRIu32"\n",
(void *) rmsg, rmsg->refcount.v, chunk->size); (void *) rmsg, rmsg->refcount.v, chunk->u.size);
ASSERT_RBUFPOOL_OWNER (chunk->rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (chunk->rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
assert (chunk->size <= chunk->rbuf->max_rmsg_size); assert (chunk->u.size <= chunk->rbuf->max_rmsg_size);
assert ((chunk->size % 8) == 0); assert ((chunk->u.size % 8) == 0);
assert (ddsrt_atomic_ld32 (&rmsg->refcount) >= RMSG_REFCOUNT_UNCOMMITTED_BIAS); assert (ddsrt_atomic_ld32 (&rmsg->refcount) >= RMSG_REFCOUNT_UNCOMMITTED_BIAS);
assert (ddsrt_atomic_ld32 (&rmsg->chunk.rbuf->n_live_rmsg_chunks) > 0); assert (ddsrt_atomic_ld32 (&rmsg->chunk.rbuf->n_live_rmsg_chunks) > 0);
assert (ddsrt_atomic_ld32 (&chunk->rbuf->n_live_rmsg_chunks) > 0); assert (ddsrt_atomic_ld32 (&chunk->rbuf->n_live_rmsg_chunks) > 0);
@ -668,10 +668,10 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8); DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32" => %"PRIu32")\n", (void *) rmsg, size, size8);
ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool); ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool);
ASSERT_RMSG_UNCOMMITTED (rmsg); ASSERT_RMSG_UNCOMMITTED (rmsg);
assert ((chunk->size % 8) == 0); assert ((chunk->u.size % 8) == 0);
assert (size8 <= rbuf->max_rmsg_size); assert (size8 <= rbuf->max_rmsg_size);
if (chunk->size + size8 > rbuf->max_rmsg_size) if (chunk->u.size + size8 > rbuf->max_rmsg_size)
{ {
struct nn_rbufpool *rbufpool = rbuf->rbufpool; struct nn_rbufpool *rbufpool = rbuf->rbufpool;
struct nn_rmsg_chunk *newchunk; struct nn_rmsg_chunk *newchunk;
@ -688,8 +688,8 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size)
chunk = newchunk; chunk = newchunk;
} }
ptr = chunk->payload + chunk->size; ptr = (unsigned char *) (chunk + 1) + chunk->u.size;
chunk->size += size8; chunk->u.size += size8;
DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32") = %p\n", (void *) rmsg, size, ptr); DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32") = %p\n", (void *) rmsg, size, ptr);
#if USE_VALGRIND #if USE_VALGRIND
if (chunk == &rmsg->chunk) { if (chunk == &rmsg->chunk) {
@ -1422,7 +1422,7 @@ void nn_defrag_notegap (struct nn_defrag *defrag, seqno_t min, seqno_t maxp1)
defrag->max_sample = ddsrt_avl_find_max (&defrag_sampletree_treedef, &defrag->sampletree); defrag->max_sample = ddsrt_avl_find_max (&defrag_sampletree_treedef, &defrag->sampletree);
} }
int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set *map, uint32_t maxsz) int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnum, struct nn_fragment_number_set_header *map, uint32_t *mapbits, uint32_t maxsz)
{ {
struct nn_rsample *s; struct nn_rsample *s;
struct nn_defrag_iv *iv; struct nn_defrag_iv *iv;
@ -1446,7 +1446,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
else else
map->numbits = maxfragnum + 1; map->numbits = maxfragnum + 1;
map->bitmap_base = 0; map->bitmap_base = 0;
nn_bitset_one (map->numbits, map->bits); nn_bitset_one (map->numbits, mapbits);
return (int) map->numbits; return (int) map->numbits;
} }
} }
@ -1491,7 +1491,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
/* Clear bitmap, then set bits for gaps in available fragments */ /* Clear bitmap, then set bits for gaps in available fragments */
if (map->numbits > maxsz) if (map->numbits > maxsz)
map->numbits = maxsz; map->numbits = maxsz;
nn_bitset_zero (map->numbits, map->bits); nn_bitset_zero (map->numbits, mapbits);
i = map->bitmap_base; i = map->bitmap_base;
while (iv && i < map->bitmap_base + map->numbits) while (iv && i < map->bitmap_base + map->numbits)
{ {
@ -1509,7 +1509,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
for (; i < map->bitmap_base + map->numbits && i < bound; i++) for (; i < map->bitmap_base + map->numbits && i < bound; i++)
{ {
unsigned x = (unsigned) (i - map->bitmap_base); unsigned x = (unsigned) (i - map->bitmap_base);
nn_bitset_set (map->numbits, map->bits, x); nn_bitset_set (map->numbits, mapbits, x);
} }
/* next sequence of fragments to request retranmsission of starts /* next sequence of fragments to request retranmsission of starts
at fragment containing maxp1 (because we don't have that byte at fragment containing maxp1 (because we don't have that byte
@ -1521,7 +1521,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu
for (; i < map->bitmap_base + map->numbits; i++) for (; i < map->bitmap_base + map->numbits; i++)
{ {
unsigned x = (unsigned) (i - map->bitmap_base); unsigned x = (unsigned) (i - map->bitmap_base);
nn_bitset_set (map->numbits, map->bits, x); nn_bitset_set (map->numbits, mapbits, x);
} }
return (int) map->numbits; return (int) map->numbits;
} }
@ -2268,7 +2268,7 @@ int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t seq)
return (s == NULL || s->u.reorder.maxp1 <= seq); return (s == NULL || s->u.reorder.maxp1 <= seq);
} }
unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set *map, uint32_t maxsz, int notail) unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t maxseq, struct nn_sequence_number_set_header *map, uint32_t *mapbits, uint32_t maxsz, int notail)
{ {
struct nn_rsample *iv; struct nn_rsample *iv;
seqno_t i; seqno_t i;
@ -2305,7 +2305,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m
map->numbits = maxsz; map->numbits = maxsz;
else else
map->numbits = (uint32_t) (maxseq + 1 - base); map->numbits = (uint32_t) (maxseq + 1 - base);
nn_bitset_zero (map->numbits, map->bits); nn_bitset_zero (map->numbits, mapbits);
if ((iv = ddsrt_avl_find_min (&reorder_sampleivtree_treedef, &reorder->sampleivtree)) != NULL) if ((iv = ddsrt_avl_find_min (&reorder_sampleivtree_treedef, &reorder->sampleivtree)) != NULL)
assert (iv->u.reorder.min > base); assert (iv->u.reorder.min > base);
@ -2315,7 +2315,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m
for (; i < base + map->numbits && i < iv->u.reorder.min; i++) for (; i < base + map->numbits && i < iv->u.reorder.min; i++)
{ {
unsigned x = (unsigned) (i - base); unsigned x = (unsigned) (i - base);
nn_bitset_set (map->numbits, map->bits, x); nn_bitset_set (map->numbits, mapbits, x);
} }
i = iv->u.reorder.maxp1; i = iv->u.reorder.maxp1;
iv = ddsrt_avl_find_succ (&reorder_sampleivtree_treedef, &reorder->sampleivtree, iv); iv = ddsrt_avl_find_succ (&reorder_sampleivtree_treedef, &reorder->sampleivtree, iv);
@ -2327,7 +2327,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m
for (; i < base + map->numbits; i++) for (; i < base + map->numbits; i++)
{ {
unsigned x = (unsigned) (i - base); unsigned x = (unsigned) (i - base);
nn_bitset_set (map->numbits, map->bits, x); nn_bitset_set (map->numbits, mapbits, x);
} }
} }
return map->numbits; return map->numbits;

View file

@ -102,12 +102,12 @@ static void maybe_set_reader_in_sync (struct proxy_writer *pwr, struct pwr_rd_ma
} }
} }
static int valid_sequence_number_set (const nn_sequence_number_set_t *snset) static int valid_sequence_number_set (const nn_sequence_number_set_header_t *snset)
{ {
return (fromSN (snset->bitmap_base) > 0 && snset->numbits <= 256); return (fromSN (snset->bitmap_base) > 0 && snset->numbits <= 256);
} }
static int valid_fragment_number_set (const nn_fragment_number_set_t *fnset) static int valid_fragment_number_set (const nn_fragment_number_set_header_t *fnset)
{ {
return (fnset->bitmap_base > 0 && fnset->numbits <= 256); return (fnset->bitmap_base > 0 && fnset->numbits <= 256);
} }
@ -136,7 +136,7 @@ static int valid_AckNack (AckNack_t *msg, size_t size, int byteswap)
count = (nn_count_t *) ((char *) &msg->readerSNState + NN_SEQUENCE_NUMBER_SET_SIZE (msg->readerSNState.numbits)); count = (nn_count_t *) ((char *) &msg->readerSNState + NN_SEQUENCE_NUMBER_SET_SIZE (msg->readerSNState.numbits));
if (byteswap) if (byteswap)
{ {
bswap_sequence_number_set_bitmap (&msg->readerSNState); bswap_sequence_number_set_bitmap (&msg->readerSNState, msg->bits);
*count = bswap4 (*count); *count = bswap4 (*count);
} }
return 1; return 1;
@ -162,7 +162,7 @@ static int valid_Gap (Gap_t *msg, size_t size, int byteswap)
if (size < GAP_SIZE (msg->gapList.numbits)) if (size < GAP_SIZE (msg->gapList.numbits))
return 0; return 0;
if (byteswap) if (byteswap)
bswap_sequence_number_set_bitmap (&msg->gapList); bswap_sequence_number_set_bitmap (&msg->gapList, msg->bits);
return 1; return 1;
} }
@ -287,7 +287,7 @@ static int valid_NackFrag (NackFrag_t *msg, size_t size, int byteswap)
NN_FRAGMENT_NUMBER_SET_SIZE (msg->fragmentNumberState.numbits)); NN_FRAGMENT_NUMBER_SET_SIZE (msg->fragmentNumberState.numbits));
if (byteswap) if (byteswap)
{ {
bswap_fragment_number_set_bitmap (&msg->fragmentNumberState); bswap_fragment_number_set_bitmap (&msg->fragmentNumberState, msg->bits);
*count = bswap4 (*count); *count = bswap4 (*count);
} }
return 1; return 1;
@ -542,7 +542,7 @@ static int add_Gap (struct nn_xmsg *msg, struct writer *wr, struct proxy_reader
gap->gapStart = toSN (start); gap->gapStart = toSN (start);
gap->gapList.bitmap_base = toSN (base); gap->gapList.bitmap_base = toSN (base);
gap->gapList.numbits = numbits; gap->gapList.numbits = numbits;
memcpy (gap->gapList.bits, bits, NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits)); memcpy (gap->bits, bits, NN_SEQUENCE_NUMBER_SET_BITS_SIZE (numbits));
nn_xmsg_submsg_setnext (msg, sm_marker); nn_xmsg_submsg_setnext (msg, sm_marker);
return 0; return 0;
} }
@ -590,12 +590,12 @@ static int acknack_is_nack (const AckNack_t *msg)
even we generate them) */ even we generate them) */
return 0; return 0;
for (i = 0; i < (int) NN_SEQUENCE_NUMBER_SET_BITS_SIZE (msg->readerSNState.numbits) / 4 - 1; i++) for (i = 0; i < (int) NN_SEQUENCE_NUMBER_SET_BITS_SIZE (msg->readerSNState.numbits) / 4 - 1; i++)
x |= msg->readerSNState.bits[i]; x |= msg->bits[i];
if ((msg->readerSNState.numbits % 32) == 0) if ((msg->readerSNState.numbits % 32) == 0)
mask = ~0u; mask = ~0u;
else else
mask = ~(~0u >> (msg->readerSNState.numbits % 32)); mask = ~(~0u >> (msg->readerSNState.numbits % 32));
x |= msg->readerSNState.bits[i] & mask; x |= msg->bits[i] & mask;
return x != 0; return x != 0;
} }
@ -660,7 +660,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
DDS_TRACE("ACKNACK(%s#%"PRId32":%"PRId64"/%"PRIu32":", msg->smhdr.flags & ACKNACK_FLAG_FINAL ? "F" : "", DDS_TRACE("ACKNACK(%s#%"PRId32":%"PRId64"/%"PRIu32":", msg->smhdr.flags & ACKNACK_FLAG_FINAL ? "F" : "",
*countp, fromSN (msg->readerSNState.bitmap_base), msg->readerSNState.numbits); *countp, fromSN (msg->readerSNState.bitmap_base), msg->readerSNState.numbits);
for (uint32_t i = 0; i < msg->readerSNState.numbits; i++) for (uint32_t i = 0; i < msg->readerSNState.numbits; i++)
DDS_TRACE("%c", nn_bitset_isset (msg->readerSNState.numbits, msg->readerSNState.bits, i) ? '1' : '0'); DDS_TRACE("%c", nn_bitset_isset (msg->readerSNState.numbits, msg->bits, i) ? '1' : '0');
seqbase = fromSN (msg->readerSNState.bitmap_base); seqbase = fromSN (msg->readerSNState.bitmap_base);
if (!rst->forme) if (!rst->forme)
@ -863,7 +863,7 @@ static int handle_AckNack (struct receiver_state *rst, nn_etime_t tnow, const Ac
contained in the acknack, and assumes all messages beyond the contained in the acknack, and assumes all messages beyond the
set are NACK'd -- don't feel like tracking where exactly we set are NACK'd -- don't feel like tracking where exactly we
left off ... */ left off ... */
if (i >= msg->readerSNState.numbits || nn_bitset_isset (numbits, msg->readerSNState.bits, i)) if (i >= msg->readerSNState.numbits || nn_bitset_isset (numbits, msg->bits, i))
{ {
seqno_t seq = seqbase + i; seqno_t seq = seqbase + i;
struct whc_borrowed_sample sample; struct whc_borrowed_sample sample;
@ -1352,11 +1352,12 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime
else else
{ {
/* Check if we are missing something */ /* Check if we are missing something */
union { DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0);
struct nn_fragment_number_set set; struct {
char pad[NN_FRAGMENT_NUMBER_SET_SIZE (256)]; struct nn_fragment_number_set_header set;
uint32_t bits[NN_FRAGMENT_NUMBER_SET_MAX_BITS / 32];
} nackfrag; } nackfrag;
if (nn_defrag_nackmap (pwr->defrag, seq, fragnum, &nackfrag.set, 256) > 0) if (nn_defrag_nackmap (pwr->defrag, seq, fragnum, &nackfrag.set, nackfrag.bits, NN_FRAGMENT_NUMBER_SET_MAX_BITS) > 0)
{ {
/* Yes we are (note that this potentially also happens for /* Yes we are (note that this potentially also happens for
samples we no longer care about) */ samples we no longer care about) */
@ -1389,7 +1390,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
DDS_TRACE("NACKFRAG(#%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, seq, msg->fragmentNumberState.bitmap_base, msg->fragmentNumberState.numbits); DDS_TRACE("NACKFRAG(#%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, seq, msg->fragmentNumberState.bitmap_base, msg->fragmentNumberState.numbits);
for (uint32_t i = 0; i < msg->fragmentNumberState.numbits; i++) for (uint32_t i = 0; i < msg->fragmentNumberState.numbits; i++)
DDS_TRACE("%c", nn_bitset_isset (msg->fragmentNumberState.numbits, msg->fragmentNumberState.bits, i) ? '1' : '0'); DDS_TRACE("%c", nn_bitset_isset (msg->fragmentNumberState.numbits, msg->bits, i) ? '1' : '0');
if (!rst->forme) if (!rst->forme)
{ {
@ -1446,7 +1447,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N
DDS_TRACE(" scheduling requested frags ...\n"); DDS_TRACE(" scheduling requested frags ...\n");
for (uint32_t i = 0; i < msg->fragmentNumberState.numbits && enqueued; i++) for (uint32_t i = 0; i < msg->fragmentNumberState.numbits && enqueued; i++)
{ {
if (nn_bitset_isset (msg->fragmentNumberState.numbits, msg->fragmentNumberState.bits, i)) if (nn_bitset_isset (msg->fragmentNumberState.numbits, msg->bits, i))
{ {
struct nn_xmsg *reply; struct nn_xmsg *reply;
if (create_fragment_message (wr, seq, sample.plist, sample.serdata, base + i, prd, &reply, 0) < 0) if (create_fragment_message (wr, seq, sample.plist, sample.serdata, base + i, prd, &reply, 0) < 0)
@ -1642,7 +1643,7 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
1 bit, but check for it just in case, to reduce the number of 1 bit, but check for it just in case, to reduce the number of
sequence number gaps to be processed. */ sequence number gaps to be processed. */
for (listidx = 0; listidx < msg->gapList.numbits; listidx++) for (listidx = 0; listidx < msg->gapList.numbits; listidx++)
if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, listidx)) if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, listidx))
break; break;
last_included_rel = (int32_t) listidx - 1; last_included_rel = (int32_t) listidx - 1;
@ -1693,13 +1694,13 @@ static int handle_Gap (struct receiver_state *rst, nn_etime_t tnow, struct nn_rm
} }
while (listidx < msg->gapList.numbits) while (listidx < msg->gapList.numbits)
{ {
if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, listidx)) if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, listidx))
listidx++; listidx++;
else else
{ {
uint32_t j; uint32_t j;
for (j = listidx + 1; j < msg->gapList.numbits; j++) for (j = listidx + 1; j < msg->gapList.numbits; j++)
if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, j)) if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, j))
break; break;
/* spec says gapList (2) identifies an additional list of sequence numbers that /* spec says gapList (2) identifies an additional list of sequence numbers that
are invalid (8.3.7.4.2), so by that rule an insane start would simply mean the are invalid (8.3.7.4.2), so by that rule an insane start would simply mean the

View file

@ -698,9 +698,10 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
uint32_t i, numbits; uint32_t i, numbits;
seqno_t base; seqno_t base;
DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0);
union { union {
struct nn_fragment_number_set set; struct nn_fragment_number_set_header set;
char pad[NN_FRAGMENT_NUMBER_SET_SIZE (256)]; uint32_t bits[NN_FRAGMENT_NUMBER_SET_MAX_BITS / 32];
} nackfrag; } nackfrag;
int nackfrag_numbits; int nackfrag_numbits;
seqno_t nackfrag_seq = 0; seqno_t nackfrag_seq = 0;
@ -735,7 +736,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
/* Make bitmap; note that we've made sure to have room for the /* Make bitmap; note that we've made sure to have room for the
maximum bitmap size. */ maximum bitmap size. */
numbits = nn_reorder_nackmap (reorder, bitmap_base, pwr->last_seq, &an->readerSNState, max_numbits, notail); numbits = nn_reorder_nackmap (reorder, bitmap_base, pwr->last_seq, &an->readerSNState, an->bits, max_numbits, notail);
base = fromSN (an->readerSNState.bitmap_base); base = fromSN (an->readerSNState.bitmap_base);
/* Scan through bitmap, cutting it off at the first missing sample /* Scan through bitmap, cutting it off at the first missing sample
@ -746,13 +747,13 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
{ {
uint32_t fragnum; uint32_t fragnum;
nackfrag_seq = base + i; nackfrag_seq = base + i;
if (!nn_bitset_isset (numbits, an->readerSNState.bits, i)) if (!nn_bitset_isset (numbits, an->bits, i))
continue; continue;
if (nackfrag_seq == pwr->last_seq) if (nackfrag_seq == pwr->last_seq)
fragnum = pwr->last_fragnum; fragnum = pwr->last_fragnum;
else else
fragnum = UINT32_MAX; fragnum = UINT32_MAX;
nackfrag_numbits = nn_defrag_nackmap (pwr->defrag, nackfrag_seq, fragnum, &nackfrag.set, max_numbits); nackfrag_numbits = nn_defrag_nackmap (pwr->defrag, nackfrag_seq, fragnum, &nackfrag.set, nackfrag.bits, max_numbits);
} }
if (nackfrag_numbits >= 0) { if (nackfrag_numbits >= 0) {
/* Cut the NACK short, NACKFRAG will be added after the NACK's is /* Cut the NACK short, NACKFRAG will be added after the NACK's is
@ -800,7 +801,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
PGUID (rwn->rd_guid), PGUID (pwr->e.guid), rwn->count, PGUID (rwn->rd_guid), PGUID (pwr->e.guid), rwn->count,
base, an->readerSNState.numbits); base, an->readerSNState.numbits);
for (uint32_t ui = 0; ui != an->readerSNState.numbits; ui++) for (uint32_t ui = 0; ui != an->readerSNState.numbits; ui++)
DDS_TRACE("%c", nn_bitset_isset (numbits, an->readerSNState.bits, ui) ? '1' : '0'); DDS_TRACE("%c", nn_bitset_isset (numbits, an->bits, ui) ? '1' : '0');
} }
if (nackfrag_numbits > 0) if (nackfrag_numbits > 0)
@ -819,7 +820,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
nf->writerSN = toSN (nackfrag_seq); nf->writerSN = toSN (nackfrag_seq);
nf->fragmentNumberState.bitmap_base = nackfrag.set.bitmap_base + 1; nf->fragmentNumberState.bitmap_base = nackfrag.set.bitmap_base + 1;
nf->fragmentNumberState.numbits = nackfrag.set.numbits; nf->fragmentNumberState.numbits = nackfrag.set.numbits;
memcpy (nf->fragmentNumberState.bits, nackfrag.set.bits, NN_FRAGMENT_NUMBER_SET_BITS_SIZE (nackfrag_numbits)); memcpy (nf->bits, nackfrag.bits, NN_FRAGMENT_NUMBER_SET_BITS_SIZE (nackfrag_numbits));
{ {
nn_count_t *countp = nn_count_t *countp =
@ -829,7 +830,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p
DDS_TRACE(" + nackfrag #%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, fromSN (nf->writerSN), nf->fragmentNumberState.bitmap_base, nf->fragmentNumberState.numbits); DDS_TRACE(" + nackfrag #%"PRId32":%"PRId64"/%u/%"PRIu32":", *countp, fromSN (nf->writerSN), nf->fragmentNumberState.bitmap_base, nf->fragmentNumberState.numbits);
for (uint32_t ui = 0; ui != nf->fragmentNumberState.numbits; ui++) for (uint32_t ui = 0; ui != nf->fragmentNumberState.numbits; ui++)
DDS_TRACE("%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->fragmentNumberState.bits, ui) ? '1' : '0'); DDS_TRACE("%c", nn_bitset_isset (nf->fragmentNumberState.numbits, nf->bits, ui) ? '1' : '0');
} }
} }