Revision: 3664 Author: eliot Date: 2016-03-29 13:18:32 -0700 (Tue, 29 Mar 2016) Log Message: ----------- Format aio.c according to Eliot's predilections, before adding kqueue and epoll support.
Modified Paths: -------------- branches/Cog/platforms/unix/vm/aio.c
Modified: branches/Cog/platforms/unix/vm/aio.c =================================================================== --- branches/Cog/platforms/unix/vm/aio.c 2016-03-29 02:48:03 UTC (rev 3663) +++ branches/Cog/platforms/unix/vm/aio.c 2016-03-29 20:18:32 UTC (rev 3664) @@ -27,7 +27,7 @@
/* Author: Ian.Piumarta@squeakland.org * - * Last edited: 2006-04-23 12:55:59 by piumarta on emilia.local + * Last edited: Tue Mar 29 13:06:00 PDT 2016 */
#include "sqaio.h" @@ -40,27 +40,27 @@ # include <sys/types.h> # include <unistd.h> # endif /* HAVE_UNISTD_H */ - + # ifdef NEED_GETHOSTNAME_P extern int gethostname(); # endif - + # include <stdio.h> # include <signal.h> # include <errno.h> # include <fcntl.h> # include <sys/ioctl.h> - + # ifdef HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif - + # ifdef HAS_SYS_SELECT_H # include <sys/select.h> # endif - + # ifndef FIONBIO # ifdef HAVE_SYS_FILIO_H # include <sys/filio.h> @@ -92,107 +92,126 @@ # include <sys/ioctl.h> # include <fcntl.h>
-#endif +#endif /* !HAVE_CONFIG_H */
#if defined(AIO_DEBUG) -long aioLastTick= 0; -long aioThisTick= 0; +long aioLastTick = 0; +long aioThisTick = 0; + #endif
#define _DO_FLAG_TYPE() do { _DO(AIO_R, rd) _DO(AIO_W, wr) _DO(AIO_X, ex) } while (0)
-static aioHandler rdHandler[FD_SETSIZE]; -static aioHandler wrHandler[FD_SETSIZE]; -static aioHandler exHandler[FD_SETSIZE]; +static aioHandler rdHandler[FD_SETSIZE]; +static aioHandler wrHandler[FD_SETSIZE]; +static aioHandler exHandler[FD_SETSIZE];
-static void *clientData[FD_SETSIZE]; +static void *clientData[FD_SETSIZE];
-static int maxFd; -static fd_set fdMask; /* handled by aio */ -static fd_set rdMask; /* handle read */ -static fd_set wrMask; /* handle write */ -static fd_set exMask; /* handle exception */ -static fd_set xdMask; /* external descriptor */ +static int maxFd; +static fd_set fdMask; /* handled by aio */ +static fd_set rdMask; /* handle read */ +static fd_set wrMask; /* handle write */ +static fd_set exMask; /* handle exception */ +static fd_set xdMask; /* external descriptor */
-static void undefinedHandler(int fd, void *clientData, int flags) +static void +undefinedHandler(int fd, void *clientData, int flags) { - fprintf(stderr, "undefined handler called (fd %d, flags %x)\n", fd, flags); + fprintf(stderr, "undefined handler called (fd %d, flags %x)\n", fd, flags); }
#ifdef AIO_DEBUG -const char *__shortFileName(const char *full__FILE__name) -{ const char *p = strrchr(full__FILE__name,'/'); - return p ? p + 1 : full__FILE__name;} -static char *handlerName(aioHandler h) +const char * +__shortFileName(const char *full__FILE__name) { - if (h == undefinedHandler) return "undefinedHandler"; + const char *p = strrchr(full__FILE__name, '/'); + + return p ? p + 1 : full__FILE__name; +} +static char * +handlerName(aioHandler h) +{ + if (h == undefinedHandler) + return "undefinedHandler"; #ifdef DEBUG_SOCKETS - { - extern char *socketHandlerName(aioHandler); - return socketHandlerName(h); - } + { + extern char *socketHandlerName(aioHandler); + + return socketHandlerName(h); + } #endif - return "***unknown***"; + return "***unknown***"; } + #endif
/* initialise asynchronous i/o */
-void aioInit(void) +void +aioInit(void) { - extern void forceInterruptCheck(int); /* not really, but hey */ + extern void forceInterruptCheck(int); /* not really, but hey */
- FD_ZERO(&fdMask); - FD_ZERO(&rdMask); - FD_ZERO(&wrMask); - FD_ZERO(&exMask); - FD_ZERO(&xdMask); - maxFd= 0; - signal(SIGPIPE, SIG_IGN); - signal(SIGIO, forceInterruptCheck); + FD_ZERO(&fdMask); + FD_ZERO(&rdMask); + FD_ZERO(&wrMask); + FD_ZERO(&exMask); + FD_ZERO(&xdMask); + maxFd = 0; + signal(SIGPIPE, SIG_IGN); + signal(SIGIO, forceInterruptCheck); }
/* disable handlers and close all handled non-exteral descriptors */
-void aioFini(void) +void +aioFini(void) { - int fd; - for (fd= 0; fd < maxFd; fd++) - if (FD_ISSET(fd, &fdMask) && !(FD_ISSET(fd, &xdMask))) - { - aioDisable(fd); - close(fd); - FD_CLR(fd, &fdMask); - FD_CLR(fd, &rdMask); - FD_CLR(fd, &wrMask); - FD_CLR(fd, &exMask); - } - while (maxFd && !FD_ISSET(maxFd - 1, &fdMask)) - --maxFd; - signal(SIGPIPE, SIG_DFL); + int fd; + + for (fd = 0; fd < maxFd; fd++) + if (FD_ISSET(fd, &fdMask) && !(FD_ISSET(fd, &xdMask))) { + aioDisable(fd); + close(fd); + FD_CLR(fd, &fdMask); + FD_CLR(fd, &rdMask); + FD_CLR(fd, &wrMask); + FD_CLR(fd, &exMask); + } + while (maxFd && !FD_ISSET(maxFd - 1, &fdMask)) + --maxFd; + signal(SIGPIPE, SIG_DFL); }
-/* answer whether i/o becomes possible within the given number of microSeconds */ +/* + * answer whether i/o becomes possible within the given number of + * microSeconds + */ #define max(x,y) (((x)>(y))?(x):(y))
-long pollpip = 0; /* set in sqUnixMain.c by -pollpip arg */ +long pollpip = 0; /* set in sqUnixMain.c by -pollpip arg */ + #if COGMTVM -/* If on the MT VM and pollpip > 1 only pip if a threaded FFI call is in +/* + * If on the MT VM and pollpip > 1 only pip if a threaded FFI call is in * progress, which we infer from disownCount being non-zero. */ extern long disownCount; + # define SHOULD_TICK() (pollpip == 1 || (pollpip > 1 && disownCount)) #else # define SHOULD_TICK() pollpip #endif
-static char *ticks= "-\|/"; -static char *ticker= ""; +static char *ticks = "-\|/"; +static char *ticker = ""; static int tickCount = 0; + #define TICKS_PER_CHAR 10 #define DO_TICK(bool) \ do if ((bool) && !(++tickCount % TICKS_PER_CHAR)) { \ @@ -200,214 +219,215 @@ if (!*ticker++) ticker= ticks; \ } while (0)
-long aioPoll(long microSeconds) +long +aioPoll(long microSeconds) { - int fd; - fd_set rd, wr, ex; - unsigned long long us; + int fd; + fd_set rd, wr, ex; + unsigned long long us;
- FPRINTF((stderr, "aioPoll(%ld)\n", microSeconds)); - DO_TICK(SHOULD_TICK()); + FPRINTF((stderr, "aioPoll(%ld)\n", microSeconds)); + DO_TICK(SHOULD_TICK());
- /* get out early if there is no pending i/o and no need to relinquish cpu */ + /* + * get out early if there is no pending i/o and no need to relinquish + * cpu + */
#ifdef TARGET_OS_IS_IPHONE - if (maxFd == 0) - return 0; + if (maxFd == 0) + return 0; #else - if ((maxFd == 0) && (microSeconds == 0)) - return 0; + if ((maxFd == 0) && (microSeconds == 0)) + return 0; #endif
- rd= rdMask; - wr= wrMask; - ex= exMask; - us= ioUTCMicroseconds(); + rd = rdMask; + wr = wrMask; + ex = exMask; + us = ioUTCMicroseconds();
- for (;;) - { - struct timeval tv; - int n; - unsigned long long now; - tv.tv_sec= microSeconds / 1000000; - tv.tv_usec= microSeconds % 1000000; - n= select(maxFd, &rd, &wr, &ex, &tv); - if (n > 0) break; - if (n == 0) return 0; - if (errno && (EINTR != errno)) - { - fprintf(stderr, "errno %d\n", errno); - perror("select"); - return 0; + for (;;) { + struct timeval tv; + int n; + unsigned long long now; + + tv.tv_sec = microSeconds / 1000000; + tv.tv_usec = microSeconds % 1000000; + n = select(maxFd, &rd, &wr, &ex, &tv); + if (n > 0) + break; + if (n == 0) + return 0; + if (errno && (EINTR != errno)) { + fprintf(stderr, "errno %d\n", errno); + perror("select"); + return 0; + } + now = ioUTCMicroseconds(); + microSeconds -= max(now - us, 1); + if (microSeconds <= 0) + return 0; + us = now; } - now= ioUTCMicroseconds(); - microSeconds -= max(now - us,1); - if (microSeconds <= 0) - return 0; - us= now; - }
- for (fd= 0; fd < maxFd; ++fd) - { -# define _DO(FLAG, TYPE) \ - { \ - if (FD_ISSET(fd, &TYPE)) \ - { \ - aioHandler handler= TYPE##Handler[fd]; \ - FD_CLR(fd, &TYPE##Mask); \ - TYPE##Handler[fd]= undefinedHandler; \ - handler(fd, clientData[fd], FLAG); \ - } \ - } - _DO_FLAG_TYPE(); -# undef _DO - } - return 1; + for (fd = 0; fd < maxFd; ++fd) { +#undef _DO +#define _DO(FLAG, TYPE) \ + if (FD_ISSET(fd, &TYPE)) { \ + aioHandler handler= TYPE##Handler[fd]; \ + FD_CLR(fd, &TYPE##Mask); \ + TYPE##Handler[fd]= undefinedHandler; \ + handler(fd, clientData[fd], FLAG); \ + } + _DO_FLAG_TYPE(); + } + return 1; }
-/* sleep for microSeconds or until i/o becomes possible, avoiding - sleeping in select() if timeout too small */ +/* + * sleep for microSeconds or until i/o becomes possible, avoiding sleeping in + * select() if timeout too small + */
-long aioSleepForUsecs(long microSeconds) +long +aioSleepForUsecs(long microSeconds) { #if defined(HAVE_NANOSLEEP) - if (microSeconds < (1000000/60)) /* < 1 timeslice? */ - { - if (!aioPoll(0)) - { - struct timespec rqtp= { 0, microSeconds * 1000 }; - struct timespec rmtp; - nanosleep(&rqtp, &rmtp); - microSeconds= 0; /* poll but don't block */ + if (microSeconds < (1000000 / 60)) { /* < 1 timeslice? */ + if (!aioPoll(0)) { + struct timespec rqtp = {0, microSeconds * 1000}; + struct timespec rmtp; + + nanosleep(&rqtp, &rmtp); + microSeconds = 0; /* poll but don't block */ + } } - } #endif - return aioPoll(microSeconds); + return aioPoll(microSeconds); }
/* enable asynchronous notification for a descriptor */
-void aioEnable(int fd, void *data, int flags) +void +aioEnable(int fd, void *data, int flags) { - FPRINTF((stderr, "aioEnable(%d)\n", fd)); - if (fd < 0) - { - FPRINTF((stderr, "aioEnable(%d): IGNORED\n", fd)); - return; - } - if (FD_ISSET(fd, &fdMask)) - { - fprintf(stderr, "aioEnable: descriptor %d already enabled\n", fd); - return; - } - clientData[fd]= data; - rdHandler[fd]= wrHandler[fd]= exHandler[fd]= undefinedHandler; - FD_SET(fd, &fdMask); - FD_CLR(fd, &rdMask); - FD_CLR(fd, &wrMask); - FD_CLR(fd, &exMask); - if (fd >= maxFd) - maxFd= fd + 1; - if (flags & AIO_EXT) - { - FD_SET(fd, &xdMask); - /* we should not set NBIO ourselves on external descriptors! */ - } - else - { - /* enable non-blocking asynchronous i/o and delivery of SIGIO to the active process */ - int arg; - FD_CLR(fd, &xdMask); + FPRINTF((stderr, "aioEnable(%d)\n", fd)); + if (fd < 0) { + FPRINTF((stderr, "aioEnable(%d): IGNORED\n", fd)); + return; + } + if (FD_ISSET(fd, &fdMask)) { + fprintf(stderr, "aioEnable: descriptor %d already enabled\n", fd); + return; + } + clientData[fd] = data; + rdHandler[fd] = wrHandler[fd] = exHandler[fd] = undefinedHandler; + FD_SET(fd, &fdMask); + FD_CLR(fd, &rdMask); + FD_CLR(fd, &wrMask); + FD_CLR(fd, &exMask); + if (fd >= maxFd) + maxFd = fd + 1; + if (flags & AIO_EXT) { + FD_SET(fd, &xdMask); + /* we should not set NBIO ourselves on external descriptors! */ + } + else { + /* + * enable non-blocking asynchronous i/o and delivery of SIGIO + * to the active process + */ + int arg;
-# if defined(O_ASYNC) - if ( fcntl(fd, F_SETOWN, getpid() ) < 0) - perror("fcntl(F_SETOWN, getpid())"); - if ((arg= fcntl(fd, F_GETFL, 0 )) < 0) - perror("fcntl(F_GETFL)"); - if ( fcntl(fd, F_SETFL, arg | O_NONBLOCK | O_ASYNC) < 0) - perror("fcntl(F_SETFL, O_ASYNC)"); + FD_CLR(fd, &xdMask);
-# elif defined(FASYNC) - if ( fcntl(fd, F_SETOWN, getpid() ) < 0) - perror("fcntl(F_SETOWN, getpid())"); - if ((arg= fcntl(fd, F_GETFL, 0 )) < 0) - perror("fcntl(F_GETFL)"); - if ( fcntl(fd, F_SETFL, arg | O_NONBLOCK | FASYNC ) < 0) - perror("fcntl(F_SETFL, FASYNC)"); +#if defined(O_ASYNC) + if (fcntl(fd, F_SETOWN, getpid()) < 0) + perror("fcntl(F_SETOWN, getpid())"); + if ((arg = fcntl(fd, F_GETFL, 0)) < 0) + perror("fcntl(F_GETFL)"); + if (fcntl(fd, F_SETFL, arg | O_NONBLOCK | O_ASYNC) < 0) + perror("fcntl(F_SETFL, O_ASYNC)");
-# elif defined(FIOASYNC) - arg= getpid(); - if (ioctl(fd, SIOCSPGRP, &arg) < 0) - perror("ioctl(SIOCSPGRP, getpid())"); - arg= 1; - if (ioctl(fd, FIOASYNC, &arg) < 0) - perror("ioctl(FIOASYNC, 1)"); -# endif - } +#elif defined(FASYNC) + if (fcntl(fd, F_SETOWN, getpid()) < 0) + perror("fcntl(F_SETOWN, getpid())"); + if ((arg = fcntl(fd, F_GETFL, 0)) < 0) + perror("fcntl(F_GETFL)"); + if (fcntl(fd, F_SETFL, arg | O_NONBLOCK | FASYNC) < 0) + perror("fcntl(F_SETFL, FASYNC)"); + +#elif defined(FIOASYNC) + arg = getpid(); + if (ioctl(fd, SIOCSPGRP, &arg) < 0) + perror("ioctl(SIOCSPGRP, getpid())"); + arg = 1; + if (ioctl(fd, FIOASYNC, &arg) < 0) + perror("ioctl(FIOASYNC, 1)"); +#endif + } }
/* install/change the handler for a descriptor */
-void aioHandle(int fd, aioHandler handlerFn, int mask) +void +aioHandle(int fd, aioHandler handlerFn, int mask) { - FPRINTF((stderr, "aioHandle(%d, %s, %d)\n", fd, handlerName(handlerFn), mask)); - if (fd < 0) - { - FPRINTF((stderr, "aioHandle(%d): IGNORED\n", fd)); - return; - } -# define _DO(FLAG, TYPE) \ - if (mask & FLAG) { \ + FPRINTF((stderr, "aioHandle(%d, %s, %d)\n", fd, handlerName(handlerFn), mask)); + if (fd < 0) { + FPRINTF((stderr, "aioHandle(%d): IGNORED\n", fd)); + return; + } +#undef _DO +#define _DO(FLAG, TYPE) \ + if (mask & FLAG) { \ FD_SET(fd, &TYPE##Mask); \ TYPE##Handler[fd]= handlerFn; \ } - _DO_FLAG_TYPE(); -# undef _DO + _DO_FLAG_TYPE(); }
/* temporarily suspend asynchronous notification for a descriptor */
-void aioSuspend(int fd, int mask) +void +aioSuspend(int fd, int mask) { - if (fd < 0) - { - FPRINTF((stderr, "aioSuspend(%d): IGNORED\n", fd)); - return; - } - FPRINTF((stderr, "aioSuspend(%d)\n", fd)); -# define _DO(FLAG, TYPE) \ - { \ - if (mask & FLAG) \ - { \ - FD_CLR(fd, &TYPE##Mask); \ - TYPE##Handler[fd]= undefinedHandler; \ - } \ - } - _DO_FLAG_TYPE(); -# undef _DO + if (fd < 0) { + FPRINTF((stderr, "aioSuspend(%d): IGNORED\n", fd)); + return; + } + FPRINTF((stderr, "aioSuspend(%d)\n", fd)); +#undef _DO +#define _DO(FLAG, TYPE) \ + if (mask & FLAG) { \ + FD_CLR(fd, &TYPE##Mask); \ + TYPE##Handler[fd]= undefinedHandler; \ + } + _DO_FLAG_TYPE(); }
/* definitively disable asynchronous notification for a descriptor */
-void aioDisable(int fd) +void +aioDisable(int fd) { - if (fd < 0) - { - FPRINTF((stderr, "aioDisable(%d): IGNORED\n", fd)); - return; - } - FPRINTF((stderr, "aioDisable(%d)\n", fd)); - aioSuspend(fd, AIO_RWX); - FD_CLR(fd, &xdMask); - FD_CLR(fd, &fdMask); - rdHandler[fd]= wrHandler[fd]= exHandler[fd]= 0; - clientData[fd]= 0; - /* keep maxFd accurate (drops to zero if no more sockets) */ - while (maxFd && !FD_ISSET(maxFd - 1, &fdMask)) - --maxFd; + if (fd < 0) { + FPRINTF((stderr, "aioDisable(%d): IGNORED\n", fd)); + return; + } + FPRINTF((stderr, "aioDisable(%d)\n", fd)); + aioSuspend(fd, AIO_RWX); + FD_CLR(fd, &xdMask); + FD_CLR(fd, &fdMask); + rdHandler[fd] = wrHandler[fd] = exHandler[fd] = 0; + clientData[fd] = 0; + /* keep maxFd accurate (drops to zero if no more sockets) */ + while (maxFd && !FD_ISSET(maxFd - 1, &fdMask)) + --maxFd; }
vm-dev@lists.squeakfoundation.org