Skip to content

Commit 87d04ed

Browse files
committed
Fix usleep() bug causing excessive host CPU consumption:
The root cause of the bug was in my incorrect #define of MAX_TOD_UPDATE_USECS in featall.h, which was #defined to 1000000 (one million) instead of 999999, thereby causing the TXF rubato_thread to do a usleep for 1000000 (one million) microseconds, which, being invalid, was causing it to not sleep at all and instead return immediately with an error, causing it to loop continuously without sleeping, consuming all available host CPU due to the timer threads being the highest priority thread in Hercules. comm3705.c also had a similar bug wherein it was using "min(1000000,delay)" for one of its usleep(). In addition to fixing the previously mentioned bug, I have also introduced a new USLEEP() macro which calls a new "herc_usleep()" function that will report any usleep() error that might occur. (I purposely did not code it to fix (hide) the problem but rather to just report it so that the caller can thus be fixed to not make invalid usleep calls.) This should close GitHub Issue #589 "Auxiliary threads eating up CPU time" as well as the long running "CPU utilization on Raspberry Pi" thread that took place in the main Hercules group recently.
1 parent cddce71 commit 87d04ed

35 files changed

+85
-65
lines changed

cckddasd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ int rc, i; /* Return code, Loop index */
310310
while (cckd->ras)
311311
{
312312
release_lock(&cckdblk.ralock);
313-
usleep(1);
313+
USLEEP(1);
314314
obtain_lock(&cckdblk.ralock);
315315
}
316316
release_lock(&cckdblk.ralock);

cckddasd64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ int rc, i; /* Return code, Loop index */
140140
while (cckd->ras)
141141
{
142142
release_lock(&cckdblk.ralock);
143-
usleep(1);
143+
USLEEP(1);
144144
obtain_lock(&cckdblk.ralock);
145145
}
146146
release_lock(&cckdblk.ralock);

cgibin.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ int msgcount = 22;
280280
panel_command(command);
281281
// Wait a bit before proceeding in case
282282
// the command issues a lot of messages
283-
usleep(50000);
283+
USLEEP(50000);
284284
}
285285

286286
if((value = cgi_variable(webblk,"msgcount")))
@@ -1623,7 +1623,7 @@ void cgibin_api_v1_syslog(WEBBLK *webblk)
16231623
panel_command(command);
16241624
// Wait a bit before proceeding in case
16251625
// the command issues a lot of messages
1626-
usleep(50000);
1626+
USLEEP(50000);
16271627
hprintf(webblk->sock,"{\"command\": \"%s\",",command);
16281628
}
16291629
else

channel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ typedef struct PREFETCH PREFETCH;
338338
#define IODELAY(_dev) \
339339
do { \
340340
if (sysblk.iodelay > 0 && (_dev)->devchar[10] == 0x20) \
341-
usleep(sysblk.iodelay); \
341+
USLEEP(sysblk.iodelay); \
342342
} while(0)
343343
#else
344344
#define IODELAY(_dev)
@@ -4151,7 +4151,7 @@ do { \
41514151
#ifdef FEATURE_S370_CHANNEL
41524152
if (dev->devtype == 0x2703)
41534153
if (dev->commadpt->lnctl == COMMADPT_LNCTL_ASYNC)
4154-
usleep(5000);
4154+
USLEEP(5000);
41554155
#endif
41564156

41574157
#if DEBUG_DUMP

cmdtab.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,8 @@
18281828
"When the z/Arch Transactional-Execution Facility *is* installed and\n" \
18291829
"enabled the minimum and default intervals are 200 and 400 microseconds.\n" \
18301830
"\n" \
1831-
"The maximum allowed interval is 1000000 microseconds (one second).\n" \
1831+
"The maximum allowed interval is "QSTR( MAX_TOD_UPDATE_USECS )" microseconds (one microsecond\n" \
1832+
"less than one second).\n" \
18321833
"\n" \
18331834
"Also note that due to host system limitations and/or design, some\n" \
18341835
"hosts may round up and/or coalesce short microsecond intervals to a\n" \

comm3705.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ static void *telnet_thread(void *vca)
11581158
ca->hangup = 0;
11591159
for (;;)
11601160
{
1161-
usleep(50000);
1161+
USLEEP(50000);
11621162
if (ca->hangup)
11631163
break;
11641164
/* read_socket has changed from 3.04 to 3.06 - we need old way */
@@ -1224,7 +1224,7 @@ static void *commadpt_thread(void *vca)
12241224
release_lock(&ca->lock);
12251225
if(ca->ackspeed == 0) delay = 50000 + (ca->unack_attn_count * 100000); /* Max's reliable algorithm */
12261226
else delay = (ca->unack_attn_count * ca->unack_attn_count + 1) * ca->ackspeed; /* much faster but TCAM hates it */
1227-
usleep(min(1000000,delay)); /* go to sleep, max. 1 second */
1227+
USLEEP(min((int)(ONE_MILLION-1),delay)); /* go to sleep, max. 1 second */
12281228
obtain_lock(&ca->lock);
12291229
make_sna_requests2(ca);
12301230
make_sna_requests3(ca);

commadpt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,7 @@ static void *commadpt_thread(void *vca)
14741474
if(ca->inbfr.havedata || ca->eol_flag)
14751475
{
14761476
if (ca->term == COMMADPT_TERM_2741) {
1477-
usleep(10000);
1477+
USLEEP(10000);
14781478
}
14791479
ca->curpending=COMMADPT_PEND_IDLE;
14801480
signal_condition(&ca->ipc);

console.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3632,7 +3632,7 @@ int prev_rlen3270;
36323632
{
36333633
// "COMM: pselect() failed: %s"
36343634
CONERROR( HHC90508, "D", strerror( select_errno ));
3635-
usleep( 50000 ); // (wait a bit; maybe it'll fix itself??)
3635+
USLEEP( 50000 ); // (wait a bit; maybe it'll fix itself??)
36363636
}
36373637
continue;
36383638

@@ -3696,7 +3696,7 @@ int prev_rlen3270;
36963696
{
36973697
// "COMM: accept() failed: %s"
36983698
CONERROR( HHC90509, "D", strerror( accept_errno ));
3699-
usleep( 50000 ); // (wait a bit; maybe it'll fix itself??)
3699+
USLEEP( 50000 ); // (wait a bit; maybe it'll fix itself??)
37003700
}
37013701
continue;
37023702
}

ctc_ctci.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ static void* CTCI_ReadThread( void* arg )
10921092
// Don't use sched_yield() here; use an actual non-dispatchable
10931093
// delay instead so as to allow another [possibly lower priority]
10941094
// thread to 'read' (remove) some packet(s) from our frame buffer.
1095-
usleep( CTC_DELAY_USECS ); // (wait a bit before retrying...)
1095+
USLEEP( CTC_DELAY_USECS ); // (wait a bit before retrying...)
10961096
}
10971097
}
10981098

ctc_lcs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ static void UpdatePortStarted( int bStarted, DEVBLK* pDEVBLK, PLCSPORT pLCSPORT
16911691
release_lock( &pLCSPORT->PortEventLock );
16921692

16931693
PTT_DEBUG( "UPDTPORT pause 150", 000, pDEVBLK->devnum, pLCSPORT->bPort );
1694-
usleep( 150*1000 );
1694+
USLEEP( 150*1000 );
16951695
}
16961696

16971697
// ====================================================================
@@ -2191,7 +2191,7 @@ static void LCS_EnqueueReplyFrame( PLCSDEV pLCSDEV, PLCSCMDHDR pReply, size_t iS
21912191
// Wait for LCS_Read to empty the buffer...
21922192

21932193
ASSERT( ENOBUFS == errno );
2194-
usleep( CTC_DELAY_USECS );
2194+
USLEEP( CTC_DELAY_USECS );
21952195
}
21962196
PTT_TIMING( "af repNQ", 0, iSize, 0 );
21972197
PTT_DEBUG( "ENQ RepFrame EXIT ", pReply->bCmdCode, pDEVBLK->devnum, bPort );
@@ -2798,7 +2798,7 @@ static void LCS_EnqueueEthFrame( PLCSPORT pLCSPORT, PLCSDEV pLCSDEV, BYTE* pData
27982798
// Wait for LCS_Read to empty the buffer...
27992799

28002800
ASSERT( ENOBUFS == errno );
2801-
usleep( CTC_DELAY_USECS );
2801+
USLEEP( CTC_DELAY_USECS );
28022802
}
28032803
PTT_TIMING( "af enqueue", 0, iSize, 0 );
28042804
PTT_DEBUG( "ENQ EthFrame EXIT ", 000, pDEVBLK->devnum, bPort );
@@ -4150,7 +4150,7 @@ static void* LCS_AttnThread( void* arg)
41504150
{
41514151

41524152
// Wait a small (but increasing) amount of time.
4153-
usleep(interval);
4153+
USLEEP(interval);
41544154

41554155
//?? // is there still something in our frame buffer?
41564156
//?? if (!pLCSDEV->fDataPending && !pLCSDEV->fReplyPending)

0 commit comments

Comments
 (0)