Connext DDS uses multiple internal threads for sending and receiving data, maintaining internal state, and calling user code when events occur. Further details regarding Connext DDS’s threading model can be found in 21. Connext DDS Threading Model. This section explains how these threads can be identified in your system.
On some systems, it is possible to check the internal name of RTI threads directly at the operating system level. See the RTI Connext DDS Core Libraries Platform Notes for which architectures support checking thread names at the operating system (OS) level.
In general, thread names follow this pattern:
r<tastkType><domainId><id>[t<threadIndex>]
Where:
The following threads have names that do not follow the above-mentioned convention:
The details on checking the thread names depends on the operating system. The following is an example output from a publisher application running on VxWorks 6.7:
-> taskSpawn "test", 10, 0x8, 150000, publisher_main, 208, 100
value = 33769616 = 0x2034890
-> i
NAME ENTRY TID PRI STATUS PC SP ERRNO DELAY
---------- ------------ -------- --- ---------- -------- -------- ------- -----
[...]
rR00208529> 3c8e73d 1ba64a4 71 PEND 466340 1bc42c0 3006b 0
rR01208529> 3c8e73d 1bd7a38 71 PEND 466340 1bf5850 3006b 0
rR02208529> 3c8e73d 1bf8288 71 PEND 466340 1c28ce0 3006b 0
rR03208529> 3c8e73d 1bf894c 71 PEND 466340 1c59c60 3006b 0
rR04208529> 3c8e73d 1c6e2d8 71 PEND 466340 1c8c1f0 3006b 0
rR00208529> 3c8e73d 24b86f4 71 PEND 466340 24d6510 3006b 0
rR01208529> 3c8e73d 24e9c74 71 PEND 466340 2507a90 3006b 0
rR02208529> 3c8e73d 251b504 71 PEND 466340 2539420 3006b 0
rR03208529> 3c8e73d 254ce14 71 PEND 466340 256ac30 3006b 0
rR04208529> 3c8e73d 256d7cc 71 PEND 466340 259eb00 3006b 0
rEvt208529> 3c8e73d 1511ae4 110 PEND+T 466340 4063380 3d0004 43
rEvt208529> 3c8e73d 20b1c14 110 PEND+T 466340 20cfc30 3d0004 22
rDtb208529> 3c8e73d 153bc48 120 PEND+T 466340 4017070 3d0004 1546
RTIOsapiIn> 3c8e73d 3ffb810 120 PEND+T 466340 1b92de0 3d0004 13
rDtb208529> 3c8e73d 2079540 120 PEND+T 466340 2080d70 3006b 926
RTIOsapiIn> 3c8e73d 20625ac 120 READY 466340 24a4fa0 3d0004 0
value = 0 = 0x0
Thread names are only available in a subset of architectures. See the RTI Connext DDS Core Libraries Platform Notes for which architectures support checking thread names at the OS level. This section lists the correspondence between Connext DDS threads and the functions they run. You can use this information to identify Connext DDS threads from the call stack, independently of your architecture. If you are using VxWorks or Integrity, see 25.5.1 Checking Thread Names at the OS Level.
This is the correspondence between threads and the functions they run:
For example, if you are on GNU/Linux, you can run the following command on gdb to get the call stack:
(gdb) thread apply all backtrace
The same information can be seen with Visual Studio. To see this information in Visual Studio, select Debug > Windows > Threads, then do Ctrl+D, T. You will need to add a breakpoint and start the application in debug mode.
Connext DDS uses the concept of a worker as an abstraction for threads. Workers are RTI-specific entities used internally to manage critical sections and to provide access to thread-specific storage. Most of the threads created by Connext DDS have an associated worker. In addition, user threads calling certain APIs from Connext DDS will have a worker associated with them. Workers are given a name when they are created. If you have the proper debug symbols, you can use the worker’s name to identify the thread (on a debugger, for instance).
To check the workers’ names, first locate these workers in the threads. You can do that by selecting a thread and printing its full backtrace. Another option is moving up and down through the frames on the thread’s stack. The worker will be either a local variable or the last argument to one of the RTI functions. Here is an example using gdb on GNU/Linux to identify a thread with the method just described:
(gdb) info thread
Id Target Id Frame
* 1 Thread 0x7ffff7fce700 (LWP 6801) "HelloWorld_publ" __clock_nanosleep (clock_id=<optimized out>, flags=0, req=0x7fffffffcb20, rem=0x7fffffffcb30) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:48
2 Thread 0x7ffff6ec1700 (LWP 6805) "HelloWorld_publ" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:225
3 Thread 0x7ffff66c0700 (LWP 6806) "HelloWorld_publ" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:225
[...]
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff6ec1700 (LWP 6805))]
(gdb) backtrace full
[...]
#3 0x0000000000c6095b in RTIEventActiveDatabaseThread_loop (param=0x13fc8c0) at ActiveDatabase.c:156
timeStr = 0x7ffff6ec0dc0 "{0000003d,00000000}"
t = 0x13fc8c0
canBeDeleted = 0
timeBuf = "{0000003d,00000000}"
workerName = 0x1351cb0 "rDtb2081a9101"
METHOD_NAME = 0x100a0d0 "RTIEventActiveDatabaseThread_loop"
[...]
As you can see in the example, workers follow the same naming convention as threads (in some cases, a shortened version of it). Workers associated with user threads use the following convention: U<threadId>, where:
© 2020 RTI