Loic Grenie on Sun, 19 Nov 2006 17:35:16 +0100 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Kludge for cygwin |
Hi, I've observed that gp's ?? and ??? commands are very slow under cygwin when gp uses more than half of the RAM. The reason is the popen() function that uses vfork() that copies memory (contrary to the UNIX semantic) => swap. I've designed a kludge that should work as long as it is not overused. It is very mean, but should fit the bill. Loïc
Index: src/language/es.c =================================================================== RCS file: /home/cvs/pari/src/language/es.c,v retrieving revision 1.229 diff -c -r1.229 es.c *** src/language/es.c 14 Oct 2006 06:05:56 -0000 1.229 --- src/language/es.c 19 Nov 2006 16:05:08 -0000 *************** *** 2611,2616 **** --- 2611,2654 ---- return file; } + #ifdef __CYGWIN32__ + struct pfd { + int pid; + int fd; + } *pfds = NULL; + static int numpfds = 0, maxpfds = 0; + + static int + _pclose(FILE *f) + { + int i; + struct pfd *ppfd; + for (i = 0, ppfd = pfds; i < numpfds; i++, ppfd++) + if (ppfd->fd == fileno(f)) + break; + if (i < numpfds) + kill(ppfd->pid, SIGTERM); + else + ppfd = NULL; + fclose(f); + if (ppfd && kill(ppfd->pid, SIGCONT) == 0) { + sleep(5); + kill(ppfd->pid, SIGKILL); + } + if (ppfd) + { + while (++i < numpfds) + { + *ppfd = ppfd[1]; + ppfd++; + } + numpfds--; + } + return 0; + } + #define pclose _pclose + #endif + static void pari_kill_file(pariFILE *f) { *************** *** 2635,2640 **** --- 2673,2682 ---- gpfree(f); } + #ifdef __CYGWIN32__ + #undef pclose + #endif + void pari_fclose(pariFILE *f) { *************** *** 2763,2768 **** --- 2805,2869 ---- return 1; } + #ifdef __CYGWIN32__ + #include <process.h> + static FILE * + _popen(char *cmd, char *mode) + { + int fd[2]; + + if (!pipe(fd)) { + char *str, *p, *q; + int pid; + + str = gpmalloc(2*strlen(cmd)+64); + strcpy(str, "eval \""); + for (p = str+strlen(str), q = cmd; *q; ) + { + if (*q == '$' || *q == '`' || *q == '"') + *p++ = '\\'; + *p++ = *q++; + } + if (*mode == 'r') + { + sprintf(p, "\" >&%d %d>&-", fd[1], fd[0]); + if (fd[1] != 1) + sprintf(p + strlen(p), " %d>&-", fd[1]); + } + else + { + sprintf(p, "\" <&%d %d>&-", fd[0], fd[1]); + if (fd[0] != 0) + sprintf(p + strlen(p), " %d>&-", fd[0]); + } + pid = spawnlp(_P_NOWAIT, "bash", "bash", "-c", str, NULL); + gpfree(str); + if (!pfds) + { + maxpfds = 10; + pfds = (struct pfd *)gpmalloc(maxpfds*sizeof(struct pfd)); + } + else if (numpfds == maxpfds) + { + maxpfds += 10; + pfds = (struct pfd *)gprealloc(pfds, maxpfds*sizeof(struct pfd)); + } + pfds[numpfds].pid = pid; + pfds[numpfds].fd = fd[*mode == 'w']; + if (*mode == 'r') { + close(fd[1]); + return fdopen(fd[0], "r"); + } + else { + close(fd[0]); + return fdopen(fd[1], "w"); + } + } + return NULL; + } + #define popen _popen + #endif + pariFILE * try_pipe(char *cmd, int fl) { *************** *** 2800,2805 **** --- 2901,2910 ---- #endif } + #ifdef __CYGWIN32__ + #undef popen + #endif + void os_close(long fd) {