Commit graph

469 commits

Author SHA1 Message Date
Erik Boasson
af19c5681c Use ddsperf in perf scripts and update README
* the scripted throughput test originally used for the throughput graph
  in the README now uses ddsperf;

* a scripted latency test has been added;

* updated the README with the results of these tests (and so now gives
  easy access not only to throughput, but also to latency and memory
  usage, as well as to latency over GbE.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-02 09:53:36 +02:00
Erik Boasson
952029dba0 ddsperf enhancements
* per-thread CPU usage (only those threads where the load is over 0.5%,
  if the sum of threads below that threshold exceeds 0.5%, it prints an
  aggregate for those threads);

* also report RSS;

* network load (only on request, as percentage of specified network
  bandwidth and actual bytes in/out, with the output suppressed if it is
  0%);

* publish CPU usage so a ddsperf instance can display CPU loads for
  its peers;

* handle SIGXFSZ (file size exceeded) by displaying one last line of
  statistics before killing itself; this simply a debugging tool to make
  it easier to get a trace covering a high sample-rate start-up issue;

* default topic changed to "KS" because that allows all the options to
  be used, this has a negative impact on performance (both latency and
  small-sample throughput) but it should be less surprising to users;

* specifying a size is now done by appending "size N" (where N is the
  size in bytes) after a "ping" or "pub" command, rather than it having
  to set it via a command-line option;

Note that some of this is platform-dependent -- SIGXFSZ is currently
only on Linux and macOS, and CPU and network load reporting is currently
only on Linux, macOS and Windows.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-02 09:53:36 +02:00
Erik Boasson
ecb77d481c Add network statistics to ddsrt
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-02 09:53:36 +02:00
Erik Boasson
f9808c7656 Add gathering per-thread CPU usage to ddsrt
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-02 09:53:36 +02:00
Erik Boasson
9b1920862e Init all sample pointers when reusing loan
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-08-02 09:53:36 +02:00
Erik Boasson
9cf4b97f1a Reorganize repository
* Move the project top-level CMakeLists.txt to the root of the project;
  this allows building Cyclone as part of ROS2 without any special
  tricks;

* Clean up the build options:

  ENABLE_SSL:    whether to check for and include OpenSSL support if a
                 library can be found (default = ON); this used to be
                 called DDSC_ENABLE_OPENSSL, the old name is deprecated
                 but still works
  BUILD_DOCS:    whether to build docs (default = OFF)
  BUILD_TESTING: whether to build test (default = OFF)

* Collect all documentation into top-level "docs" directory;

* Move the examples to the top-level directory;

* Remove the unused and somewhat misleading pseudo-default
  cyclonedds.xml;

* Remove unused cmake files

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-30 10:52:44 +02:00
Erik Boasson
4e80559763 Improve multicast related defaults
* use multicast only for participant discovery if using a WiFi network
* default to using unicast for retransmits

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 11:31:51 +02:00
Erik Boasson
fda285e2f5 Add support for Solaris 2.6 on sun4m builds
It is an excellent platform for catching bugs: big-endian, slow enough
that a context switch in the middle of an operation becomes a regular
occurrence, and all that on a SMP box.  Or: I just wanted to see if it
would work.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
Erik Boasson
47920df65c Remove qoslock
Creating a reader/writer in a listener for a built-in topic (as ddsperf
does) recursively ends up in reader/writer matching, recursively
read-locking qoslock.  As nobody ever takes a write-lock, it is a
non-issue provided the rwlock really is an rwlock.  On Solaris 2.6 those
don't exist, and mapping it onto a mutex deadlocks.

This commit removes the thing in its entirety, the fact that it is
currently only ever locked for reading is hint that perhaps it is not
that valuable a thing.  The way it was used in the code would in any
case not have helped with re-matching on QoS changes (save for
duplicating all the matching code), and it is doubtful that serializing
the matching in that case would be necessary in the first place.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
Erik Boasson
96e09d2d4e Use ddsrt_strsep instead of ddsrt_strtok_r
The two do essentially the same think, and ddsrt_strtok_r was only used
in one place.  (Triggered by Solaris 2.6 not providing strtok_r.)

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
Erik Boasson
0d33462664 Use uintptr_t rather than uintmax_t for thread ids
On 32-bit machines uintmax_t is likely to be slower than uintptr_t, and
for that reason, using an uintmax_t for a thread id seems highly
unlikely.  For the current platforms, uintptr_t works.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
Erik Boasson
bf5920385f Account for DDSI_INCLUDE_SSM in parameterlist size
The parameter list table indices ought to be a small as possible to
avoid wasting space, and that means the index size is dependent on
whether or not DDSI_INCLUDE_SSM is set.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
Erik Boasson
5a83d422ea Do not use msg_flags if DDSRT_MSGHDR_FLAGS not set
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
Erik Boasson
20b91796b1 Fix big-endian build failure
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-25 10:59:09 +02:00
TheFixer
1f5083aa44 #213 - Allow readconditions and queryconditions as valid entities for… (#214)
Allow readconditions and queryconditions as valid entities for dds_instance_get_key

Signed-off-by: TheFixer <thefixer@iteazz.com>
2019-07-16 13:09:06 +02:00
Erik Boasson
0dd2155f99 64-bit alignment in serialised data
The payload in a struct serdata_default is assumed to be at a 64-bit
offset for conversion to/from a dds_{i,o}stream_t and getting padding
calculations in the serialised representation correct.  The definition
did not guarantee this and got it wrong on a 32-bit release build.

This commit computes the required padding at compile time and at
verifies the assumption holds where it matters.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-07-16 12:37:33 +02:00
Thijs Sassen
2fe4a4ca35 Fixed failing FreeRTOS target due to recent code refactors
Signed-off-by: Thijs Sassen <thijs.sassen@adlinktech.com>

Adjusted the close methode not to expand by the lwip close macro and added a check for DDSI_INCLUDE_SSM to match the correct pid table size.

Signed-off-by: Thijs Sassen <thijs.sassen@adlinktech.com>
2019-07-11 22:45:17 +02:00
Erik Boasson
ee9a12b469 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>
2019-06-28 12:47:27 +02:00
Erik Boasson
260f8cd86b Lazily allocate state for multi-writer instances
Multiple writers for a single instance is pretty rare, so it makes sense
to lazily allocate the tables for keeping track of them.  The more
elegant solution would be to have a single lock-free table.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
0e888eb2ec Special-case size-1 sequential hopscotch hash table
Rather than allocate a HH_HOP_RANGE large array of buckets, allocate
just 1 if the initial size is 1, then jump to HH_HOP_RANGE as soon as a
second element is added to the table.  There are quite a few cases where
hash tables are created where there never be more than 1 (or even 0)
elements in the table (e.g., a writer without readers, a reader for a
keyless topic).

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
0b8fd9fcc0 Use ddsrt_malloc in macOS socket waitset code
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
12d2a82823 Remove superfluous lock/unlock pairs in read
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
647f7466d6 Address locking order for entity locks
There were inconsistencies in the order in which entity locks were taken
when multiple entities needed to be locked at the same time.  In most
cases, the order was first locking entity X, then locking the parent
entity of X.  However, in some cases the order was reversed, a likely
cause of deadlocks.

This commit sorts these problems, and in particular propagating
operations into children.  The entity refcount is now part of the handle
administration so that it is no longer necessary to lock an entity to
determine whether it is still allowed to be used (previously it had to
check the CLOSED flag afterward).  This allows recursing into the
children while holding handles and the underlying objects alive, but
without violating lock order.

Attendant changes that would warrant there own commits but are too hard
to split off:

* Children are now no longer in a singly linked list, but in an AVL
  tree; this was necessary at some intermediate stage to allow unlocking
  an entity and restarting iteration over all children at the "next"
  child (all thanks to the eternally unique instance handle);

* Waitsets shifted to using arrays of attached entities instead of
  linked lists; this was a consequence of dealing with some locking
  issues in reading triggers and considering which operations on the
  "triggered" and "observed" sets are actually needed.

* Entity status flags and waitset/condition trigger counts are now
  handled using atomic operations.  Entities are now classified as
  having a "status" with a corresponding mask, or as having a "trigger
  count" (conditions).  As there are fewer than 16 status bits, the
  status and its mask can squeeze into the same 32-bits as the trigger
  count.  These atomic updates avoid the need for a separate lock just
  for the trigger/status values and results in a significant speedup
  with waitsets.

* Create topic now has a more rational behaviour when multiple
  participants attempt to create the same topic: each participant now
  gets its own topic definition, but the underlying type representation
  is shared.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
f61b2d54da Add some atomic operations returning old value
* ddsrt_atomic_inc32_ov
* ddsrt_atomic_add32_ov
* ddsrt_atomic_sub32_ov

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
4cdcff8be7 Combine {user,group,topic}_data set_qos tests
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
28317ba49e Give all entities an instance handle (#43)
Add the instance handle to the DDSC entity type, initialize it properly
for all types, and remove the per-type handling of
dds_get_instance_handle.  Those entities that have a DDSI variant take
the instance handle from DDSI (which plays tricks to get the instance
handles of the entities matching the built-in topics).  For those that
do not have a DDSI variant, just generate a unique identifier using the
same generate that DDSI uses.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
9c2f3bdf2b Update leases with atomic ops instead of hashing leases to lease_locks
Lease_renew is the key one, and that one only ever shifts the lease
expiry to the future, providing the lease hasn't expired already.  All
other operations work within leaseheap_lock.

Other updates to lease end time are in set_expiry (which is used in some
special cases).  So ... the number of ways this can go wrong is rather
limited.
2019-06-28 12:47:27 +02:00
Erik Boasson
559c325307 Emulate 64-bit atomic ops if hardware doesn't support them
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
6ad99463ce Fix ddsperf race conditions
Tracking pings and expected number of pongs was done without holding the
correct locks.  Terminate flag was also not a ddsrt_atomic... and hence
flagged by thread sanitizer as a race condition.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
c6c5a872eb Trivial changes for thread sanitizer
Thread sanitizer warns about reads and writes of variables that are
meant to be read without holding a lock:

* Global "keep_going" is now a ddsrt_atomic_uint32_t

* Thread "vtime" is now a ddsrt_atomic_uint32_t

Previously the code relied on the assumption that a 32-bit int would be
treated as atomic, now that is all wrapped in ddsrt_atomic_{ld,st}32.
These being inline functions doing exactly the same thing, there is no
functional change, but it does allow annotating the loads and stores for
via function attributes on the ddsrt_atomic_{ld,st}X.

The concurrent hashtable implementation is replaced by a locked version
of the non-concurrent implementation if thread sanitizer is used.  This
changes eliminates the scores of problems signalled by thread sanitizer
in the GUID-to-entity translation and the key-to-instance id lookups.

Other than that, this replaces a flag used in a waitset test case to be
a ddsrt_atomic_uint32_t.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
0356af470d Fix undefined behaviour reported by ubsan
* calling ddsrt_memdup, ddsrt_strdup with a null pointer (they handle it
  gracefully but forbid it in the interface ...)

* replacement of all pre-C99 flexible arrays (i.e., declaring as
  array[1], then mallocing and using as if array[N]) by C99 flexible
  arrays.

* also add a missing null-pointer test in dds_dispose_ts, and fix the
  test cases that pass a null pointer and a non-writer handle to it to
  instead pass an invalid adress

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
b3d6eec405 Remove prototypes for non-existent functions (#75)
* dds_set_allocator
* dds_set_aligned_allocator

The intent behind them is good, but the approach too primitive ... there
is far more work to be done for managing dynamic allocation in a
meaningful way.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
e016ef20e2 Add changing user data QoS to pubsub
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 12:47:27 +02:00
Erik Boasson
348e68e9df Update FindMaven for Travis/Windows
It appears the Chocolately maven package now installs in different
location (or some shims that used to be installed no longer are).
Because the Travis build uses bash instead of cmd/powershell it doesn't
properly pick up M2_HOME.  This commits adds the new location.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-28 08:54:20 +02:00
Jeroen Koekkoek
23b45b9610 Add CMake module to interact with Sphinx
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-06-23 18:30:35 +02:00
Juan Oxoby
f1db768b39 Add PacketCapture for received messages in UDP (#202)
* Add PacketCapture for receiving messages in UDP

Signed-off-by: Juan Oxoby <joxoby@irobot.com>

* Explicit cast ret to size_t in write_pcap_received()

Signed-off-by: Juan Oxoby <joxoby@irobot.com>
2019-06-21 01:41:33 +08:00
Erik Boasson
95ea8fbf32 Update Travis to use xcode 10.2
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-21 01:15:20 +08:00
Erik Boasson
f6fc1751e9 Treat warnings as errors in CI builds
The CMake files now add "-Werror"/"/WX" if the "WERROR" CMake variable
is true.  By default it is not; the CI builds set this.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Erik Boasson
32b683bf37 Enable "missing prototypes" warning for gcc, clang
Missing prototypes for exported functions cause a really huge issue on
Windows.  Enabling the "missing prototypes" warning makes it much easier
to catch this problem.  Naturally, any warnings caused by this have been
fixed.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Erik Boasson
a4d8aba4f9 Add limited support for QoS changes
This commit adds support for changing all mutable QoS except those that
affect reader/writer matching (i.e., deadline, latency budget and
partition).  This is simply because the recalculation of the matches
hasn't been implemented yet, it is not a fundamental limitation.

Implementing this basically forced fixing up a bunch of inconsistencies
in handling QoS in entity creation.  A silly multi-process ping-pong
test built on changing the value of user data has been added.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Erik Boasson
11a1b9d6f9 Don't perform discovery for subscriptions to built-in topics
These topics are generated internally and never sent over the wire.
Performing full discovery for these is therefore a significant waste of
effort.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Erik Boasson
4a4f092f7b Accept and generate ACKNACK/GAP with empty bitset
The DDSI spec version 2.1 forbade the use of ACKNACK/GAP messages with
an empty bitset, but most vendors used these forms anyway.  The DDSI
stack of Cyclone had code to avoid generating these (though with a bug
where it could generate an invalid GAP), but for no real benefit.
Because the other vendors used them anyway, the stack has always been
perfectly capable of handling them.

DDSI spec version 2.3 allows these forms, and so there's no value in
maintaining the old complications.  This also eliminates the invalid GAP
messages that could be generated at times.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Erik Boasson
8a1980faa6 Remove ArrivalOfDataAssertsPpAndEpLiveliness option
The Compatibility/ArrivalOfDataAssertsPpAndEpLiveliness option was a
rather strange option: receipt of a message is proof of the existence of
the sender, so having an option to not treat it as such only adds
complexity without any benefit.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Erik Boasson
7bffaedde8 Clear padding in outgoing messages
Padding used to not be cleared in this code base, but that has the
downside of valgrind reporting nuisance warnings (which could be fixed
using valgrind's programmatic interface) but also of potentially leaking
information.  The cost of clearing the padding appears to be
insignificant compared to the cost of doing the real work, and so it is
probably best to just clear it.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-13 12:54:35 +02:00
Martin Bremmer
cdfeb0aacc Removed redundant closing parentheses of dds_err_nr().
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
2019-06-13 11:23:27 +02:00
Martin Bremmer
b3b0e52e25 Do not reset dds_sample_rejected_status_t::last_reason
Signed-off-by: Martin Bremmer <martin.bremmer@adlinktech.com>
2019-06-13 11:22:25 +02:00
Erik Boasson
3322fc086d Table-driven parameter list handling
The old parameter list parsing was a mess of custom code with tons of
duplicated checks, even though parameter list parsing really is a fairly
straightforward affair.  This commit changes it to a mostly table-driven
implementation, where the vast majority of the settings are handled by a
generic deserializer and the irregular ones (like reliability, locators)
are handled by custom functions.  The crazy ones (IPv4 address and port
rely on additional state and are completely special-cased).

Given these tables, the serialization, finalisation, validation,
merging, unalias'ing can all be handled by a very small amount of custom
code and an appropriately defined generic function for the common cases.
This also makes it possible to have all QoS validation in place, and so
removes the need for the specialized implementations for the various
entity kinds in the upper layer.

QoS inapplicable to an entity were previously ignored, allowing one to
have invalid values set in a QoS object when creating an entity,
provided that the invalid values are irrelevant to that entity.  Whether
this is a good thing or not is debatable, but certainly it is a good
thing to avoid copying in inapplicable QoS settings.  That in turn means
the behaviour of the API can remain the same.

It does turn out that the code used to return "inconsistent QoS" also
for invalid values.  That has now been rectified, and it returns
"inconsistent QoS" or "bad parameter" as appropriate.  Tests have been
updated accordingly.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:45:53 +02:00
Erik Boasson
8ae81db490 Add get_matched_{publication,subscription}_...
The implementation is provisional (too inefficient), but it works.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:45:53 +02:00
Erik Boasson
ffbf3d7843 Avoid implementation defined types, e.g. unsigned
There are some cases where "int" or "unsigend" actually makes sense, but
in a large number of cases it is really supposed to be either a 32-bit
integer, or, in some cases, at least a 32-bit integer.  It is much to be
preferred to be clear about this.

Another reason is that at least some embedded platforms define, e.g.,
int32_t as "long" instead of "int".  For the ones I am aware of the
"int" and "long" are actually the same 32-bit integer, but that
distinction can cause trouble with printf format specifications.  So
again a good reason to be consistent in avoiding the
implementation-defined ones.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:42:52 +02:00
Erik Boasson
f9219bb5fa Listener getters: set callback to 0 if listener is NULL
The functions did not touch the callback pointer if a null pointer was
passed in for the listener.  That means one would have to initialize the
out parameter before the call or manually check the listener pointer to
know whether the callback point has a defined value following the call.
That's asking for trouble.

Thus, the decision to return a callback of 0 when no listener object is
passed in.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-06-10 10:42:52 +02:00