diff --git a/src/core/ddsi/include/dds/ddsi/q_bswap.h b/src/core/ddsi/include/dds/ddsi/q_bswap.h index 6f8cbff..b186f69 100644 --- a/src/core/ddsi/include/dds/ddsi/q_bswap.h +++ b/src/core/ddsi/include/dds/ddsi/q_bswap.h @@ -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_ntoh_guid (nn_guid_t g); -void bswap_sequence_number_set_hdr (nn_sequence_number_set_t *snset); -void bswap_sequence_number_set_bitmap (nn_sequence_number_set_t *snset); -void bswap_fragment_number_set_hdr (nn_fragment_number_set_t *fnset); -void bswap_fragment_number_set_bitmap (nn_fragment_number_set_t *fnset); +void bswap_sequence_number_set_hdr (nn_sequence_number_set_header_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_header_t *fnset); +void bswap_fragment_number_set_bitmap (nn_fragment_number_set_header_t *fnset, uint32_t *bits); #if defined (__cplusplus) } diff --git a/src/core/ddsi/include/dds/ddsi/q_protocol.h b/src/core/ddsi/include/dds/ddsi/q_protocol.h index 6980285..9d5495c 100644 --- a/src/core/ddsi/include/dds/ddsi/q_protocol.h +++ b/src/core/ddsi/include/dds/ddsi/q_protocol.h @@ -32,25 +32,28 @@ typedef struct { #define NN_SEQUENCE_NUMBER_UNKNOWN_HIGH -1 #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)) -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; uint32_t numbits; - uint32_t bits[]; -} nn_sequence_number_set_t; +} nn_sequence_number_set_header_t; /* SequenceNumberSet size is base (2 words) + numbits (1 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_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 struct nn_fragment_number_set { +typedef struct nn_fragment_number_set_header { nn_fragment_number_t bitmap_base; uint32_t numbits; - uint32_t bits[]; -} nn_fragment_number_set_t; +} nn_fragment_number_set_header_t; /* FragmentNumberSet size is base (2 words) + numbits (1 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_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; #define DDSI_COUNT_MIN (-2147483647 - 1) #define DDSI_COUNT_MAX (2147483647) @@ -224,11 +227,12 @@ typedef struct AckNack { SubmessageHeader_t smhdr; nn_entityid_t readerId; nn_entityid_t writerId; - nn_sequence_number_set_t readerSNState; + nn_sequence_number_set_header_t readerSNState; + uint32_t bits[]; /* nn_count_t count; */ } AckNack_t; #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) typedef struct Gap { @@ -236,9 +240,10 @@ typedef struct Gap { nn_entityid_t readerId; nn_entityid_t writerId; nn_sequence_number_t gapStart; - nn_sequence_number_set_t gapList; + nn_sequence_number_set_header_t gapList; + uint32_t bits[]; } 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) typedef struct InfoTS { @@ -272,7 +277,8 @@ typedef struct NackFrag { nn_entityid_t readerId; nn_entityid_t writerId; 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; */ } NackFrag_t; #define NACKFRAG_SIZE(numbits) (offsetof (NackFrag_t, fragmentNumberState) + NN_FRAGMENT_NUMBER_SET_SIZE (numbits) + 4) diff --git a/src/core/ddsi/include/dds/ddsi/q_radmin.h b/src/core/ddsi/include/dds/ddsi/q_radmin.h index 9b302d5..f05c512 100644 --- a/src/core/ddsi/include/dds/ddsi/q_radmin.h +++ b/src/core/ddsi/include/dds/ddsi/q_radmin.h @@ -46,16 +46,16 @@ struct nn_rmsg_chunk { /* Size is 0 after initial allocation, must be set with nn_rmsg_setsize after receiving a packet from the kernel and before processing it. */ - uint32_t size; - - /* to ensure reasonable alignment of payload[] */ union { + uint32_t size; + + /* to ensure reasonable alignment of payload */ int64_t l; double d; void *p; } u; - /* payload array stretched to whatever it really is */ - unsigned char payload[]; + + /* unsigned char payload[] -- disallowed by C99 because of nesting */ }; struct nn_rmsg { @@ -95,7 +95,7 @@ struct nn_rmsg { 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)) 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); 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); -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); 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_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); -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); struct nn_dqueue *nn_dqueue_new (const char *name, uint32_t max_samples, nn_dqueue_handler_t handler, void *arg); diff --git a/src/core/ddsi/src/q_bswap.c b/src/core/ddsi/src/q_bswap.c index 512c310..c3ee3cf 100644 --- a/src/core/ddsi/src/q_bswap.c +++ b/src/core/ddsi/src/q_bswap.c @@ -53,28 +53,28 @@ nn_guid_t nn_ntoh_guid (nn_guid_t 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); 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; 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->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; for (uint32_t i = 0; i < n; i++) - fnset->bits[i] = bswap4u (fnset->bits[i]); + bits[i] = bswap4u (bits[i]); } diff --git a/src/core/ddsi/src/q_radmin.c b/src/core/ddsi/src/q_radmin.c index 70f7869..039e591 100644 --- a/src/core/ddsi/src/q_radmin.c +++ b/src/core/ddsi/src/q_radmin.c @@ -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 there. */ return - max_uint32 ((uint32_t) offsetof (struct nn_rmsg, chunk.payload), - (uint32_t) offsetof (struct nn_rmsg_chunk, payload)) + max_uint32 ((uint32_t) (offsetof (struct nn_rmsg, chunk) + sizeof (struct nn_rmsg_chunk)), + (uint32_t) sizeof (struct nn_rmsg_chunk)) + 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->next = NULL; - chunk->size = 0; + chunk->u.size = 0; 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_RMSG_UNCOMMITTED (rmsg); 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 (rmsg->lastchunk == &rmsg->chunk); - rmsg->chunk.size = size8; + rmsg->chunk.u.size = size8; #if USE_VALGRIND VALGRIND_MEMPOOL_CHANGE (rmsg->chunk.rbuf->rbufpool, rmsg, rmsg, offsetof (struct nn_rmsg, chunk.u.payload) + rmsg->chunk.size); #endif @@ -587,7 +587,7 @@ static void commit_rmsg_chunk (struct nn_rmsg_chunk *chunk) { struct nn_rbuf *rbuf = chunk->rbuf; 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) @@ -602,11 +602,11 @@ void nn_rmsg_commit (struct nn_rmsg *rmsg) completed before we got to commit. */ struct nn_rmsg_chunk *chunk = rmsg->lastchunk; 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_RMSG_UNCOMMITTED (rmsg); - assert (chunk->size <= chunk->rbuf->max_rmsg_size); - assert ((chunk->size % 8) == 0); + assert (chunk->u.size <= chunk->rbuf->max_rmsg_size); + assert ((chunk->u.size % 8) == 0); 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 (&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); ASSERT_RBUFPOOL_OWNER (rbuf->rbufpool); ASSERT_RMSG_UNCOMMITTED (rmsg); - assert ((chunk->size % 8) == 0); + assert ((chunk->u.size % 8) == 0); 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_rmsg_chunk *newchunk; @@ -688,8 +688,8 @@ void *nn_rmsg_alloc (struct nn_rmsg *rmsg, uint32_t size) chunk = newchunk; } - ptr = chunk->payload + chunk->size; - chunk->size += size8; + ptr = (unsigned char *) (chunk + 1) + chunk->u.size; + chunk->u.size += size8; DDS_LOG(DDS_LC_RADMIN, "rmsg_alloc(%p, %"PRIu32") = %p\n", (void *) rmsg, size, ptr); #if USE_VALGRIND 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); } -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_defrag_iv *iv; @@ -1446,7 +1446,7 @@ int nn_defrag_nackmap (struct nn_defrag *defrag, seqno_t seq, uint32_t maxfragnu else map->numbits = maxfragnum + 1; map->bitmap_base = 0; - nn_bitset_one (map->numbits, map->bits); + nn_bitset_one (map->numbits, mapbits); 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 */ if (map->numbits > maxsz) map->numbits = maxsz; - nn_bitset_zero (map->numbits, map->bits); + nn_bitset_zero (map->numbits, mapbits); i = map->bitmap_base; 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++) { 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 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++) { 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; } @@ -2268,7 +2268,7 @@ int nn_reorder_wantsample (struct nn_reorder *reorder, seqno_t 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; seqno_t i; @@ -2305,7 +2305,7 @@ unsigned nn_reorder_nackmap (struct nn_reorder *reorder, seqno_t base, seqno_t m map->numbits = maxsz; else 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) 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++) { 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; 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++) { unsigned x = (unsigned) (i - base); - nn_bitset_set (map->numbits, map->bits, x); + nn_bitset_set (map->numbits, mapbits, x); } } return map->numbits; diff --git a/src/core/ddsi/src/q_receive.c b/src/core/ddsi/src/q_receive.c index 6964ddf..4d97333 100644 --- a/src/core/ddsi/src/q_receive.c +++ b/src/core/ddsi/src/q_receive.c @@ -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); } -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); } @@ -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)); if (byteswap) { - bswap_sequence_number_set_bitmap (&msg->readerSNState); + bswap_sequence_number_set_bitmap (&msg->readerSNState, msg->bits); *count = bswap4 (*count); } 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)) return 0; if (byteswap) - bswap_sequence_number_set_bitmap (&msg->gapList); + bswap_sequence_number_set_bitmap (&msg->gapList, msg->bits); 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)); if (byteswap) { - bswap_fragment_number_set_bitmap (&msg->fragmentNumberState); + bswap_fragment_number_set_bitmap (&msg->fragmentNumberState, msg->bits); *count = bswap4 (*count); } 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->gapList.bitmap_base = toSN (base); 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); return 0; } @@ -590,12 +590,12 @@ static int acknack_is_nack (const AckNack_t *msg) even we generate them) */ return 0; 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) mask = ~0u; else mask = ~(~0u >> (msg->readerSNState.numbits % 32)); - x |= msg->readerSNState.bits[i] & mask; + x |= msg->bits[i] & mask; 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" : "", *countp, fromSN (msg->readerSNState.bitmap_base), msg->readerSNState.numbits); 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); 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 set are NACK'd -- don't feel like tracking where exactly we 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; struct whc_borrowed_sample sample; @@ -1352,11 +1352,12 @@ static int handle_HeartbeatFrag (struct receiver_state *rst, UNUSED_ARG(nn_etime else { /* Check if we are missing something */ - union { - struct nn_fragment_number_set set; - char pad[NN_FRAGMENT_NUMBER_SET_SIZE (256)]; + DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0); + struct { + struct nn_fragment_number_set_header set; + uint32_t bits[NN_FRAGMENT_NUMBER_SET_MAX_BITS / 32]; } 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 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); 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) { @@ -1446,7 +1447,7 @@ static int handle_NackFrag (struct receiver_state *rst, nn_etime_t tnow, const N DDS_TRACE(" scheduling requested frags ...\n"); 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; 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 sequence number gaps to be processed. */ 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; 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) { - if (!nn_bitset_isset (msg->gapList.numbits, msg->gapList.bits, listidx)) + if (!nn_bitset_isset (msg->gapList.numbits, msg->bits, listidx)) listidx++; else { uint32_t 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; /* 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 diff --git a/src/core/ddsi/src/q_xevent.c b/src/core/ddsi/src/q_xevent.c index 9f1ad3a..4588c0d 100644 --- a/src/core/ddsi/src/q_xevent.c +++ b/src/core/ddsi/src/q_xevent.c @@ -698,9 +698,10 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p uint32_t i, numbits; seqno_t base; + DDSRT_STATIC_ASSERT ((NN_FRAGMENT_NUMBER_SET_MAX_BITS % 32) == 0); union { - struct nn_fragment_number_set set; - 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; int nackfrag_numbits; 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 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); /* 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; nackfrag_seq = base + i; - if (!nn_bitset_isset (numbits, an->readerSNState.bits, i)) + if (!nn_bitset_isset (numbits, an->bits, i)) continue; if (nackfrag_seq == pwr->last_seq) fragnum = pwr->last_fragnum; else 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) { /* 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, base, an->readerSNState.numbits); 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) @@ -819,7 +820,7 @@ static void add_AckNack (struct nn_xmsg *msg, struct proxy_writer *pwr, struct p nf->writerSN = toSN (nackfrag_seq); nf->fragmentNumberState.bitmap_base = nackfrag.set.bitmap_base + 1; 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 = @@ -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); 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'); } }