mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-02 09:40:15 +00:00
[core] use pthread_condattr_setclock rather than pthread_cond_clockwait() #2302
This commit is contained in:
parent
26d6c27329
commit
fec64cfc33
2
USAGE.md
2
USAGE.md
@ -730,7 +730,7 @@ typedef struct ncinput {
|
||||
// timespec to bound blocking. Returns a single Unicode code point, or
|
||||
// (uint32_t)-1 on error. Returns 0 on a timeout. If an event is processed, the
|
||||
// return value is the 'id' field from that event. 'ni' may be NULL. 'ts' is an
|
||||
// a delay bound against gettimeofday() (see pthread_cond_timedwait(3)).
|
||||
// a delay bound against CLOCK_MONOTONIC (see clock_gettime(2)).
|
||||
uint32_t notcurses_get(struct notcurses* n, const struct timespec* ts,
|
||||
ncinput* ni);
|
||||
|
||||
|
@ -1086,7 +1086,7 @@ ncinput_equal_p(const ncinput* n1, const ncinput* n2){
|
||||
// timespec to bound blocking. Returns a single Unicode code point, or
|
||||
// (uint32_t)-1 on error. Returns 0 on a timeout. If an event is processed, the
|
||||
// return value is the 'id' field from that event. 'ni' may be NULL. 'ts' is an
|
||||
// a delay bound against CLOCK_MONOTONIC (see pthread_cond_clockwait(3)).
|
||||
// a delay bound against CLOCK_MONOTONIC (see clock_gettime(2)).
|
||||
API uint32_t notcurses_get(struct notcurses* n, const struct timespec* ts,
|
||||
ncinput* ni)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "compat/compat.h"
|
||||
#include <pthread.h>
|
||||
#ifdef __MINGW64__
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -44,11 +45,38 @@ pid_t waitpid(pid_t pid, int* state, int options){ // FIXME
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_condmonotonic_init(pthread_cond_t* cond){
|
||||
if(pthread_cond_init(cond, &cat)){
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else // not windows
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
// initializes a pthread_cond_t to use CLOCK_MONOTONIC (as opposed to the
|
||||
// default CLOCK_REALTIME) if possible. if not possible, initializes a
|
||||
// regular ol' CLOCK_REALTIME condvar.
|
||||
int pthread_condmonotonic_init(pthread_cond_t* cond){
|
||||
pthread_condattr_t cat;
|
||||
if(pthread_condattr_init(&cat)){
|
||||
return -1;
|
||||
}
|
||||
if(pthread_condattr_setclock(&cat, CLOCK_MONOTONIC)){
|
||||
pthread_condattr_destroy(&cat);
|
||||
return -1;
|
||||
}
|
||||
if(pthread_cond_init(cond, &cat)){
|
||||
pthread_condattr_destroy(&cat);
|
||||
return -1;
|
||||
}
|
||||
pthread_condattr_destroy(&cat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate){
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
if(flags < 0){
|
||||
|
@ -67,10 +67,11 @@ struct winsize {
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifndef _USE_GNU
|
||||
// FIXME actually implement this honoring c: CLOCK_MONOTONIC
|
||||
#define pthread_cond_clockwait(a, b, c, d) pthread_cond_timedwait(a, b, d)
|
||||
#endif
|
||||
// initializes a pthread_cond_t to use CLOCK_MONOTONIC (as opposed to the
|
||||
// default CLOCK_REALTIME) if possible. if not possible, initializes a
|
||||
// regular ol' CLOCK_REALTIME condvar. this eliminates the need for
|
||||
// pthread_cond_clockwait(), which is highly nonportable.
|
||||
int pthread_condmonotonic_init(pthread_cond_t* cond);
|
||||
|
||||
int set_fd_nonblocking(int fd, unsigned state, unsigned* oldstate);
|
||||
int set_fd_cloexec(int fd, unsigned state, unsigned* oldstate);
|
||||
|
@ -17,8 +17,8 @@ static int input_pipefds[2] = {-1, -1};
|
||||
static pthread_t tid;
|
||||
static nciqueue* queue;
|
||||
static nciqueue** enqueue = &queue;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cond; // use pthread_condmonotonic_init()
|
||||
|
||||
static int
|
||||
handle_mouse(const ncinput* ni){
|
||||
@ -71,7 +71,7 @@ uint32_t demo_getc(struct notcurses* nc, const struct timespec* ts, ncinput* ni)
|
||||
pthread_mutex_unlock(&lock);
|
||||
return 0;
|
||||
}
|
||||
pthread_cond_clockwait(&cond, &lock, CLOCK_MONOTONIC, &abstime);
|
||||
pthread_cond_timedwait(&cond, &lock, &abstime);
|
||||
}
|
||||
nciqueue* q = queue;
|
||||
queue = queue->next;
|
||||
@ -153,6 +153,10 @@ int input_dispatcher(struct notcurses* nc){
|
||||
if(input_pipefds[0] >= 0){
|
||||
return -1;
|
||||
}
|
||||
if(pthread_condmonotonic_init(&cond)){
|
||||
fprintf(stderr, "error creating monotonic condvar\n");
|
||||
return -1;
|
||||
}
|
||||
// freebsd doesn't have eventfd :/ and apple doesn't even have pipe2() =[ =[
|
||||
// omg windows doesn't have pipe() fml FIXME
|
||||
#ifndef __MINGW64__
|
||||
@ -182,6 +186,7 @@ int stop_input(void){
|
||||
ret |= close(input_pipefds[0]);
|
||||
ret |= close(input_pipefds[1]);
|
||||
input_pipefds[0] = input_pipefds[1] = -1;
|
||||
ret |= pthread_cond_destroy(&cond);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
18
src/lib/in.c
18
src/lib/in.c
@ -1396,9 +1396,9 @@ create_inputctx(tinfo* ti, FILE* infp, int lmargin, int tmargin, int rmargin,
|
||||
i->isize = BUFSIZ;
|
||||
if( (i->inputs = malloc(sizeof(*i->inputs) * i->isize)) ){
|
||||
if(pthread_mutex_init(&i->ilock, NULL) == 0){
|
||||
if(pthread_cond_init(&i->icond, NULL) == 0){
|
||||
if(pthread_condmonotonic_init(&i->icond) == 0){
|
||||
if(pthread_mutex_init(&i->clock, NULL) == 0){
|
||||
if(pthread_cond_init(&i->ccond, NULL) == 0){
|
||||
if(pthread_condmonotonic_init(&i->ccond) == 0){
|
||||
if((i->stdinfd = fileno(infp)) >= 0){
|
||||
if( (i->initdata = malloc(sizeof(*i->initdata))) ){
|
||||
if(getpipes(i->readypipes) == 0){
|
||||
@ -2079,7 +2079,7 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
|
||||
if(ts == NULL){
|
||||
pthread_cond_wait(&ictx->icond, &ictx->ilock);
|
||||
}else{
|
||||
int r = pthread_cond_clockwait(&ictx->icond, &ictx->ilock, CLOCK_MONOTONIC, ts);
|
||||
int r = pthread_cond_timedwait(&ictx->icond, &ictx->ilock, ts);
|
||||
if(r == ETIMEDOUT){
|
||||
pthread_mutex_unlock(&ictx->ilock);
|
||||
return 0;
|
||||
@ -2119,15 +2119,17 @@ internal_get(inputctx* ictx, const struct timespec* ts, ncinput* ni){
|
||||
return id;
|
||||
}
|
||||
|
||||
// FIXME kill off for API3, and expect an absolute deadline directly
|
||||
static void
|
||||
delaybound_to_deadline(const struct timespec* ts, struct timespec* absdl){
|
||||
if(ts){
|
||||
// incoming ts is a delay bound, but we want an absolute deadline for
|
||||
// pthread_cond_timedwait(). convert it.
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
absdl->tv_sec = ts->tv_sec + tv.tv_sec;
|
||||
absdl->tv_nsec = ts->tv_nsec + tv.tv_usec * 1000;
|
||||
// pthread_cond_timedwait(). convert it, using CLOCK_MONOTONIC (we
|
||||
// initialized the condvar with pthread_condmonotonic_init()).
|
||||
struct timespec tspec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &tspec);
|
||||
absdl->tv_sec = ts->tv_sec + tspec.tv_sec;
|
||||
absdl->tv_nsec = ts->tv_nsec + tspec.tv_nsec;
|
||||
if(absdl->tv_nsec > 1000000000){
|
||||
++absdl->tv_sec;
|
||||
absdl->tv_nsec -= 1000000000;
|
||||
|
Loading…
Reference in New Issue
Block a user