diff options
Diffstat (limited to 'mit-pthreads/patches/mevans')
-rwxr-xr-x | mit-pthreads/patches/mevans | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/mit-pthreads/patches/mevans b/mit-pthreads/patches/mevans new file mode 100755 index 00000000000..d5ff2f27610 --- /dev/null +++ b/mit-pthreads/patches/mevans @@ -0,0 +1,642 @@ +=A0 +Attached are several patches for pthreads-1_60_beta6. The patches fall +into 3 catagories: + + 1. Crashes and hangs. + 2. Missing functionality (namely flock()) + 3. Use of POSIX reentrant safe routines. + +Most of the patches contain a comment as to why the change was made. +The one major exception is to fd_kern.c at line 257 (unpatched). The +change to that line is to fix a "hang" that prevents threads for +scheduling for an hour if there is no external I/O event. + +I also include patches that modify several functions to use POSIX +reentrant safe routines. I know that MIT pthreads implements routine +like gethostbyname in a thread safe manner, but we're pretty, um, anal +about trying to keep our code as portable as possible. By excluding +using routines that are not reentrant safe according to the PTHREAD +safe, it's easy for us to stub out the unsafe routines and catch +non-compliant code. I almost left these patches out, but I'm hoping +they'll be adopted. :-) + +WARNING: None of the MIT pthreads routines that convert floats/doubles +between their native forms and strings are thread safe! (i.e printf, +sprintf, fprintf, atod, strtod, etc) I have replacements, but I need to +check with the author of the replacements and my employer. + +Mark Evans + +------------69CDAAF52A3566916F8ED01A0 +Content-Disposition: inline; filename="pthreads-1_60_beta6.patch" +Content-Type: text/plain; charset=us-ascii; name="pthreads-1_60_beta6.patch" +Content-Transfer-Encoding: 7bit + +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/config.h.in pthreads-1_60_beta6+/config/config.h.in +*** pthreads-1_60_beta6/config/config.h.in Thu Mar 21 21:30:04 1996 +--- pthreads-1_60_beta6+/config/config.h.in Sat Mar 15 14:08:55 1997 +*************** +*** 137,142 **** +--- 137,145 ---- + /* Define if you have the syscall_ftruncate function. */ + #undef HAVE_SYSCALL_FTRUNCATE + ++ /* Define if you have the syscall_flock function. */ ++ #undef HAVE_SYSCALL_FLOCK ++ + /* Define if you have the syscall_getdents function. */ + #undef HAVE_SYSCALL_GETDENTS + +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/config/configure.in pthreads-1_60_beta6+/config/configure.in +*** pthreads-1_60_beta6/config/configure.in Wed Nov 13 14:03:08 1996 +--- pthreads-1_60_beta6+/config/configure.in Sat Mar 15 14:08:55 1997 +*************** +*** 241,247 **** + + PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe + fchmod fchown execve fstat lstat link unlink chdir chown chmod stat +! rename select getdtablesize ioctl ftruncate + dnl - signals + sigsuspend sigaction sigpause sigprocmask ksigaction + dnl - directory reading +--- 241,247 ---- + + PTHREADS_CHECK_SYSCALLS(open write read creat close fcntl lseek dup2 dup pipe + fchmod fchown execve fstat lstat link unlink chdir chown chmod stat +! rename select getdtablesize ioctl ftruncate flock + dnl - signals + sigsuspend sigaction sigpause sigprocmask ksigaction + dnl - directory reading +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/directory.c pthreads-1_60_beta6+/gen/directory.c +*** pthreads-1_60_beta6/gen/directory.c Sat May 20 10:55:34 1995 +--- pthreads-1_60_beta6+/gen/directory.c Sat Mar 15 14:08:55 1997 +*************** +*** 251,262 **** +--- 251,266 ---- + /* + * Seek to an entry in a directory. + * _seekdir is in telldir.c so that it can share opaque data structures. ++ * ++ * Use the POSIX reentrant safe readdir_r to simplify varifying POSIX ++ * thread-safe compliance. + */ + void seekdir(DIR * dirp, long loc) + { + register struct ddloc ** prevlp; + register struct ddloc * lp; + struct dirent * dp; ++ struct dirent de; + + pthread_mutex_lock (dirp->dd_lock); + prevlp = (struct ddloc **)&(dirp->dd_ddloc); +*************** +*** 277,283 **** + dirp->dd_seek = lp->loc_seek; + dirp->dd_loc = 0; + while (dirp->dd_loc < lp->loc_loc) { +! if (!(dp = readdir(dirp))) { + *prevlp = lp->loc_next; + break; + } +--- 281,287 ---- + dirp->dd_seek = lp->loc_seek; + dirp->dd_loc = 0; + while (dirp->dd_loc < lp->loc_loc) { +! if (readdir_r(dirp, &de, &dp)) { + *prevlp = lp->loc_next; + break; + } +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/gen/getcwd.c pthreads-1_60_beta6+/gen/getcwd.c +*** pthreads-1_60_beta6/gen/getcwd.c Sat Sep 2 17:39:30 1995 +--- pthreads-1_60_beta6+/gen/getcwd.c Sat Mar 15 14:08:55 1997 +*************** +*** 50,67 **** + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + dp->d_name[1] == '.' && dp->d_name[2] == '\0')) + + char * + getcwd(pt, size) + char *pt; + size_t size; + { +- register struct dirent *dp; + register DIR *dir; + register dev_t dev; + register ino_t ino; + register int first; + register char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; +--- 50,71 ---- + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + dp->d_name[1] == '.' && dp->d_name[2] == '\0')) + ++ /* Only use reentrant safe routines to simplify varifying POSIX thread-safe ++ * compliance. (mevans). ++ */ + char * + getcwd(pt, size) + char *pt; + size_t size; + { + register DIR *dir; + register dev_t dev; + register ino_t ino; + register int first; + register char *bpt, *bup; + struct stat s; ++ struct dirent *dp; ++ struct dirent de; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; +*************** +*** 166,179 **** + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { +! if (!(dp = readdir(dir))) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { +! if (!(dp = readdir(dir))) + goto notfound; + if (ISDOT(dp)) + continue; +--- 170,183 ---- + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { +! if (readdir_r(dir, &de, &dp)) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { +! if (readdir_r(dir, &de, &dp)) + goto notfound; + if (ISDOT(dp)) + continue; +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/include/syslog.h pthreads-1_60_beta6+/include/syslog.h +*** pthreads-1_60_beta6/include/syslog.h Mon Sep 26 21:26:29 1994 +--- pthreads-1_60_beta6+/include/syslog.h Sat Mar 15 14:08:56 1997 +*************** +*** 9,14 **** +--- 9,16 ---- + #ifndef SYSLOG_H + #define SYSLOG_H + ++ /* Added __[BEGIN/END]_DECLS so this file would work with C++. (mevans) */ ++ #include <sys/cdefs.h> + #include <stdarg.h> + + /* Discipline: openlog(), closelog(), and setlogmask() are not thread-safe +*************** +*** 84,95 **** +--- 86,101 ---- + #define LOG_NDELAY 0x08 /* don't delay open */ + #define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */ + ++ __BEGIN_DECLS ++ + /* Syslogging functions. */ + void syslog(int pri, char *fmt, ...); + void vsyslog(int pri, char *fmt, va_list args); + void openlog(char *ident, int logstat, int logfac); + void closelog(void); + int setlogmask(int pmask); ++ ++ __END_DECLS + + #endif + +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c +*** pthreads-1_60_beta6/machdep/engine-i386-linux-1.0.c Mon Oct 21 20:39:13 1996 +--- pthreads-1_60_beta6+/machdep/engine-i386-linux-1.0.c Sat Mar 15 14:08:56 1997 +*************** +*** 142,147 **** +--- 142,149 ---- + * machdep_pthread_start(). + */ + machdep_pthread->machdep_state->__pc = (char *)machdep_pthread_start; ++ machdep_pthread->machdep_state->__bp = (char *)0;/* So the backtrace ++ * is sensible (mevans) */ + + /* Stack starts high and builds down. */ + machdep_pthread->machdep_state->__sp = +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S +*** pthreads-1_60_beta6/machdep/syscall-i386-linux-1.0.S Mon Oct 21 22:17:32 1996 +--- pthreads-1_60_beta6+/machdep/syscall-i386-linux-1.0.S Sat Mar 15 14:08:56 1997 +*************** +*** 148,156 **** + /* ========================================================================= + * exit 1 select 82 + * fork 2 socketcall 102 +! * read 3 readv 145 +! * write 4 writev 146 +! * open 5 + * creat 8 + * link 9 + * unlink 10 +--- 148,156 ---- + /* ========================================================================= + * exit 1 select 82 + * fork 2 socketcall 102 +! * read 3 flock 143 +! * write 4 readv 145 +! * open 5 writev 146 + * creat 8 + * link 9 + * unlink 10 +*************** +*** 390,394 **** +--- 390,401 ---- + */ + #ifdef HAVE_SYSCALL_WRITEV + SYSCALL3(writev) ++ #endif ++ ++ /* ========================================================================== ++ * machdep_sys_flock() ++ */ ++ #ifdef HAVE_SYSCALL_FLOCK ++ SYSCALL2(flock) + #endif + +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/gethostbyname.c pthreads-1_60_beta6+/net/gethostbyname.c +*** pthreads-1_60_beta6/net/gethostbyname.c Mon Apr 22 22:41:21 1996 +--- pthreads-1_60_beta6+/net/gethostbyname.c Sat Mar 15 14:08:58 1997 +*************** +*** 146,161 **** + { + char **alias; + FILE *fp = NULL; + + pthread_mutex_lock(&host_iterate_lock); + sethostent(0); +! while ((result = gethostent_r(result, buf, bufsize, errval)) != NULL) { + /* Check the entry's name and aliases against the given name. */ + if (strcasecmp(result->h_name, name) == 0) + break; + for (alias = result->h_aliases; *alias; alias++) { +! if (strcasecmp(*alias, name) == 0) + break; + } + } + pthread_mutex_unlock(&host_iterate_lock); +--- 146,166 ---- + { + char **alias; + FILE *fp = NULL; ++ int fFound = FALSE; + + pthread_mutex_lock(&host_iterate_lock); + sethostent(0); +! while (!fFound && (result = gethostent_r(result, buf, bufsize, errval)) +! != NULL) { + /* Check the entry's name and aliases against the given name. */ + if (strcasecmp(result->h_name, name) == 0) + break; + for (alias = result->h_aliases; *alias; alias++) { +! if (strcasecmp(*alias, name) == 0) { +! /* fFound will exit while loop. (mevans). */ +! fFound = TRUE; + break; ++ } + } + } + pthread_mutex_unlock(&host_iterate_lock); +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/net/res_debug.c pthreads-1_60_beta6+/net/res_debug.c +*** pthreads-1_60_beta6/net/res_debug.c Thu Feb 23 22:42:35 1995 +--- pthreads-1_60_beta6+/net/res_debug.c Sat Mar 15 14:08:58 1997 +*************** +*** 375,380 **** +--- 375,383 ---- + + /* + * Print resource record fields in human readable form. ++ * ++ * Removed calls to non-reentrant routines to simplify varifying ++ * POSIX thread-safe implementations. (mevans). + */ + char * + p_rr(cp, msg, file) +*************** +*** 386,391 **** +--- 389,395 ---- + char *cp1, *cp2; + u_long tmpttl, t; + int lcnt; ++ char buf[32]; + + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); /* compression error */ +*************** +*** 413,426 **** + case C_HS: + bcopy(cp, (char *)&inaddr, sizeof(inaddr)); + if (dlen == 4) { +! fprintf(file,"\t%s", inet_ntoa(inaddr)); + cp += dlen; + } else if (dlen == 7) { + char *address; + u_char protocol; + u_short port; + +! address = inet_ntoa(inaddr); + cp += sizeof(inaddr); + protocol = *(u_char*)cp; + cp += sizeof(u_char); +--- 417,432 ---- + case C_HS: + bcopy(cp, (char *)&inaddr, sizeof(inaddr)); + if (dlen == 4) { +! fprintf(file,"\t%s", +! inet_ntoa_r(inaddr, buf, sizeof(buf))); + cp += dlen; + } else if (dlen == 7) { + char *address; + u_char protocol; + u_short port; + +! address = inet_ntoa_r(inaddr, +! buf, sizeof(buf)); + cp += sizeof(inaddr); + protocol = *(u_char*)cp; + cp += sizeof(u_char); +*************** +*** 524,530 **** + bcopy(cp, (char *)&inaddr, sizeof(inaddr)); + cp += sizeof(u_long); + fprintf(file, "\t%s %s ( ", +! inet_ntoa(inaddr), + deproto((int) *cp)); + cp += sizeof(u_char); + n = 0; +--- 530,536 ---- + bcopy(cp, (char *)&inaddr, sizeof(inaddr)); + cp += sizeof(u_long); + fprintf(file, "\t%s %s ( ", +! inet_ntoa_r(inaddr, buf, sizeof(buf)), + deproto((int) *cp)); + cp += sizeof(u_char); + n = 0; +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/fd_kern.c pthreads-1_60_beta6+/pthreads/fd_kern.c +*** pthreads-1_60_beta6/pthreads/fd_kern.c Tue Oct 1 12:26:48 1996 +--- pthreads-1_60_beta6+/pthreads/fd_kern.c Sat Mar 15 14:09:00 1997 +*************** +*** 215,221 **** + * Called when there is no active thread to run. + */ + extern struct timeval __fd_kern_wait_timeout; +! + void fd_kern_wait() + { + fd_set fd_set_read, fd_set_write, fd_set_except; +--- 215,221 ---- + * Called when there is no active thread to run. + */ + extern struct timeval __fd_kern_wait_timeout; +! extern volatile sig_atomic_t sig_to_process; + void fd_kern_wait() + { + fd_set fd_set_read, fd_set_write, fd_set_except; +*************** +*** 254,260 **** + + machdep_unset_thread_timer(NULL); + __fd_kern_wait_timeout.tv_usec = 0; +! __fd_kern_wait_timeout.tv_sec = 3600; + + machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset); + +--- 254,260 ---- + + machdep_unset_thread_timer(NULL); + __fd_kern_wait_timeout.tv_usec = 0; +! __fd_kern_wait_timeout.tv_sec = (sig_to_process) ? 0 : 3600; + + machdep_sys_sigprocmask(SIG_UNBLOCK, &sig_to_block, &oset); + +*************** +*** 726,731 **** +--- 726,753 ---- + return(ret); + } + ++ #if defined (HAVE_SYSCALL_FLOCK) ++ /* ========================================================================== ++ * flock() ++ * ++ * Added (mevans) ++ */ ++ int flock(int fd, int operation) ++ { ++ int ret; ++ ++ if ((ret = fd_lock(fd, FD_RDWR, NULL)) == OK) { ++ if ((ret = machdep_sys_flock(fd_table[fd]->fd.i, ++ operation)) < OK) { ++ SET_ERRNO(-ret); ++ ret = NOTOK; ++ } ++ fd_unlock(fd, FD_RDWR); ++ } ++ return(ret); ++ } ++ #endif ++ + /* ========================================================================== + * pipe() + */ +*************** +*** 1126,1132 **** + /* Get the error, this function should not fail */ + machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET, + SO_ERROR, &ret, &tmpnamelen); +! SET_ERRNO(-ret); + ret = NOTOK; + } + } else { +--- 1148,1155 ---- + /* Get the error, this function should not fail */ + machdep_sys_getsockopt(fd_table[fd]->fd.i, SOL_SOCKET, + SO_ERROR, &ret, &tmpnamelen); +! /* ret is already positive (mevans) */ +! SET_ERRNO(ret); + ret = NOTOK; + } + } else { +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/malloc.c pthreads-1_60_beta6+/pthreads/malloc.c +*** pthreads-1_60_beta6/pthreads/malloc.c Thu Mar 9 21:06:43 1995 +--- pthreads-1_60_beta6+/pthreads/malloc.c Sat Mar 15 14:09:00 1997 +*************** +*** 196,204 **** + else + n = n - x; + if (n) { +! if (sbrk(n) == (char *)-1) + return (NULL); + } + bucket = 0; + amt = 8; + while (pagesz > amt) { +--- 196,207 ---- + else + n = n - x; + if (n) { +! if (sbrk(n) == (char *)-1) { +! /* Unlock before returning (mevans) */ +! pthread_mutex_unlock(mutex); + return (NULL); + } ++ } + bucket = 0; + amt = 8; + while (pagesz > amt) { +*************** +*** 363,366 **** +--- 366,382 ---- + free(cp); + + return (res); ++ } ++ /* ========================================================================== ++ * calloc() ++ * ++ * Added to ensure pthread's allocation is used (mevans). ++ */ ++ void *calloc(size_t nmemb, size_t size) ++ { ++ void *p; ++ size *= nmemb; ++ p = malloc(size); ++ if (p) memset(p, 0, size); ++ return (p); + } +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/select.c pthreads-1_60_beta6+/pthreads/select.c +*** pthreads-1_60_beta6/pthreads/select.c Sat Jul 6 21:58:55 1996 +--- pthreads-1_60_beta6+/pthreads/select.c Sat Mar 15 14:09:00 1997 +*************** +*** 165,176 **** + pthread_resched_resume(PS_SELECT_WAIT); + + /* We're awake */ +- CLEAR_PF_DONE_EVENT(pthread_run); + if (sleep_cancel(pthread_run) == NOTOK) { + ret = OK; + } else { + ret = data.nfds; + } + } else { + pthread_resched_resume(PS_SELECT_WAIT); + CLEAR_PF_DONE_EVENT(pthread_run); +--- 165,180 ---- + pthread_resched_resume(PS_SELECT_WAIT); + + /* We're awake */ + if (sleep_cancel(pthread_run) == NOTOK) { + ret = OK; + } else { + ret = data.nfds; + } ++ /* Moving this after the sleep_cancel() seemed ++ * to fix intermittent crashes during heavy ++ * socket use. (mevans) ++ */ ++ CLEAR_PF_DONE_EVENT(pthread_run); + } else { + pthread_resched_resume(PS_SELECT_WAIT); + CLEAR_PF_DONE_EVENT(pthread_run); +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/pthreads/signal.c pthreads-1_60_beta6+/pthreads/signal.c +*** pthreads-1_60_beta6/pthreads/signal.c Tue Mar 12 21:33:17 1996 +--- pthreads-1_60_beta6+/pthreads/signal.c Sat Mar 15 14:09:00 1997 +*************** +*** 65,71 **** + */ + + static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, }; +! static sig_atomic_t sig_to_process = 0; + + /* static volatile sigset_t sig_to_process; */ + static volatile int sig_count = 0; +--- 65,71 ---- + */ + + static sig_atomic_t signum_to_process[SIGMAX + 1] = { 0, }; +! volatile sig_atomic_t sig_to_process = 0; + + /* static volatile sigset_t sig_to_process; */ + static volatile int sig_count = 0; +*************** +*** 303,309 **** + break; + case NOTOK: + /* Do the registered action, no threads were sleeping */ +! sigdefault(sig); + break; + } + break; +--- 303,317 ---- + break; + case NOTOK: + /* Do the registered action, no threads were sleeping */ +! /* There is a timing window that gets +! * here when no threads are on the +! * sleep queue. This is a quick fix. +! * The real problem is possibly related +! * to heavy use of condition variables +! * with time outs. +! * (mevans) +! *sigdefault(sig); +! */ + break; + } + break; +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdio/setvbuf.c pthreads-1_60_beta6+/stdio/setvbuf.c +*** pthreads-1_60_beta6/stdio/setvbuf.c Sat Sep 3 20:58:36 1994 +--- pthreads-1_60_beta6+/stdio/setvbuf.c Sat Mar 15 14:09:00 1997 +*************** +*** 142,148 **** + flags |= __SLBF; + if (flags & __SRW) + flags &= ~(__SRD | __SWR); +! fp->_w = 0; + fp->_flags = flags; + fp->_bf._base = fp->_p = (unsigned char *)buf; + fp->_bf._size = size; +--- 142,148 ---- + flags |= __SLBF; + if (flags & __SRW) + flags &= ~(__SRD | __SWR); +! fp->_w = size; /* Was 0 (mevans) */ + fp->_flags = flags; + fp->_bf._base = fp->_p = (unsigned char *)buf; + fp->_bf._size = size; +diff -c -b -r -d -I .*$Id:.* pthreads-1_60_beta6/stdlib/system.c pthreads-1_60_beta6+/stdlib/system.c +*** pthreads-1_60_beta6/stdlib/system.c Wed Apr 24 21:18:56 1996 +--- pthreads-1_60_beta6+/stdlib/system.c Sat Mar 15 14:09:01 1997 +*************** +*** 62,68 **** + argp[2] = (char *) command; + sigemptyset(&tmp_mask); + sigaddset(&tmp_mask, SIGCHLD); +! pthread_sigmask(SIG_BLOCK, tmp_mask, &old_mask); + switch(pid = fork()) { + case -1: /* error */ + (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL); +--- 62,69 ---- + argp[2] = (char *) command; + sigemptyset(&tmp_mask); + sigaddset(&tmp_mask, SIGCHLD); +! /* Pass the address of tmp_mask to avoid a sigfault. (mevans). */ +! pthread_sigmask(SIG_BLOCK, &tmp_mask, &old_mask); + switch(pid = fork()) { + case -1: /* error */ + (void)pthread_sigmask(SIG_SETMASK, &old_mask, NULL); |