From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mimir.eigenstate.org ([206.124.132.107]) by ewsd; Tue May 12 11:39:24 EDT 2020 Received: from abbatoir.fios-router.home (pool-162-83-132-245.nycmny.fios.verizon.net [162.83.132.245]) by mimir.eigenstate.org (OpenSMTPD) with ESMTPSA id ec82a45a (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO); Tue, 12 May 2020 08:39:10 -0700 (PDT) Message-ID: <31D15567B016B6BA3B3B721A5DC1DA6C@eigenstate.org> To: jamos@oboj.net, 9front@9front.org Subject: Re: [9front] etimer() assumes seconds together with APE Date: Tue, 12 May 2020 08:39:09 -0700 From: ori@eigenstate.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: hardware cache > Dear list, > > The function etimer(ulong key, int n) is used in libevent to get a timer > event every 'n' milliseconds. However, if APE is used, etimer() delivers > an event every 'n' second instead. The reason is that sleep() assumes > seconds in APE and milliseconds in Plan 9. > > I am aware that combining Plan 9 libraries with APE is a bit risky. Note, we've *designed* it to work: /sys/src/ape/lib/draw. This should be fine. > When I earlier wanted to use etimer() in the netsurf framebuffer driver, I > assumed it didn't work under APE, but I was not patient enough to wait > 1000 seconds, when I thought it would fire after one second. > > Would this be considered a bug? I'd call it a bug, yeah. It's a bit tricky to fix, since we share code between native and ape-compatible draw -- it can be done with an ifdef, but that's gross. Other approaches could be to add a compat.c file that we link against in ape/libdraw. I've got both approaches below: diff -r 965e0f59464d sys/src/ape/lib/draw/ape.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/src/ape/lib/draw/ape.c Tue May 12 08:37:35 2020 -0700 @@ -0,0 +1,17 @@ +#include + +void +_drawsleep(int ms) +{ + /* + * This is gross. We need draw to compile under APE, + * which defines sleep differently from plan 9. + * Native sleep is in milliseconds, APE sleep is in + * seconds. So we need to call different functions. + */ + struct timespec ts; + ts.tv_sec = ms/1000; + ts.tv_nsec = (ms%1000)*1000*1000; + while(ts.tv_sec != 0 && ts.tv_nsec != 0) + nanosleep(&ts, &ts); +} diff -r 965e0f59464d sys/src/ape/lib/draw/mkfile --- a/sys/src/ape/lib/draw/mkfile Sun May 10 22:51:40 2020 +0200 +++ b/sys/src/ape/lib/draw/mkfile Tue May 12 08:37:35 2020 -0700 @@ -14,6 +14,7 @@ bytesperline.$O\ chan.$O\ cloadimage.$O\ + ape.$O\ computil.$O\ creadimage.$O\ debug.$O\ diff -r 965e0f59464d sys/src/libdraw/event.c --- a/sys/src/libdraw/event.c Sun May 10 22:51:40 2020 +0200 +++ b/sys/src/libdraw/event.c Tue May 12 08:37:35 2020 -0700 @@ -7,6 +7,8 @@ typedef struct Slave Slave; typedef struct Ebuf Ebuf; +extern void _drawsleep(int); + struct Slave { int pid; @@ -176,7 +178,7 @@ n = 1000; t[0] = t[1] = Stimer - MAXSLAVE; do - sleep(n); + _drawsleep(n); while(write(epipe[1], t, 2) == 2); t[0] = MAXSLAVE; write(epipe[1], t, 1); diff -r 965e0f59464d sys/src/libdraw/mkfile --- a/sys/src/libdraw/mkfile Sun May 10 22:51:40 2020 +0200 +++ b/sys/src/libdraw/mkfile Tue May 12 08:37:35 2020 -0700 @@ -13,6 +13,7 @@ bytesperline.$O\ chan.$O\ cloadimage.$O\ + plan9.$O\ computil.$O\ creadimage.$O\ debug.$O\ diff -r 965e0f59464d sys/src/libdraw/plan9.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sys/src/libdraw/plan9.c Tue May 12 08:37:35 2020 -0700 @@ -0,0 +1,8 @@ +#include +#include + +static void +_drawsleep(int ms) +{ + sleep(ms); +} =============================================================== Here's an alternative with ifdef: diff -r 965e0f59464d sys/src/libdraw/event.c --- a/sys/src/libdraw/event.c Sun May 10 22:51:40 2020 +0200 +++ b/sys/src/libdraw/event.c Tue May 12 08:29:57 2020 -0700 @@ -175,9 +175,23 @@ if(n <= 0) n = 1000; t[0] = t[1] = Stimer - MAXSLAVE; - do + do{ + /* + * This is gross. We need draw to compile under APE, + * which defines sleep differently from plan 9. + * Native sleep is in milliseconds, APE sleep is in + * seconds. So we need to call different functions. + */ +#ifdef _POSIX_SOURCE + struct timespec ts; + ts.tv_sec = n/1000; + ts.tv_nsec = (n%1000)*1000*1000; + while(ts.tv_sec != 0 && ts.tv_nsec != 0) + nanosleep(&ts, &ts); +#else sleep(n); - while(write(epipe[1], t, 2) == 2); +#endif + }while(write(epipe[1], t, 2) == 2); t[0] = MAXSLAVE; write(epipe[1], t, 1); _exits(0);