UaBase_DoCom(); pegs CPU at 100%

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
deviceWISE
Jr. Member
Jr. Member
Posts: 2
Joined: 06 Dec 2017, 23:03

UaBase_DoCom(); pegs CPU at 100%

Post by deviceWISE »

I've patterned my OPC UA Client after the UA Client example. Mine differs from the example in that my code is pulling requests (read/write/disconnect) off a queue. The while loop takes the form of this:

while ( OpcUa_IsGood( uStatus ) )
{
QUEUE_ENTRY *queue_entry;
if ((ret = queue_get(g_ua_queue, (void **)(void *)&queue_entry, 0)) < 0) {
u_status = UaBase_TimedDoCom(5000);
continue;
}
switch (queue_entry->command) {
case READ:
.
.
case WRITE:
.
}
UaBase_TimedDoCom(5000);
}

In this code the queue_get() function has a timeout parameter, which above is set to 0, so if nothing is on the queue it drops out and does the UaBase_TimedDoCom(5000) and goes back to the top of the while and checks the queue again. My problem is this code pegs the CPU at 100%. I assumed that the UaBase_TimedDoCom(5000) would wait 5000ms for work, but it exits immediately out of the method with a good return code. I've modified the code by putting a non-zero timeout value in the queue_get function to try to free up cpu cycles for other threads, but if I make it too high, then the UaBase_TimedDoCom() fails. It seems that the timeout value I use in the queu_get has to be less than the timeout value in the UaBase_TimedDocCom(). I've tried using the UABase_DoCom() hoping that would help, but again, this function doesn't wait and I end up in a very tight spin loop.

Anyone else experience these issues with the UA libraries and the DoCom or TimedDoCom() hogging CPU cycles.?

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re: UaBase_DoCom(); pegs CPU at 100%

Post by Support Team »

Hello deviceWISE,

the UaBase_DoCom() function internally calls the UaBase_TimedDoCom() function with a timeout of 10ms. The timeout is applied to the select() call inside the UaStack.

In the case of using only the client part of the SDK, if there are no sessions that are currently connected there are no sockets to put into the select() call. In that constellation, the select() call returns immediately, which leads to the UaBase_DoCom() call returning immediately. This leads to the 100% CPU usage you are experiencing if you don't wait in the loop calling UaBase_DoCom().

When using the server part of the SDK, there are always sockets that are put into the select() call, leading to the DoCom loop to wait for the timeout if nothing happened on the sockets. As most of our customers also use the server part of the SDK when using the client part, your problem didn't show up yet.

We will look into this issue in the next bugfix release of the SDK. Until then you can work around the issue by adding a call to 'OpcUa_Thread_Sleep(1);' right after UaBase_DoCom(). This call should only be executed if there currently are no connected sessions.
Best regards
Unified Automation Support Team

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re: UaBase_DoCom(); pegs CPU at 100%

Post by Support Team »

Hello deviceWISE,

after investigating this issue further, we found this to be an issue in the UaStack. We will fix this in the next bugfix version 1.8.1 of the AnsiC SDK, so you need to remove the sleep-workaround after you have updated to the new version.

Please note: this issue was accidentally posted in the wrong forum and only affects the AnsiC SDK and does not affect the C++ SDK.
Best regards
Unified Automation Support Team

deviceWISE
Jr. Member
Jr. Member
Posts: 2
Joined: 06 Dec 2017, 23:03

Re: UaBase_DoCom(); pegs CPU at 100%

Post by deviceWISE »

Thank you for the update. I've added the sleep which takes care of the problem, but look forward to the fix in the next release

Post Reply