Allocate xpack::iov once writer has to send data
Currently each DDSC (not DDSI) writer has its own "xpack" for packing submessages into larger messages, but that is a bit wasteful, especially when a lot of samples are being generated that never need to go onto the wire. Lazily allocating them and only pushing message into them when they have a destination address saves memory and improves speed for local communications. Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
		
							parent
							
								
									260f8cd86b
								
							
						
					
					
						commit
						ee9a12b469
					
				
					 2 changed files with 22 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -1103,6 +1103,22 @@ static int write_sample_eot (struct thread_state1 * const ts1, struct nn_xpack *
 | 
			
		|||
      ddsrt_free (plist);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (addrset_empty (wr->as) && (wr->as_group == NULL || addrset_empty (wr->as_group)))
 | 
			
		||||
  {
 | 
			
		||||
    /* No network destination, so no point in doing all the work involved
 | 
			
		||||
       in going all the way.  We do have to record that we "transmitted"
 | 
			
		||||
       this sample, or it might not be retransmitted on request.
 | 
			
		||||
 | 
			
		||||
      (Note that no network destination is very nearly the same as no
 | 
			
		||||
      matching proxy readers.  The exception is the SPDP writer.) */
 | 
			
		||||
    UPDATE_SEQ_XMIT_LOCKED (wr, seq);
 | 
			
		||||
    ddsrt_mutex_unlock (&wr->e.lock);
 | 
			
		||||
    if (plist != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      nn_plist_fini (plist);
 | 
			
		||||
      ddsrt_free (plist);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    /* Note the subtlety of enqueueing with the lock held but
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -200,7 +200,7 @@ struct nn_xpack
 | 
			
		|||
  ddsi_tran_conn_t conn;
 | 
			
		||||
  ddsi_sem_t sem;
 | 
			
		||||
  size_t niov;
 | 
			
		||||
  ddsrt_iovec_t iov[NN_XMSG_MAX_MESSAGE_IOVECS];
 | 
			
		||||
  ddsrt_iovec_t *iov;
 | 
			
		||||
  enum nn_xmsg_dstmode dstmode;
 | 
			
		||||
 | 
			
		||||
  union
 | 
			
		||||
| 
						 | 
				
			
			@ -978,6 +978,7 @@ struct nn_xpack * nn_xpack_new (ddsi_tran_conn_t conn, uint32_t bw_limit, bool a
 | 
			
		|||
  xp = ddsrt_malloc (sizeof (*xp));
 | 
			
		||||
  memset (xp, 0, sizeof (*xp));
 | 
			
		||||
  xp->async_mode = async_mode;
 | 
			
		||||
  xp->iov = NULL;
 | 
			
		||||
 | 
			
		||||
  /* Fixed header fields, initialized just once */
 | 
			
		||||
  xp->hdr.protocol.id[0] = 'R';
 | 
			
		||||
| 
						 | 
				
			
			@ -1030,6 +1031,7 @@ void nn_xpack_free (struct nn_xpack *xp)
 | 
			
		|||
#endif
 | 
			
		||||
  if (gv.thread_pool)
 | 
			
		||||
    ddsi_sem_destroy (&xp->sem);
 | 
			
		||||
  ddsrt_free (xp->iov);
 | 
			
		||||
  ddsrt_free (xp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1411,6 +1413,9 @@ int nn_xpack_addmsg (struct nn_xpack *xp, struct nn_xmsg *m, const uint32_t flag
 | 
			
		|||
  assert ((m->sz % 4) == 0);
 | 
			
		||||
  assert (m->refd_payload == NULL || (m->refd_payload_iov.iov_len % 4) == 0);
 | 
			
		||||
 | 
			
		||||
  if (xp->iov == NULL)
 | 
			
		||||
    xp->iov = malloc (NN_XMSG_MAX_MESSAGE_IOVECS * sizeof (*xp->iov));
 | 
			
		||||
 | 
			
		||||
  if (!nn_xpack_mayaddmsg (xp, m, flags))
 | 
			
		||||
  {
 | 
			
		||||
    assert (xp->niov > 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue