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:
		
							parent
							
								
									ecbee32422
								
							
						
					
					
						commit
						3afce30c37
					
				
					 7 changed files with 88 additions and 80 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue