[input] try to use CLOCK_MONOTONIC for condvar

By default, Pthread condition variables use the wretched
CLOCK_REALTIME for pthread_cond_timedwait(). We reaaaaaaly
want it to use CLOCK_MONOTONIC instead. Where supported,
use pthread_condvar_setclock() to initialize the input
condvar with CLOCK_MONOTONIC, since every other operation
we perform is clocked against it. Closes #2291.
pull/2294/head
nick black 3 years ago committed by nick black
parent a087960ab7
commit 3e0ce64b76

@ -1385,6 +1385,24 @@ getpipes(ipipe pipes[static 2]){
return 0; return 0;
} }
// attempt to set up a pthread_condattr_t such that pthread_cond_timedwait()
// uses CLOCK_MONOTONIC rather than CLOCK_REALTIME. unfortunately, this isn't
// available on all operating systems. return success so long as we can
// initialize the condattr_t; it does not imply successful clock selection =\.
static int
prep_condattr(pthread_condattr_t* cattr){
int e;
if( (e = pthread_condattr_init(cattr)) ){
logerror("couldn't initialize condattr (%s)\n", strerror(e));
return -1;
}
// remember, return success even if this doesn't fly
if( (e = pthread_condattr_setclock(cattr, CLOCK_MONOTONIC)) ){
logwarn("warning: couldn't set CLOCK_MONOTONIC for condvar (%s)\n", strerror(e));
}
return 0;
}
static inline inputctx* static inline inputctx*
create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, int rmargin, create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, int rmargin,
int bmargin, ncsharedstats* stats, unsigned drain, int bmargin, ncsharedstats* stats, unsigned drain,
@ -1396,52 +1414,56 @@ create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, int rmargin,
i->isize = BUFSIZ; i->isize = BUFSIZ;
if( (i->inputs = malloc(sizeof(*i->inputs) * i->isize)) ){ if( (i->inputs = malloc(sizeof(*i->inputs) * i->isize)) ){
if(pthread_mutex_init(&i->ilock, NULL) == 0){ if(pthread_mutex_init(&i->ilock, NULL) == 0){
if(pthread_cond_init(&i->icond, NULL) == 0){ pthread_condattr_t condattr;
if(pthread_mutex_init(&i->clock, NULL) == 0){ if(prep_condattr(&condattr) == 0){
if(pthread_cond_init(&i->ccond, NULL) == 0){ if(pthread_cond_init(&i->icond, &condattr) == 0){
if((i->stdinfd = fileno(infp)) >= 0){ if(pthread_mutex_init(&i->clock, NULL) == 0){
if( (i->initdata = malloc(sizeof(*i->initdata))) ){ if(pthread_cond_init(&i->ccond, &condattr) == 0){
if(getpipes(i->readypipes) == 0){ if((i->stdinfd = fileno(infp)) >= 0){
memset(&i->amata, 0, sizeof(i->amata)); if( (i->initdata = malloc(sizeof(*i->initdata))) ){
if(prep_special_keys(i) == 0){ if(getpipes(i->readypipes) == 0){
if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){ memset(&i->amata, 0, sizeof(i->amata));
i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp); if(prep_special_keys(i) == 0){
memset(i->initdata, 0, sizeof(*i->initdata)); if(set_fd_nonblocking(i->stdinfd, 1, &ti->stdio_blocking_save) == 0){
i->initdata->qterm = ti->qterm; i->termfd = tty_check(i->stdinfd) ? -1 : get_tty_fd(infp);
i->iread = i->iwrite = i->ivalid = 0; memset(i->initdata, 0, sizeof(*i->initdata));
i->cread = i->cwrite = i->cvalid = 0; i->initdata->qterm = ti->qterm;
i->initdata_complete = NULL; i->iread = i->iwrite = i->ivalid = 0;
i->stats = stats; i->cread = i->cwrite = i->cvalid = 0;
i->ti = ti; i->initdata_complete = NULL;
i->stdineof = 0; i->stats = stats;
i->ti = ti;
i->stdineof = 0;
#ifdef __MINGW64__ #ifdef __MINGW64__
i->stdinhandle = ti->inhandle; i->stdinhandle = ti->inhandle;
#endif #endif
i->ibufvalid = 0; i->ibufvalid = 0;
i->linesigs = linesigs_enabled; i->linesigs = linesigs_enabled;
i->tbufvalid = 0; i->tbufvalid = 0;
i->midescape = 0; i->midescape = 0;
i->lmargin = lmargin; i->lmargin = lmargin;
i->tmargin = tmargin; i->tmargin = tmargin;
i->rmargin = rmargin; i->rmargin = rmargin;
i->bmargin = bmargin; i->bmargin = bmargin;
i->drain = drain; i->drain = drain;
i->failed = false; i->failed = false;
logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd); logdebug("input descriptors: %d/%d\n", i->stdinfd, i->termfd);
return i; return i;
}
} }
input_free_esctrie(&i->amata);
} }
input_free_esctrie(&i->amata); endpipes(i->readypipes);
} }
endpipes(i->readypipes); free(i->initdata);
} }
free(i->initdata); pthread_cond_destroy(&i->ccond);
} }
pthread_cond_destroy(&i->ccond); pthread_mutex_destroy(&i->clock);
} }
pthread_mutex_destroy(&i->clock); pthread_cond_destroy(&i->icond);
} }
pthread_cond_destroy(&i->icond); pthread_condattr_destroy(&condattr);
} }
pthread_mutex_destroy(&i->ilock); pthread_mutex_destroy(&i->ilock);
} }

Loading…
Cancel
Save