Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 32 additions & 48 deletions src/dep/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,65 +693,49 @@ getTxTimestamp(NetPath* netPath,TimeInternal* timeStamp) {
ssize_t length;
fd_set tmpSet;
struct timeval timeOut = {0,0};
int val = 1;
/* int val = 1; */
int i = 0;
int rc;
if(netPath->txTimestampFailure)
goto failure;

FD_ZERO(&tmpSet);
FD_SET(netPath->eventSock, &tmpSet);

if(select(netPath->eventSock + 1, &tmpSet, NULL, NULL, &timeOut) > 0) {
if (FD_ISSET(netPath->eventSock, &tmpSet)) {
do {
if ((rc = select(netPath->eventSock + 1, &tmpSet, NULL, NULL, &timeOut)) > 0) {
if (FD_ISSET(netPath->eventSock, &tmpSet)) {

length = netRecvEvent(G_ptpClock->msgIbuf, timeStamp,
netPath, MSG_ERRQUEUE);
if (length > 0) {
DBG("getTxTimestamp: Grabbed sent msg via errqueue: %d bytes, at %d.%d\n", length, timeStamp->seconds, timeStamp->nanoseconds);
return TRUE;
} else if (length < 0) {
DBG("getTxTimestamp: Failed to poll error queue for SO_TIMESTAMPING transmit time\n");
G_ptpClock->counters.messageRecvErrors++;
} else if (length == 0) {
DBG("getTxTimestamp: Received no data from TX error queue\n");
}
}
}

/* we're desperate here, aren't we... */
for(i = 0; i < 3; i++) {
length = netRecvEvent(G_ptpClock->msgIbuf, timeStamp, netPath, MSG_ERRQUEUE);
if(length > 0) {
DBG("getTxTimestamp: SO_TIMESTAMPING - delayed TX timestamp caught\n");
length = netRecvEvent(G_ptpClock->msgIbuf, timeStamp,
netPath, MSG_ERRQUEUE);
if (length > 0) {
DBG("getTxTimestamp: Grabbed sent msg via errqueue: %d bytes, at %d.%d\n", length, timeStamp->seconds, timeStamp->nanoseconds);
return TRUE;
} else if (length < 0) {
DBG("getTxTimestamp: Failed to poll error queue for SO_TIMESTAMPING transmit time\n");
G_ptpClock->counters.messageRecvErrors++;
} else if (length == 0) {
DBG("getTxTimestamp: Received no data from TX error queue\n");
}
}
usleep(10);
}

/* try for the last time: sleep and poll the error queue, if nothing, consider SO_TIMESTAMPING inoperable */
usleep(LATE_TXTIMESTAMP_US);

length = netRecvEvent(G_ptpClock->msgIbuf, timeStamp, netPath, MSG_ERRQUEUE);

if(length > 0) {
DBG("getTxTimestamp: SO_TIMESTAMPING - even more delayed TX timestamp caught\n");
return TRUE;
} else {
DBG("getTxTimestamp: SO_TIMESTAMPING - TX timestamp retry failed - will use loop from now on\n");
}

failure:
DBG("net.c: SO_TIMESTAMPING TX software timestamp failure - reverting to SO_TIMESTAMPNS\n");
/* unset SO_TIMESTAMPING first! otherwise we get an always-exiting select! */
val = 0;
if(setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPING, &val, sizeof(int)) < 0) {
DBG("getTxTimestamp: failed to unset SO_TIMESTAMPING");
}
val = 1;
if(setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPNS, &val, sizeof(int)) < 0) {
DBG("getTxTimestamp: failed to revert to SO_TIMESTAMPNS");
} else {
sleep_monotonic(100);
}
} while (rc == -1 && errno == EINTR);

/* wait for tx stamp */
for (i = 0; i < 2000; i++) {
sleep_monotonic(500);
length = netRecvEvent(G_ptpClock->msgIbuf, timeStamp, netPath, MSG_ERRQUEUE);
if (length > 0) {
DBG("getTxTimestamp: SO_TIMESTAMPING - delayed TX timestamp caught\n");
return TRUE;
}
}
DBG("getTxTimestamp: SO_TIMESTAMPING - TX timestamp retry failed");

failure:

return FALSE;
}
#endif /* SO_TIMESTAMPING */
Expand Down Expand Up @@ -2290,7 +2274,7 @@ netRefreshIGMP(NetPath * netPath, const RunTimeOpts * rtOpts, PtpClock * ptpCloc
}

/* suspend process 100 milliseconds, to make sure the kernel sends the IGMP_leave properly */
usleep(100*1000);
sleep_monotonic(100000000);

if (!netInitMulticast(netPath, rtOpts)) {
return FALSE;
Expand Down
1 change: 1 addition & 0 deletions src/dep/ntpengine/ntpdcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ NTPDCquery(
DBG("NTPDCquery(): select EINTR caught");
retries--;
res = 1;
sleep_monotonic(1500);
continue;
}
DBG("NTPDCquery(): select() error - not EINTR: %s\n", strerror(errno));
Expand Down
1 change: 1 addition & 0 deletions src/dep/ptpd_dep.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ void displayStatus(PtpClock *ptpClock, const char *prefixMessage);
void displayPortIdentity(PortIdentity *port, const char *prefixMessage);
int snprint_PortIdentity(char *s, int max_len, const PortIdentity *id);
Boolean nanoSleep(TimeInternal*);
int sleep_monotonic(int nanoseconds);
void getTime(TimeInternal*);
void getTimeMonotonic(TimeInternal*);
void setTime(TimeInternal*);
Expand Down
4 changes: 2 additions & 2 deletions src/dep/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -879,11 +879,11 @@ ptpdStartup(int argc, char **argv, Integer16 * ret, RunTimeOpts * rtOpts)
* On some systems this happened after we tried re-acquiring
* the lock, so the lock would fail. Hence, we wait.
*/
for (i = 0; i < 1000000; i++) {
for (i = 0; i < 1000; i++) {
/* Once we've been reaped by init, parent PID will be 1 */
if(getppid() == 1)
break;
usleep(1);
sleep_monotonic(1000000);
}
}

Expand Down
17 changes: 17 additions & 0 deletions src/dep/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,23 @@ nanoSleep(TimeInternal * t)
return TRUE;
}

int
sleep_monotonic(int nanoseconds)
{
int rc;
struct timespec request, remain;
request.tv_sec = 0;
request.tv_nsec = nanoseconds;

while ((rc = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, &remain)) == EINTR) {
/* restart sleep for the remaining time */
request.tv_nsec = remain.tv_nsec;
}

return rc;
}


#ifdef __QNXNTO__

static const struct sigevent* timerIntHandler(void* data, int id) {
Expand Down
6 changes: 3 additions & 3 deletions src/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ protocol(RunTimeOpts *rtOpts, PtpClock *ptpClock)
* that is keep processing signals. If init failed, wait for n seconds
* until next retry, do not exit. Wait in chunks so SIGALRM can interrupt.
*/
if(ptpClock->initFailure) {
usleep(10000);
ptpClock->initFailureTimeout--;
if (ptpClock->initFailure) {
sleep_monotonic(10000000);
ptpClock->initFailureTimeout--;
}

if(!ptpClock->initFailure || ptpClock->initFailureTimeout <= 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/signaling.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ cancelNodeGrants(UnicastGrantTable *nodeTable, const RunTimeOpts *rtOpts, PtpClo
if(grantData->granted) {
cancelUnicastTransmission(grantData, rtOpts, ptpClock);
/* sleep 250 to 500 us so that we don't flood the node */
usleep(250+round(getRand()*250));
sleep_monotonic((250 + (rand() % 250)) * 1000);
}

}
Expand Down