Ignore:
Timestamp:
Nov 5, 2010, 3:45:55 PM (14 years ago)
Author:
garnier
Message:

update ti head

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/global/management/include/G4FPEDetection.hh

    r1337 r1340  
    2525//
    2626//
    27 // $Id: G4FPEDetection.hh,v 1.2 2006/11/15 16:00:18 gcosmo Exp $
    28 // GEANT4 tag $Name: geant4-09-04-beta-01 $
     27// $Id: G4FPEDetection.hh,v 1.5 2010/10/14 17:02:52 mkelsey Exp $
     28// GEANT4 tag $Name: global-V09-03-22 $
    2929//
    3030//
     
    3232//
    3333// -----------------------------------------------------------------------
    34 // This global method should be used on LINUX platforms with gcc compiler
    35 // for activating NaN detection and FPE signals, and forcing abortion of
    36 // the application at the time these are detected.
     34// This global method should be used on LINUX or MacOSX platforms with gcc
     35// compiler for activating NaN detection and FPE signals, and forcing
     36// abortion of the application at the time these are detected.
    3737// Meant to be used for debug purposes, can be activated by compiling the
    3838// "run" module with the flag G4FPE_DEBUG set in the environment.
     
    4141#ifndef G4FPEDetection_h
    4242#define G4FPEDetection_h 1
     43
     44#include <iostream>
     45#include <stdlib.h>  /* abort(), exit() */
    4346
    4447#ifdef __linux__
     
    4851  #include <csignal>
    4952
    50   #include <iostream>
    51 
    5253  struct sigaction termaction, oldaction;
    5354
    54   void TerminationSignalHandler(int sig)
     55  static void TerminationSignalHandler(int sig, siginfo_t* sinfo, void* /* context */)
    5556  {
    5657    std::cerr << "ERROR: " << sig;
    57     std::string message;
    58     switch (SIGFPE)
    59     {
     58    std::string message = "Floating-point exception (FPE).";
     59
     60    if (sinfo) {
     61      switch (sinfo->si_code) {
     62#ifdef FPE_NOOP         /* BUG: MacOSX uses this instead of INTDIV */
     63      case FPE_NOOP:
     64#endif
    6065      case FPE_INTDIV:
    6166        message = "Integer divide by zero.";
     
    8590        message = "Unknown error.";
    8691        break;
    87     }
     92      }
     93    }
     94
    8895    std::cerr << " - " << message << std::endl;
    89 
     96   
    9097    ::abort();
    9198  }
    9299
    93   void InvalidOperationDetection()
     100  static void InvalidOperationDetection()
    94101  {
    95102    std::cout << std::endl
     
    106113    //(void) feenableexcept( FE_UNDERFLOW );
    107114
    108     sigset_t *def_set;
    109     def_set=&termaction.sa_mask;
    110     sigfillset(def_set);
    111     sigdelset(def_set,SIGFPE);
    112     termaction.sa_handler=TerminationSignalHandler;
    113     termaction.sa_flags=0;
    114     sigaction(SIGFPE, &termaction,&oldaction);
    115   }
    116 #endif
    117 #else
    118   void InvalidOperationDetection() {;}
    119 #endif
    120 
    121 #endif
     115    sigdelset(&termaction.sa_mask,SIGFPE);
     116    termaction.sa_sigaction=TerminationSignalHandler;
     117    termaction.sa_flags=SA_SIGINFO;
     118    sigaction(SIGFPE, &termaction, &oldaction);
     119  }
     120#endif
     121#elif __MACH__      /* MacOSX */
     122
     123  #include <fenv.h>
     124  #include <signal.h>
     125
     126  #define DEFINED_PPC      (defined(__ppc__) || defined(__ppc64__))
     127  #define DEFINED_INTEL    (defined(__i386__) || defined(__x86_64__))
     128
     129  #if DEFINED_PPC
     130
     131    #define FE_EXCEPT_SHIFT 22  // shift flags right to get masks
     132    #define FM_ALL_EXCEPT    FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
     133
     134    static inline int feenableexcept (unsigned int excepts)
     135    {
     136      static fenv_t fenv;
     137      unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT,
     138                   old_excepts;  // all previous masks
     139
     140      if ( fegetenv (&fenv) )  { return -1; }
     141      old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
     142      fenv = (fenv & ~new_excepts) | new_excepts;
     143
     144      return ( fesetenv (&fenv) ? -1 : old_excepts );
     145    }
     146
     147    static inline int fedisableexcept (unsigned int excepts)
     148    {
     149      static fenv_t fenv;
     150      unsigned int still_on = ~((excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT),
     151                   old_excepts;  // previous masks
     152
     153      if ( fegetenv (&fenv) )  { return -1; }
     154      old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
     155      fenv &= still_on;
     156
     157      return ( fesetenv (&fenv) ? -1 : old_excepts );
     158    }
     159
     160  #elif DEFINED_INTEL
     161
     162    static inline int feenableexcept (unsigned int excepts)
     163    {
     164      static fenv_t fenv;
     165      unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
     166                   old_excepts;  // previous masks
     167
     168      if ( fegetenv (&fenv) )  { return -1; }
     169      old_excepts = fenv.__control & FE_ALL_EXCEPT;
     170
     171      // unmask
     172      //
     173      fenv.__control &= ~new_excepts;
     174      fenv.__mxcsr   &= ~(new_excepts << 7);
     175
     176      return ( fesetenv (&fenv) ? -1 : old_excepts );
     177    }
     178
     179    static inline int fedisableexcept (unsigned int excepts)
     180    {
     181      static fenv_t fenv;
     182      unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
     183                   old_excepts;  // all previous masks
     184
     185      if ( fegetenv (&fenv) )  { return -1; }
     186      old_excepts = fenv.__control & FE_ALL_EXCEPT;
     187
     188      // mask
     189      //
     190      fenv.__control |= new_excepts;
     191      fenv.__mxcsr   |= new_excepts << 7;
     192
     193      return ( fesetenv (&fenv) ? -1 : old_excepts );
     194    }
     195
     196  #endif  /* PPC or INTEL enabling */
     197
     198  static void TerminationSignalHandler(int sig, siginfo_t* sinfo, void* /* context */)
     199  {
     200    std::cerr << "ERROR: " << sig;
     201    std::string message = "Floating-point exception (FPE).";
     202
     203    if (sinfo) {
     204      switch (sinfo->si_code) {
     205#ifdef FPE_NOOP         /* BUG: MacOSX uses this instead of INTDIV */
     206      case FPE_NOOP:
     207#endif
     208      case FPE_INTDIV:
     209        message = "Integer divide by zero.";
     210        break;
     211      case FPE_INTOVF:
     212        message = "Integer overflow.";
     213        break;
     214      case FPE_FLTDIV:
     215        message = "Floating point divide by zero.";
     216        break;
     217      case FPE_FLTOVF:
     218        message = "Floating point overflow.";
     219        break;
     220      case FPE_FLTUND:
     221        message = "Floating point underflow.";
     222        break;
     223      case FPE_FLTRES:
     224        message = "Floating point inexact result.";
     225        break;
     226      case FPE_FLTINV:
     227        message = "Floating point invalid operation.";
     228        break;
     229      case FPE_FLTSUB:
     230        message = "Subscript out of range.";
     231        break;
     232      default:
     233        message = "Unknown error.";
     234        break;
     235      }
     236    }
     237
     238    std::cerr << " - " << message << std::endl;
     239   
     240    ::abort();
     241  }
     242
     243  static void InvalidOperationDetection()
     244  {
     245    struct sigaction termaction, oldaction;
     246
     247    std::cout << std::endl
     248              << "        "
     249              << "############################################" << std::endl
     250              << "        "
     251              << "!!! WARNING - FPE detection is activated !!!" << std::endl
     252              << "        "
     253              << "############################################" << std::endl;
     254
     255    feenableexcept ( FE_DIVBYZERO );
     256    feenableexcept ( FE_INVALID   );
     257    // fedisableexcept( FE_OVERFLOW  );
     258    // fedisableexcept( FE_UNDERFLOW );
     259
     260    sigdelset(&termaction.sa_mask,SIGFPE);
     261    termaction.sa_sigaction=TerminationSignalHandler;
     262    termaction.sa_flags=SA_SIGINFO;
     263    sigaction(SIGFPE, &termaction, &oldaction);
     264  }
     265#else  /* Not Linux, nor MacOSX ... */
     266
     267  static void InvalidOperationDetection() {;}
     268
     269#endif
     270
     271#endif
Note: See TracChangeset for help on using the changeset viewer.