[BACK]Return to os_dep.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc

Diff for /OpenXM_contrib2/asir2000/gc/os_dep.c between version 1.1 and 1.3

version 1.1, 1999/12/03 07:39:10 version 1.3, 2000/12/01 09:26:12
Line 2  int ox_usr1_sent, ox_int_received, critical_when_signa
Line 2  int ox_usr1_sent, ox_int_received, critical_when_signa
 static int inside_critical_section;  static int inside_critical_section;
   
 /*  /*
    * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.   * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved.
  * Copyright (c) 1996-1997 by Silicon Graphics.  All rights reserved.   * Copyright (c) 1996-1999 by Silicon Graphics.  All rights reserved.
    * Copyright (c) 1999 by Hewlett-Packard Company.  All rights reserved.
  *   *
  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED   * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.   * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
Line 34  static int inside_critical_section;
Line 36  static int inside_critical_section;
       /* make sure the former gets defined to be the latter if appropriate. */        /* make sure the former gets defined to be the latter if appropriate. */
 #     include <features.h>  #     include <features.h>
 #     if 2 <= __GLIBC__  #     if 2 <= __GLIBC__
 #       if 0 == __GLIBC_MINOR__  #       if 2 == __GLIBC__ && 0 == __GLIBC_MINOR__
           /* glibc 2.1 no longer has sigcontext.h.  But signal.h        */            /* glibc 2.1 no longer has sigcontext.h.  But signal.h        */
           /* has the right declaration for glibc 2.1.                   */            /* has the right declaration for glibc 2.1.                   */
 #         include <sigcontext.h>  #         include <sigcontext.h>
Line 57  static int inside_critical_section;
Line 59  static int inside_critical_section;
 # include <signal.h>  # include <signal.h>
   
 /* Blatantly OS dependent routines, except for those that are related   */  /* Blatantly OS dependent routines, except for those that are related   */
 /* dynamic loading.                                                     */  /* to dynamic loading.                                                  */
   
 # if !defined(THREADS) && !defined(STACKBOTTOM) && defined(HEURISTIC2)  # if !defined(THREADS) && !defined(STACKBOTTOM) && defined(HEURISTIC2)
 #   define NEED_FIND_LIMIT  #   define NEED_FIND_LIMIT
 # endif  # endif
   
 # if defined(IRIX_THREADS)  # if defined(IRIX_THREADS) || defined(HPUX_THREADS)
 #   define NEED_FIND_LIMIT  #   define NEED_FIND_LIMIT
 # endif  # endif
   
 # if (defined(SUNOS4) & defined(DYNAMIC_LOADING)) && !defined(PCR)  # if (defined(SUNOS4) && defined(DYNAMIC_LOADING)) && !defined(PCR)
 #   define NEED_FIND_LIMIT  #   define NEED_FIND_LIMIT
 # endif  # endif
   
Line 75  static int inside_critical_section;
Line 77  static int inside_critical_section;
 #   define NEED_FIND_LIMIT  #   define NEED_FIND_LIMIT
 # endif  # endif
   
 # if defined(LINUX) && (defined(POWERPC) || defined(SPARC) || defined(ALPHA))  # if defined(LINUX) && \
        (defined(POWERPC) || defined(SPARC) || defined(ALPHA) || defined(IA64) \
         || defined(MIPS))
 #   define NEED_FIND_LIMIT  #   define NEED_FIND_LIMIT
 # endif  # endif
   
Line 142  static int inside_critical_section;
Line 146  static int inside_critical_section;
 # define OPT_PROT_EXEC 0  # define OPT_PROT_EXEC 0
 #endif  #endif
   
 #if defined(LINUX) && (defined(POWERPC) || defined(SPARC) || defined(ALPHA))  #if defined(SEARCH_FOR_DATA_START)
     /* The following doesn't work if the GC is in a dynamic library.      */
   /* The I386 case can be handled without a search.  The Alpha case     */    /* The I386 case can be handled without a search.  The Alpha case     */
   /* used to be handled differently as well, but the rules changed      */    /* used to be handled differently as well, but the rules changed      */
   /* for recent Linux versions.  This seems to be the easiest way to    */    /* for recent Linux versions.  This seems to be the easiest way to    */
Line 516  ptr_t GC_get_stack_base()
Line 521  ptr_t GC_get_stack_base()
   
 #   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1)  #   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1)
         static struct sigaction old_segv_act;          static struct sigaction old_segv_act;
 #       if defined(_sigargs) /* !Irix6.x */  #       if defined(_sigargs) || defined(HPUX) /* !Irix6.x */
             static struct sigaction old_bus_act;              static struct sigaction old_bus_act;
 #       endif  #       endif
 #   else  #   else
Line 544  ptr_t GC_get_stack_base()
Line 549  ptr_t GC_get_stack_base()
                 (void) sigaction(SIGSEGV, &act, 0);                  (void) sigaction(SIGSEGV, &act, 0);
 #         else  #         else
                 (void) sigaction(SIGSEGV, &act, &old_segv_act);                  (void) sigaction(SIGSEGV, &act, &old_segv_act);
 #               ifdef _sigargs  /* Irix 5.x, not 6.x */  #               if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
                     /* Under 5.x, we may get SIGBUS.                    */                     || defined(HPUX)
                     /* Pthreads doesn't exist under 5.x, so we don't    */                      /* Under Irix 5.x or HP/UX, we may get SIGBUS.      */
                     /* have to worry in the threads case.               */                      /* Pthreads doesn't exist under Irix 5.x, so we     */
                       /* don't have to worry in the threads case.         */
                     (void) sigaction(SIGBUS, &act, &old_bus_act);                      (void) sigaction(SIGBUS, &act, &old_bus_act);
 #               endif  #               endif
 #         endif /* IRIX_THREADS */  #         endif /* IRIX_THREADS */
Line 563  ptr_t GC_get_stack_base()
Line 569  ptr_t GC_get_stack_base()
     {      {
 #       if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1)  #       if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1)
           (void) sigaction(SIGSEGV, &old_segv_act, 0);            (void) sigaction(SIGSEGV, &old_segv_act, 0);
 #         ifdef _sigargs        /* Irix 5.x, not 6.x */  #         if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
                || defined(HPUX)
               (void) sigaction(SIGBUS, &old_bus_act, 0);                (void) sigaction(SIGBUS, &old_bus_act, 0);
 #         endif  #         endif
 #       else  #       else
Line 608  ptr_t GC_get_stack_base()
Line 615  ptr_t GC_get_stack_base()
     }      }
 # endif  # endif
   
   #ifdef LINUX_STACKBOTTOM
   
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   
   # define STAT_SKIP 27   /* Number of fields preceding startstack        */
                           /* field in /proc/self/stat                     */
   
     ptr_t GC_linux_stack_base(void)
     {
       /* We read the stack base value from /proc/self/stat.  We do this   */
       /* using direct I/O system calls in order to avoid calling malloc   */
       /* in case REDIRECT_MALLOC is defined.                              */
   #   define STAT_BUF_SIZE 4096
   #   ifdef USE_LD_WRAP
   #       define STAT_READ __real_read
   #   else
   #       define STAT_READ read
   #   endif
       char stat_buf[STAT_BUF_SIZE];
       int f;
       char c;
       word result = 0;
       size_t i, buf_offset = 0;
   
       f = open("/proc/self/stat", O_RDONLY);
       if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) {
           ABORT("Couldn't read /proc/self/stat");
       }
       c = stat_buf[buf_offset++];
       /* Skip the required number of fields.  This number is hopefully    */
       /* constant across all Linux implementations.                       */
         for (i = 0; i < STAT_SKIP; ++i) {
           while (isspace(c)) c = stat_buf[buf_offset++];
           while (!isspace(c)) c = stat_buf[buf_offset++];
         }
       while (isspace(c)) c = stat_buf[buf_offset++];
       while (isdigit(c)) {
         result *= 10;
         result += c - '0';
         c = stat_buf[buf_offset++];
       }
       close(f);
       if (result < 0x10000000) ABORT("Absurd stack bottom value");
       return (ptr_t)result;
     }
   
   #endif /* LINUX_STACKBOTTOM */
   
 ptr_t GC_get_stack_base()  ptr_t GC_get_stack_base()
 {  {
     word dummy;      word dummy;
Line 629  ptr_t GC_get_stack_base()
Line 685  ptr_t GC_get_stack_base()
                               & ~STACKBOTTOM_ALIGNMENT_M1);                                & ~STACKBOTTOM_ALIGNMENT_M1);
 #          endif  #          endif
 #       endif /* HEURISTIC1 */  #       endif /* HEURISTIC1 */
   #       ifdef LINUX_STACKBOTTOM
              result = GC_linux_stack_base();
   #       endif
 #       ifdef HEURISTIC2  #       ifdef HEURISTIC2
 #           ifdef STACK_GROWS_DOWN  #           ifdef STACK_GROWS_DOWN
                 result = GC_find_limit((ptr_t)(&dummy), TRUE);                  result = GC_find_limit((ptr_t)(&dummy), TRUE);
Line 1462  void GC_default_push_other_roots()
Line 1521  void GC_default_push_other_roots()
   
 # if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \  # if defined(SOLARIS_THREADS) || defined(WIN32_THREADS) \
      || defined(IRIX_THREADS) || defined(LINUX_THREADS) \       || defined(IRIX_THREADS) || defined(LINUX_THREADS) \
      || defined(IRIX_PCR_THREADS)       || defined(IRIX_JDK_THREADS) || defined(HPUX_THREADS)
   
 extern void GC_push_all_stacks();  extern void GC_push_all_stacks();
   
Line 1589  struct hblk *h;
Line 1648  struct hblk *h;
 #   include <sys/syscall.h>  #   include <sys/syscall.h>
   
 #   define PROTECT(addr, len) \  #   define PROTECT(addr, len) \
           if (mprotect((caddr_t)(addr), (int)(len), \            if (mprotect((caddr_t)(addr), (size_t)(len), \
                        PROT_READ | OPT_PROT_EXEC) < 0) { \                         PROT_READ | OPT_PROT_EXEC) < 0) { \
             ABORT("mprotect failed"); \              ABORT("mprotect failed"); \
           }            }
 #   define UNPROTECT(addr, len) \  #   define UNPROTECT(addr, len) \
           if (mprotect((caddr_t)(addr), (int)(len), \            if (mprotect((caddr_t)(addr), (size_t)(len), \
                        PROT_WRITE | PROT_READ | OPT_PROT_EXEC ) < 0) { \                         PROT_WRITE | PROT_READ | OPT_PROT_EXEC ) < 0) { \
             ABORT("un-mprotect failed"); \              ABORT("un-mprotect failed"); \
           }            }
Line 1623  struct hblk *h;
Line 1682  struct hblk *h;
     typedef void (* SIG_PF)();      typedef void (* SIG_PF)();
 #endif  #endif
 #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX)  #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX)
   # ifdef __STDC__
     typedef void (* SIG_PF)(int);      typedef void (* SIG_PF)(int);
   # else
       typedef void (* SIG_PF)();
   # endif
 #endif  #endif
 #if defined(MSWIN32)  #if defined(MSWIN32)
     typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_PF;      typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_PF;
Line 1635  struct hblk *h;
Line 1698  struct hblk *h;
     typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);      typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
 #endif  #endif
 #if defined(SUNOS5SIGS)  #if defined(SUNOS5SIGS)
     typedef void (* REAL_SIG_PF)(int, struct siginfo *, void *);  # ifdef HPUX
   #   define SIGINFO __siginfo
   # else
   #   define SIGINFO siginfo
   # endif
   # ifdef __STDC__
       typedef void (* REAL_SIG_PF)(int, struct SIGINFO *, void *);
   # else
       typedef void (* REAL_SIG_PF)();
   # endif
 #endif  #endif
 #if defined(LINUX)  #if defined(LINUX)
 #   include <linux/version.h>  #   include <linux/version.h>
 #   if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA)  #   if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA) || defined(IA64)
       typedef struct sigcontext s_c;        typedef struct sigcontext s_c;
 #   else  #   else
       typedef struct sigcontext_struct s_c;        typedef struct sigcontext_struct s_c;
 #   endif  #   endif
   #   if defined(ALPHA) || defined(M68K)
         typedef void (* REAL_SIG_PF)(int, int, s_c *);
   #   else
   #     if defined(IA64)
           typedef void (* REAL_SIG_PF)(int, siginfo_t *, s_c *);
   #     else
           typedef void (* REAL_SIG_PF)(int, s_c);
   #     endif
   #   endif
 #   ifdef ALPHA  #   ifdef ALPHA
     typedef void (* REAL_SIG_PF)(int, int, s_c *);  
     /* Retrieve fault address from sigcontext structure by decoding     */      /* Retrieve fault address from sigcontext structure by decoding     */
     /* instruction.                                                     */      /* instruction.                                                     */
     char * get_fault_addr(s_c *sc) {      char * get_fault_addr(s_c *sc) {
Line 1657  struct hblk *h;
Line 1737  struct hblk *h;
         faultaddr += (word) (((int)instr << 16) >> 16);          faultaddr += (word) (((int)instr << 16) >> 16);
         return (char *)faultaddr;          return (char *)faultaddr;
     }      }
 #   else /* !ALPHA */  
     typedef void (* REAL_SIG_PF)(int, s_c);  
 #   endif /* !ALPHA */  #   endif /* !ALPHA */
 # endif  # endif
   
Line 1694  SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS
Line 1772  SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS
 #   endif  #   endif
 # endif  # endif
 # if defined(LINUX)  # if defined(LINUX)
 #   ifdef ALPHA  #   if defined(ALPHA) || defined(M68K)
       void GC_write_fault_handler(int sig, int code, s_c * sc)        void GC_write_fault_handler(int sig, int code, s_c * sc)
 #   else  #   else
       void GC_write_fault_handler(int sig, s_c sc)  #     if defined(IA64)
           void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
   #     else
           void GC_write_fault_handler(int sig, s_c sc)
   #     endif
 #   endif  #   endif
 #   define SIG_OK (sig == SIGSEGV)  #   define SIG_OK (sig == SIGSEGV)
 #   define CODE_OK TRUE  #   define CODE_OK TRUE
         /* Empirically c.trapno == 14, but is that useful?      */          /* Empirically c.trapno == 14, on IA32, but is that useful?     */
         /* We assume Intel architecture, so alignment           */          /* Should probably consider alignment issues on other           */
         /* faults are not possible.                             */          /* architectures.                                               */
 # endif  # endif
 # if defined(SUNOS5SIGS)  # if defined(SUNOS5SIGS)
     void GC_write_fault_handler(int sig, struct siginfo *scp, void * context)  #  ifdef __STDC__
 #   define SIG_OK (sig == SIGSEGV)      void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
 #   define CODE_OK (scp -> si_code == SEGV_ACCERR)  #  else
       void GC_write_fault_handler(sig, scp, context)
       int sig;
       struct SIGINFO *scp;
       void * context;
   #  endif
   #   ifdef HPUX
   #     define SIG_OK (sig == SIGSEGV || sig == SIGBUS)
   #     define CODE_OK (scp -> si_code == SEGV_ACCERR) \
                        || (scp -> si_code == BUS_ADRERR) \
                        || (scp -> si_code == BUS_UNKNOWN) \
                        || (scp -> si_code == SEGV_UNKNOWN) \
                        || (scp -> si_code == BUS_OBJERR)
   #   else
   #     define SIG_OK (sig == SIGSEGV)
   #     define CODE_OK (scp -> si_code == SEGV_ACCERR)
   #   endif
 # endif  # endif
 # if defined(MSWIN32)  # if defined(MSWIN32)
     LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info)      LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info)
Line 1760  SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS
Line 1858  SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS
 #         ifdef ALPHA  #         ifdef ALPHA
             char * addr = get_fault_addr(sc);              char * addr = get_fault_addr(sc);
 #         else  #         else
   #           ifdef IA64
                 char * addr = si -> si_addr;
                 /* I believe this is claimed to work on all platforms for */
                 /* Linux 2.3.47 and later.  Hopefully we don't have to    */
                 /* worry about earlier kernels on IA64.                   */
   #           else
   #             if defined(POWERPC)
                   char * addr = (char *) (sc.regs->dar);
   #             else
                 --> architecture not supported                  --> architecture not supported
   #             endif
   #           endif
 #         endif  #         endif
 #       endif  #       endif
 #     endif  #     endif
Line 1813  SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS
Line 1922  SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS
                     return;                      return;
 #               endif  #               endif
 #               if defined (LINUX)  #               if defined (LINUX)
 #                   ifdef ALPHA  #                   if defined(ALPHA) || defined(M68K)
                         (*(REAL_SIG_PF)old_handler) (sig, code, sc);                          (*(REAL_SIG_PF)old_handler) (sig, code, sc);
 #                   else  #                   else
   #                     if defined(IA64)
                           (*(REAL_SIG_PF)old_handler) (sig, si, scp);
   #                     else
                         (*(REAL_SIG_PF)old_handler) (sig, sc);                          (*(REAL_SIG_PF)old_handler) (sig, sc);
   #                     endif
 #                   endif  #                   endif
                     return;                      return;
 #               endif  #               endif
Line 1928  void GC_dirty_init()
Line 2041  void GC_dirty_init()
       }        }
 #   endif  #   endif
 #   if defined(SUNOS5SIGS) || defined(IRIX5)  #   if defined(SUNOS5SIGS) || defined(IRIX5)
 #     if defined(IRIX_THREADS) || defined(IRIX_PCR_THREADS)  #     if defined(IRIX_THREADS) || defined(IRIX_JDK_THREADS)
         sigaction(SIGSEGV, 0, &oldact);          sigaction(SIGSEGV, 0, &oldact);
         sigaction(SIGSEGV, &act, 0);          sigaction(SIGSEGV, &act, 0);
 #     else  #     else
Line 1954  void GC_dirty_init()
Line 2067  void GC_dirty_init()
           GC_err_printf0("Replaced other SIGSEGV handler\n");            GC_err_printf0("Replaced other SIGSEGV handler\n");
 #       endif  #       endif
       }        }
   #     ifdef HPUX
             sigaction(SIGBUS, &act, &oldact);
             GC_old_bus_handler = oldact.sa_handler;
             if (GC_old_segv_handler != SIG_DFL) {
   #           ifdef PRINTSTATS
                 GC_err_printf0("Replaced other SIGBUS handler\n");
   #           endif
             }
   #     endif
 #    endif  #    endif
 #   if defined(MSWIN32)  #   if defined(MSWIN32)
       GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);        GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
Line 2045  word len;
Line 2167  word len;
               ((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE);                ((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE);
 }  }
   
 #ifndef MSWIN32  #if !defined(MSWIN32) && !defined(LINUX_THREADS)
 /* Replacement for UNIX system call.     */  /* Replacement for UNIX system call.     */
 /* Other calls that write to the heap    */  /* Other calls that write to the heap    */
 /* should be handled similarly.          */  /* should be handled similarly.          */
 # if defined(__STDC__) && !defined(SUNOS4)  # if defined(__STDC__) && !defined(SUNOS4)
 #   include <unistd.h>  #   include <unistd.h>
   #   include <sys/uio.h>
     ssize_t read(int fd, void *buf, size_t nbyte)      ssize_t read(int fd, void *buf, size_t nbyte)
 # else  # else
 #   ifndef LINT  #   ifndef LINT
Line 2067  word len;
Line 2190  word len;
   
     GC_begin_syscall();      GC_begin_syscall();
     GC_unprotect_range(buf, (word)nbyte);      GC_unprotect_range(buf, (word)nbyte);
 #   ifdef IRIX5  #   if defined(IRIX5) || defined(LINUX_THREADS)
         /* Indirect system call may not always be easily available.     */          /* Indirect system call may not always be easily available.     */
         /* We could call _read, but that would interfere with the       */          /* We could call _read, but that would interfere with the       */
         /* libpthread interception of read.                             */          /* libpthread interception of read.                             */
           /* On Linux, we have to be careful with the linuxthreads        */
           /* read interception.                                           */
         {          {
             struct iovec iov;              struct iovec iov;
   
Line 2084  word len;
Line 2209  word len;
     GC_end_syscall();      GC_end_syscall();
     return(result);      return(result);
 }  }
 #endif /* !MSWIN32 */  #endif /* !MSWIN32 && !LINUX */
   
   #ifdef USE_LD_WRAP
       /* We use the GNU ld call wrapping facility.                        */
       /* This requires that the linker be invoked with "--wrap read".     */
       /* This can be done by passing -Wl,"--wrap read" to gcc.            */
       /* I'm not sure that this actually wraps whatever version of read   */
       /* is called by stdio.  That code also mentions __read.             */
   #   include <unistd.h>
       ssize_t __wrap_read(int fd, void *buf, size_t nbyte)
       {
           int result;
   
           GC_begin_syscall();
           GC_unprotect_range(buf, (word)nbyte);
           result = __real_read(fd, buf, nbyte);
           GC_end_syscall();
           return(result);
       }
   
       /* We should probably also do this for __read, or whatever stdio    */
       /* actually calls.                                                  */
   #endif
   
 /*ARGSUSED*/  /*ARGSUSED*/
 GC_bool GC_page_was_ever_dirty(h)  GC_bool GC_page_was_ever_dirty(h)

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.3

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>