Chapter 73 Identifying Threads Used by Connext
Connext uses multiple internal threads for sending and receiving data, maintaining internal state, and calling user code when events occur. Further details regarding Connext’s threading model can be found in Part 11: Connext Threading Model. This section explains how these threads can be identified in your system.
73.1 Checking Thread Names at the OS Level
On some systems, it is possible to check the internal name of RTI threads directly at the operating system level. Threads created by Connext will have RTI-specific thread names, unless otherwise stated in the RTI Connext Core Libraries Platform Notes, which lists architectures that do not support setting thread names.
In general, thread names follow this pattern:
r<Module>[<Participant identifier>][<Thread index>][Transport name>]<Task type>
Where:
- The maximum length for a thread name is 16, including the '\0'.
- r indicates this is a thread from RTI.
- The second and third characters identify the <Module>:
Table 73.1 Module in the Thread Representation
Module |
Thread Representation |
---|---|
Core |
Co |
Transport |
Tr |
Security |
Se |
Distributed Logger |
DI |
Persistence Service |
Ps |
Database Integration Service |
Ds |
Web Integration Service |
Ws |
Monitor |
Mo |
Recording Service |
Re |
Routing Service |
Rs |
- <Participant identifier> is represented with five characters, as follows:
- If participant_name is set: the participant identifier will be the first three characters and the last two characters of the participant_name.
- If participant_name is not set: the identifier is computed as domain_id (three characters), participant_id (two characters).
- If participant_name is not set and the participant_id is set to -1 (default value): the participant identifier is computed as the last five digits of the rtps_instance_id in the participant GUID.
- <Thread index> - index used to distinguish among threads with the same name.
For example, there are several instantiations of the receive thread; the thread index is used to differentiate them:
rCo32265##00Rcv
rCo32265##01Rcv
rCo32265##02Rcv
rCo32265##03Rcv
rCo32265##04Rcv
- <Transport name> is represented with four characters:
Table 73.2 Transport Name in the Thread Representation
Transport Name |
Thread Representation |
---|---|
Transmission Control Protocol version 4 (TCPv4) |
TCP4 |
Transport Layer Security (TLS) |
TLS |
Wide Area Network (WAN) |
WAN |
User Datagram Protocol version 4 (UDPv4) |
UDP4 |
User Datagram Protocol version 6 (UDPv6) |
UDP6 |
- <taskType> - the type of thread is represented with three characters:
Table 73.3 Task Type in the Thread Representation
Transport Name |
Thread Representation |
---|---|
Event |
Evt |
Receive |
Rcv |
Database |
Dtb |
Asynchronous waitSet |
AWs |
Dispatcher |
Dsp |
Asynchronous batch flushing |
ABF |
Topic query publication |
TQP |
DNS tracker |
DNS |
Writer |
Wri |
Logger |
Log |
Control |
Ctr |
Server |
Svr |
Interface tracker |
Itr |
Discovery |
Dis |
Publication |
Pub |
Timer |
Tim |
Connection |
Con |
The details on checking the thread names depend on the operating system. The following is an example output from a publisher application running on VxWorks 6.9.4:
-> taskSpawn "test", 255, <floating_point_option>, 150000, publisher_main, 1, 100
value = 83748528 = 0x4fde6b0
-> i
NAME ENTRY TID PRI STATUS PC SP ERRNO CPU #
---------- ------------ -------- --- ---------- -------- -------- ------- -----
[...]
rCoHelnt##> RTIOsapiThr> 444a010 71 PEND 37b218 53f7c00 0 -
rCoHelnt##> RTIOsapiThr> 540b2b0 71 PEND 37b218 542ac00 0 -
rCoHelnt##> RTIOsapiThr> 543e080 71 PEND 37b218 545dc90 0 -
rCoHelnt##> RTIOsapiThr> 543ea78 71 PEND 37b218 5490c00 0 -
rCoHelnt##> RTIOsapiThr> 5471860 71 PEND 37b218 54c5c90 0 -
Test REDATester_> 456c010 100 STOP 2cf594 501cc94 0 -
rCoHelnt##> RTIOsapiThr> 44d4358 110 PEND+T 37b218 735fda0 3d0010 -
rCoHelnt##> RTIOsapiThr> 44dea68 120 PEND+T 37b218 730fe04 0 -
rTrHelntUD> RTIOsapiThr> 53bbcb0 120 PEND+T 37b218 53c4e2c 0 -
tZynq7Task 2c8e9c 43f0228 240 DELAY 384288 4df5fa4 0 -
miiBusMoni> 2c9974 464bb60 252 DELAY 384288 4654fb8 0 -
test publisher_m> 4fde6b0 255 DELAY 384288 7231ee8 3d0010 -
tIdleTask0 idleTaskEnt> 43d5418 287 READY 37a918 43d53ec 0 -
tIdleTask1 idleTaskEnt> 43d9670 287 READY 37a918 43d9644 0 -
value = 0 = 0x0
-> ti 0x444a010
NAME ENTRY TID PRI STATUS PC SP ERRNO DELAY
---------- ------------ -------- --- ---------- -------- -------- ------- -----
rCoHelnt##> RTIOsapiThr> 444a010 71 PEND 37b218 53f7c00 0 0
full task name : rCoHelnt##00Rcv
task entry : RTIOsapiThreadChild_onSpawned
task affinity : 0x00000000
[...]
Where <floating_point_option> is a numeric value that varies depending on the hardware. See Enabling Floating Point Coprocessor in Kernel Tasks, in the RTI Connext Core Libraries Platform Notes.
In this example, the i
command in VxWorks retrieves information about the running threads. The >
at the end of the name (rCoHelnt##>) indicates that the full thread name could not be displayed, because it exceeds 10 characters. You can use the ti
command in VxWorks (shown above), followed by the thread ID (TID), to retrieve information about a specific thread, including its full name (in this case, rCoHelnt##00Rcv).
The following is an example from running a subscriber on a Linux machine:
$ ./objs/x64Linux3gcc5.4.0/HelloWorld_subscriber
HelloWorld subscriber sleeping for 4 sec...
HelloWorld subscriber sleeping for 4 sec...
HelloWorld subscriber sleeping for 4 sec...
[...]
$ ps -eT | grep rC
22966 22967 pts/19 00:00:00 rCo32265####Dtb
22966 22968 pts/19 00:00:00 rCo32265####Evt
22966 22970 pts/19 00:00:00 rCo32265##00Rcv
22966 22971 pts/19 00:00:00 rCo32265##01Rcv
22966 22972 pts/19 00:00:00 rCo32265##02Rcv
22966 22973 pts/19 00:00:00 rCo32265##03Rcv
22966 22974 pts/19 00:00:00 rCo32265##04Rcv
Note: For transport threads, you have the option of setting your own thread name prefix, which substitutes the first three components (r<Module>[<Participant identifier>]) of the thread name with your own prefix. Setting your own thread name prefix allows you to add extra information to the transport thread, such as your own identifier for the threads or the Topic used. You can optionally set this prefix using the parent.thread_name_prefix field in the transport (for example, in the 53.2.7 TCP/TLS Transport Properties).
Table 73.4 Example Thread Names shows names for the majority of threads created by Connext:
Table 73.4 Example Thread Names
Thread Information |
Name |
Fields |
Example: Domain: 111
|
---|---|---|---|
Receive thread |
rCo%5s##%02dRcv |
Participant identifier, thread index |
rCo11122##33Rcv |
Asynchronous waitset thread |
rCo%5s##%02dAWs |
Participant identifier, thread index |
rCo11122##33AWs |
Database thread |
rCo%5s####Dtb |
Participant identifier |
rCo11122####Dtb |
Dispatcher (i.e., asynchronous publishing) thread |
rCo%5s##%02dDsp |
Participant identifier, thread index |
rCo11122##33Dsp |
Asynchronous batch flushing thread |
rCo%5s####ABF |
Participant identifier |
rCo11122####ABF |
Topic query publication thread |
rCo%5s####TQP |
Participant identifier |
rCo11122####TQP |
Event thread |
rCo%5s####Evt |
Participant identifier |
rCo11122####Evt |
DNS tracker thread |
rCo%5s####DNS |
Participant identifier |
rCo11122####DNS |
Distributed logger writer thread |
rDl#########Wri |
|
rDl#########Wri |
Secure distributed logger thread |
rSe%5s####Log |
Participant identifier |
rSe11122####Log |
TCP control thread |
rTr%5s%04sCtr |
Participant identification, transportName (TCP4) |
rTr11122TCP4Ctr |
TCP event thread |
rTr%5s%04sEvt |
Participant identification, transportName (TCP4) |
rTr11122TCP4Evt |
TLS receive thread |
rTr%5s%04sRcv |
Participant identification, transportName (TLS) |
rTr11122#TLSRcv |
WAN receive thread |
rTr%5s%04sRcv |
Participant identification, transportName (WAN) |
rTr11122#WANRcv |
WAN server thread |
rTr%5s%04sSvr |
Participant identification, transportName (WAN) |
rTr11122#WANCtr |
Interface tracking thread |
rTr%5s%04sITr |
Participant identification, transportName (UDP4, UDP6, TCP4) |
rTr11122UDP4ITr |
Persistence Service receive administration command request thread |
rPs%03d######RAC |
domainId |
rPs111######RAC |
Persistence Service discovery thread |
rPs%09sDis |
Application name |
rPsTestPersiDis |
Persistence Service reception thread (topic) |
rPs%07s%02dRcv |
topic name, thread index |
rPsHello##33Rea |
Persistence Service publication thread |
rPs%07s%02dPub |
topic name, thread index |
rPsHello##33Pub |
Persistence Service reception thread (TopicSet) |
rPsTopic##%02dRcv |
thread index |
rPsHello##33Rea |
Persistence Service event thread |
rPs#########Evt |
|
rPsHello##33Rea |
Recording Service timer thread |
rRe#########Tim |
|
rRe#########Tim |
Monitor event thread |
rMo%5s####Evt |
Participant identifier |
rREHelloWorlPub |
Routing Service polling timer thread |
rRs#########Tim |
|
rRs#########Tim |
Routing Service filter tracker event thread |
rRsFilterTr#Evt |
|
rRsFilterTr#Evt |
Routing Service monitor statistics event thread |
rRsMoSta####Evt |
|
rRsMoSta####Evt |
Routing Service monitor publication event thread |
rRsMoPub####Evt |
|
rRsMoPub####Evt |
Routing Service discovery event thread |
rRsDisc#####Evt |
|
rRsDisc#####Evt |
Routing Service aysnchronous admin thread |
rRsAdmin##%02dAWs |
thread index |
rRsAdmin##33AWs |
Routing Service aysnchronous discovery thread |
rRsDisc###%02dAWs |
thread index |
rRsDisc###33dAWs |
Database Integrated Service discovery thread |
rDs#########Dis |
|
rDs#########Dis |
Database Integrated Service connection thread |
rDs%.9sCon |
Database name |
rDsTestsCon |
Database Integrated Service refresh thread |
rDs%.9sRef |
Database name |
rDsTestsRef |
Database Integrated Service finalization Library thread |
rDsFinalizeLib# |
|
rDsFinalizeLib# |
Database Integrated Service event manager thread |
rDsManager##Evt |
|
rDsManager##Evt |
Web Integrated Service access control list dataBase thread |
rWsACL######Dtb |
|
rWsACL######Dtb |
73.2 Checking Thread Names from the Call Stack
Thread names are only available in a subset of architectures. See the RTI Connext Core Libraries Platform Notes for which architectures support checking thread names at the OS level. This section lists the correspondence between Connext threads and the functions they run. You can use this information to identify Connext threads from the call stack, independently of your architecture. If you are using VxWorks or Integrity, see 73.1 Checking Thread Names at the OS Level.
This is the correspondence between threads and the functions they run:
- Database Thread: RTIEventActiveDatabaseThread_loop()
- (Main) Event Thread: RTIEventActiveGeneratorThread_loop(). Note that this function is generic to all the event threads. That is, all of the event threads run RTIEventActiveGeneratorThread_loop(), which detects and handles events. For this reason, it can be difficult to distinguish the Main Event Thread from other event threads (such as the Topic Query Publication Event Thread); however, to better make this distinction, you can check whether some (sub)functions are called (for example, the subfunctions related to the Asynchronous Batch Flushing Event Thread and Topic Query Publication Event Thread below).
- Receive Thread: COMMENDActiveFacadeReceiver_loop(), which calls to a different function depending on what transport is being used to get the (meta)data:
- Shared Memory: NDDS_Transport_Shmem_receive_rEA()
- UDP: NDDS_Transport_UDP_receive_rEA()
- TCP: NDDS_Transport_TCP_receive_rEA()
- Interface Tracking Thread: RTIOsapiInterfaceTracker_()
- Transport-Specific Threads:
- TCP Control Thread: NDDS_Transport_TCPv4_Plugin_threadLoop()
- TCP Event Thread: RTIEventActiveGeneratorThread_loop() and NDDS_Transport_TCPv4_Plugin_clientOn<event_name>()
- Asynchronous Publishing Thread: RTIEventJobDispatcherThread_spawnedFnc()
- Asynchronous Batch Flushing Event Thread: RTIEventActiveGeneratorThread_loop() and PRESPsWriter_onFlushBatch()
- Topic Query Publication Event Thread: RTIEventActiveGeneratorThread_loop() and PRESPsService_onWriterServiceDispatchActiveTopicQueriesEvent()
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.
73.3 Checking Thread Names Using the Worker’s Name
Connext 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 have an associated worker. In addition, user threads calling certain APIs from Connext 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:
- U - indicator that this is a User Thread
- <threadId> - ID given to the thread by the OS