Commit graph

151 commits

Author SHA1 Message Date
Erik Boasson
c3dca32a2f nestable calls to thread_[state_]awake
Remove all the "if asleep then awake ..." stuff from the code by making
awake/asleep calls nestable, whereas before it "awake ; awake" really
meant a transition through "asleep".  This self-evidently necessitates
fixing those places where the old behaviour was relied on upon, but
fortunately those are few.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-04-21 16:05:06 +02:00
Erik Boasson
9b3a71e1ab lift limits on handle allocation and reuse (#95)
The old entity handle mechanism suffered from a number of problems, the
most terrible one being that it would only ever allocate 1000 handles
(not even have at most 1000 in use at the same time).  Secondarily, it
was protected by a single mutex that actually does show up as a limiting
factor in, say, a polling-based throughput test with small messages.
Thirdly, it tried to provide for various use cases that don't exist in
practice but add complexity and overhead.

This commit totally rewrites the mechanism, by replacing the old array
with a hash table and allowing a near-arbitrary number of handles as
well as reuse of handles.  It also removes the entity "kind" bits in the
most significant bits of the handles, because they only resulted in
incorrect checking of argument validity.  All that is taken out, but
there is still more cleaning up to be done.  It furthermore removes an
indirection in the handle-to-entity lookup by embedding the
"dds_handle_link" structure in the entity.

Handle allocation is randomized to avoid the have a high probability of
quickly finding an available handle (the total number of handles is
limited to a number much smaller than the domain from which they are
allocated).  The likelihood of handle reuse is still dependent on the
number of allocated handles -- the fewer handles there are, the longer
the expected time to reuse.  Non-randomized handles would give a few
guarantees more, though.

It moreover moves the code from the "util" to the "core/ddsc" component,
because it really is only used for entities, and besides the new
implementation relies on the deferred freeing (a.k.a. garbage collection
mechanism) implemented in the core.

The actual handle management has two variants, selectable with a macro:
the preferred embodiment uses a concurrent hash table, the actually used
one performs all operations inside a single mutex and uses a
non-concurrent version of the hash table.  The reason the
less-predeferred embodiment is used is that the concurrent version
requires the freeing of entity objects to be deferred (much like the
GUID-to-entity hash tables in DDSI function, or indeed the key value to
instance handle mapping).  That is a fair bit of work, and the
non-concurrent version is a reasonable intermediate step.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-04-21 16:05:06 +02:00
Erik Boasson
dd9aceb713 small performance improvement in RHC
The introduction of properly functioning query conditions adds some
overhead, this commit removes some of that cost by avoiding some calls
to update_conditions when there are no query conditions.

It also removes the has_changed field from the instance, instead using a
local boolean to track whether DATA_AVAILABLE should be raised or not.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-04-21 16:05:06 +02:00
Erik Boasson
671e73ec98 set DATA_AVAILABLE when deleting writer (#148)
Deleting a writer causes unregisters (and possibly disposes) in the rest
of the network, and these updates to the instances should trigger
DATA_AVAILABLE.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-04-11 10:09:35 +02:00
Jeroen Koekkoek
3bdd2a140d Move md5 from ddsi to ddsrt
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-04-11 10:04:06 +02:00
Jeroen Koekkoek
63a5c87baf Fix format strings and signatures for fixed size integers
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-04-11 10:04:06 +02:00
Erik Boasson
f0f76454c7 timely initialization of builtin topics (#138)
The rtps_init function used to initialize all data structures and start
all threads used by the protocol stack, allowing discovery of remote
entities before the built-in topic data structures were initialized.
(Very) early discovery of a remote participant thus led to a crash.

This commit splits the initialisation, providing a separate function for
starting, in particular, the threads receiving data from the network.
In terms of threads created, it matches exactly with the rtps_stop /
rtps_fini split that already existed to address the exact same problem
on termination.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-03-27 09:30:15 +01:00
Erik Boasson
fcb6b935ea support for building/running on OpenIndiana
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-03-23 15:40:29 +01:00
Erik Boasson
7540ac8229 make expensive checks in asserts optional (#125)
This adds an Internal/EnableExpensiveChecks setting for enabling some or all expensive run-time checks to avoid a massive slowdown when assertions are enabled at compile-time. Currently these cover only the writer and reader-history cache checking.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-03-23 15:40:29 +01:00
Jeroen Koekkoek
cd6742ee12 Rearrange and fixup abstraction layer
- Replace os_result by dds_retcode_t and move DDS return code defines down.
  Eliminates the need to convert between different return code types.

- Move dds_time_t down and remove os_time.
  Eliminates the need to convert between different time representations and
  reduces code duplication.

- Remove use of Microsoft source-code annotation language (SAL).
  SAL annotations are Microsoft specific and not very well documented. This
  makes it very difficult for contributers to write.

- Rearrange the abstraction layer to be feature-based. The previous layout
  falsely assumed that the operating system dictates which implementation is
  best suited. For general purpose operating systems this is mostly true, but
  embedded targets require a slightly different approach and may not even offer
  all features. The new layout makes it possible to mix-and-match feature
  implementations and allows for features to not be implemented at all.

- Replace the os prefix by ddsrt to avoid name collisions.

- Remove various portions of unused and unwanted code.

- Export thread names on all supported platforms.

- Return native thread identifier on POSIX compatible platforms.

- Add timed wait for condition variables that takes an absolute time.

- Remove system abstraction for errno. The os_getErrno and os_setErrno were
  incorrect. Functions that might fail now simply return a DDS return code
  instead.

- Remove thread-specific memory abstraction. os_threadMemGet and accompanying
  functions were a mess and their use has been eliminated by other changes in
  this commit.

- Replace attribute (re)defines by ddsrt_ prefixed equivalents to avoid name
  collisions and problems with faulty __nonnull__ attributes.

Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-03-22 15:19:09 +01:00
Erik Boasson
753f910aad consistently use Eclipse Cyclone DDS in API header files
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-15 11:35:00 +01:00
Erik Boasson
1c963b5c3b add torture test for read, query conditions
The "rhc" test runs a random sequence of operations (writes, reads, &c.)
through an RHC with conditions attached to it.  All possible state masks
are used, and query conditions are tried with a condition that only
tests the key value, and one that tests attribute values.  It depends on
the internal checking logic of the RHC, which is currently enabled only
in Debug builds because of the associated run-time overhead.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-12 14:22:06 +01:00
Erik Boasson
a1e827cf7e minor improvements to query condition handling
Various details:
- index replaced throughout by bitmask
- caching a single sample in RHC for deserialising samples when query conditions are used
- short-circuiting the trivial case of an instance matched neither before nor after a change to its state
- combining inc/dec counters into a single delta in condition evaluation
- major speed-up of rhc_check_counts by not checking the condition bit masks every single time

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-11 15:56:58 +01:00
Erik Boasson
96649c435d always zero out non-key fields in invalid samples returned by read/take
The specification says the data in an invalid sample must not be inspected, but that means retrieving the key values from a disposed/unregistered instance after a take is impossible. So, the elegant thing to do is to always provide the key values in the data. The remaining question is then whether the non-key fields should be left in whatever state they happened to be in, or be set to zero. The latter is more consistent in the interface, and that is almost invariably a good thing.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-11 11:12:07 +01:00
Erik Boasson
f0675ca7f1 support for query conditions
This also fixes #87.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-11 11:12:07 +01:00
Erik Boasson
b21c7f032c set masks in samples/instances for query conditions
Whenever a sample or an instance is added, check it against the attached query conditions and indicate which ones match

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 19:19:41 +01:00
Erik Boasson
7739341e71 some errors on locking entities are not worth logging
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 18:23:51 +01:00
Erik Boasson
eee8f6cc59 assign an index to query conditions
This index can then be used as an index into a bitmap to keep track
which query conditions are matched by a sample or an instance.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 18:23:51 +01:00
Erik Boasson
1d746a866d remove unused conds_lock from RHC
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 18:23:51 +01:00
Erik Boasson
de5021dc55 change initialisation of a read condition to set the query condition as well
The read condition and the query condition are represented by the same data type internally, and a read condition therefore has a "m_filter" attribute. It makes more sense to initialise this properly as part of the read condition, instead of initialisation-by-memset in the dds_create_readcond, then overwriting it in dds_create_querycond.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 18:23:51 +01:00
Erik Boasson
fcdffa8cf8 add a separate RHC tracing category
The RHC tracing produces so much junk that is hardly ever useful that a
normal trace should definitely not include it.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 18:23:51 +01:00
Erik Boasson
e0e1e67f24 read condition on view "old" not triggered when reading only "read" samples
A read restricted to samples in "read" state would not enter the condition update code on the false assumption that no read conditions could become triggered if the number of read samples remained the same, but it is nonetheless possible that the instance was transitions from "new" to "old" as a consequence, at least in my interpretation of the spec and the current implementation of read() in Cyclone. This commit brings consistency to the implementation without the intention of confirming the current behaviour as being desirable.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-02-10 18:23:51 +01:00
eboasson
4483807e71
Merge pull request #100 from eboasson/master
the "tracing" category in the configuration should only affect the "trace" sink and leave the "log" sink alone
2019-01-22 09:14:43 +01:00
Erik Boasson
c35c5f9190 the "tracing" category in the configuration should only affect the "trace" sink and leave the "log" sink alone
Fixing that produces a lot of noise on stderr because of inappropriate use of the "info" category in various place and, on macOS, because of a rather stupid way of messing with thread scheduling priorities even when none have been specified explicitly in the configuration.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-21 12:53:55 +01:00
Erik Boasson
8157d3bec8 fix taking only some samples from an instance using a query condition
and add a test case

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-18 12:14:21 +01:00
Erik Boasson
98f757a5ab let dds_get_qos reset the input qos first
Getting a QoS from an entity is akin to reading, and all read/take operations reuse or free/reallocate memory to avoid memory leaks, and so it is a reasonable assumption that calling dds_get_qos repeatedly without intervening calls to dds_reset_qos would not leak any memory either. (This was actually an assumption in the builtin topics test.) Therefore, it is reasonable to first call dds_reset_qos in dds_get_qos. All operations in the API that yield or modify a QoS object result in a properly initialised one, therefore the input to dds_get_qos is necessarily initialised, and so this is safe.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-17 12:34:37 +01:00
Erik Boasson
54b5bed8d2 use enum with values log2(STATUS) for identifying status/listener
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-17 10:18:14 +01:00
Erik Boasson
ba46cb1140 rework listener invocation and entity status flags
Listener/status management invocation was rather expensive, and
especially the cost of checking listeners, then setting status flags and
triggering waitsets ran into severe lock contention.

A major cost was the repeated use of dds_entity_lock and
dds_entity_unlock, these have been eliminated.  Another cost was that
each time an event occurred (with DATA_AVAILABLE the most problematic
one) it would walk the chain of ancestors to see if any had a relevant
listener, and only if none of them had any, it would set the status
flags.

The locking/unlocking of the entity has been eliminated by moving the
listener/status flag manipulation from the general entity lock to its
m_observers_lock.  That lock has a much smaller scope, and consequently
contention has been significantly reduced.

Instead of walking the entity hierarchy looking for listeners, an entity
now inherits the ancestors' listeners.  The set_listener operation has
been made a little more complicated by the need to not only set the
listeners for the specified entity, but to also update any inherited
listeners its descendants.

The commit is a bit larger than strictly needed ... I've started
reformatting the code to reduce the variety of styles ... as there I
haven't been able to find a single tool that does what I want, it may
well end up as manual work.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-17 10:18:14 +01:00
Erik Boasson
2e5ecb2e76 requiring checking the return value of dds_{get,set}_listener is pedantry
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-17 10:18:14 +01:00
Erik Boasson
e4360d25a0 code cleanup: replacement of lots of function-like macros by inline functions, removal of unnecessary casts
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-17 10:18:14 +01:00
Erik Boasson
336a9da8b4 fix read of uninitialized program name in dds_init
dds_init generates an entity name for the participant derived from the
process name and process id, but the name is currently uninitialised
(temporarily so, caused by a recent update to the OS abstraction layer).

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-15 15:07:40 +01:00
Erik Boasson
66076817e1 rework built-in topics again
Move details of built-in topics out of the DDSI core (so the only hooks
remain).  For this, rtps_term had to be split, so now it is "stop"
followed by "fini".

Add a notion of local writers that are not bound to a participant ("local
orphans"), so that the local built-in topic writers can be created during
initialization.  This eliminates the "builtin" participant.  This
uncovered in inconsistency in the unit tests: on the one hand, a newly
created participant is expected to have no child entities; on the other
hand, the built-in topics were expected to be returned by find_topic ...
This inconsistency has been resolved by creating them lazily and
accepting that find_topic can't return them until they have been
created.  Special code was in place in dds_create_reader anyway, so it
is not expected to have any real consequence for applications.

Use a special WHC implementation that regenerates the data on the fly
using the internal discovery tables of DDSI, so that the samples are only
stored by readers.  This eliminates the memory overhead of that existed
previously when the WHC of the writers stored the data.

No longer return topic name and type name in the built-in topics, they
have been extracted already and are not accessible through the normal
interface but do cause problems when comparing QoS.

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-09 08:38:56 +01:00
Erik Boasson
d6dcb0558d fix incorrect QoS compare that breaks creating topics multiple times
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-09 08:38:37 +01:00
Erik Boasson
30f421ea9b remove a stray debugging printf when calling create_topic multiple times for the same topic
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-09 08:38:37 +01:00
Jeroen Koekkoek
0bc263e537 Remove unnecessary os_procName and os_procNamePid functions
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-01-08 16:40:07 +01:00
Jeroen Koekkoek
e25656a4c5 Remove unnecessary CMake modules and fixup os/CMakeLists.txt
Signed-off-by: Jeroen Koekkoek <jeroen@koekkoek.nl>
2019-01-07 18:15:07 +01:00
Erik Boasson
d51a67f74b use plain os_malloc in RHC for performance reasons
simply switching from dds_alloc to os_malloc in alloc_sample removes a redundant memset, which gives 5% improvement in a throughput test (on my laptop); other analogous changes for consistency

Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-04 10:48:57 +01:00
Erik Boasson
ed06ab8f4b trivial modifications to pacify gcc -O2 and clang --analyze
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-02 15:03:20 +01:00
Erik Boasson
65ac9b0711 fix error propagation in dds_get_qos
Signed-off-by: Erik Boasson <eb@ilities.com>
2019-01-02 15:03:18 +01:00
Erik Boasson
179a35d192 fix race conditions in instance id-to-key lookup
this is just an intermediate step: firstly, iid-to-key lookup is a linear scan; secondly, the lookup should happen on the RHC or the WHC and not on some internal map to associates key values with instance handles and is independent of entities

Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-25 12:40:05 +01:00
Erik Boasson
0f7ce1ac43 instance operations must also ensure thread is considered awake or GC may free tkmap instances prematurely
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-25 12:40:05 +01:00
Erik Boasson
84506b8518 rollback changes to dispose counts when resource limits reached during RHC update
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-25 12:40:05 +01:00
Erik Boasson
e96a47f3f9 fix test issues detected by address sanitizer
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-25 12:40:05 +01:00
Erik Boasson
98c53db057 fix leak of config data if a domain id problem leads to an initialization failure
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-25 12:40:05 +01:00
eboasson
97c5e06b6a
Merge pull request #69 from FirasSahliADLinktech/rename-functions
Make function names more consistent:

* ``dds_topic_{get,set}_filter`` -> ``dds_{get,set}_topic_filter``
* ``dds_{get,set}_enabled_status`` -> ``dds_{get,set}_status_mask``
* ``dds_instance_lookup`` -> ``dds_lookup_instance``

Plus removal of defunct ddsv2.h.
2018-12-25 12:38:25 +01:00
Erik Boasson
1a0fcea0c2 replace old builtin topics by new ones and add implementation of DCPSSubscription and DCPSPublication
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-14 14:02:08 +01:00
Erik Boasson
78d49b52a0 add new "builtin topic" types and conversion routines
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-14 14:02:08 +01:00
Erik Boasson
945fc94de7 setting "must inspect result" on return_loan is pedantry
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-14 14:02:08 +01:00
Erik Boasson
e631567c35 extend sertopic interface and move the concept of a type descriptor to just the sertopic definition
Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-14 14:02:08 +01:00
Erik Boasson
29f542b916 iid and tkmap are integral to this DDSI stack and should be part of it
They were made available from the DCPS layer to DDSI using some function pointers, but it makes more sense to have them as part of the DDSI core.

Signed-off-by: Erik Boasson <eb@ilities.com>
2018-12-14 14:02:08 +01:00