Print this page
5262 libm needs to be carefully unifdef'd
5268 libm doesn't need to hide symbols which are already local


  40 #if defined(__SUNPRO_C)
  41 #include <sunmath.h>
  42 #endif
  43 #include <fenv.h>
  44 #include "fex_handler.h"
  45 #include "fenv_inlines.h"
  46 
  47 #if defined(__sparc) && !defined(__sparcv9)
  48 #include <sys/procfs.h>
  49 #endif
  50 
  51 /* 2.x signal.h doesn't declare sigemptyset or sigismember
  52    if they're #defined (see sys/signal.h) */
  53 extern int sigemptyset(sigset_t *);
  54 extern int sigismember(const sigset_t *, int);
  55 
  56 /* external globals */
  57 void (*__mt_fex_sync)() = NULL; /* for synchronization with libmtsk */
  58 #pragma weak __mt_fex_sync
  59 
  60 #ifdef LIBM_MT_FEX_SYNC
  61 void (*__libm_mt_fex_sync)() = NULL; /* new, improved version of above */
  62 #pragma weak __libm_mt_fex_sync
  63 #endif
  64 
  65 /* private variables */
  66 static fex_handler_t main_handlers;
  67 static int handlers_initialized = 0;
  68 static thread_key_t handlers_key;
  69 static mutex_t handlers_key_lock = DEFAULTMUTEX;
  70 
  71 static struct sigaction oact = { 0, SIG_DFL };
  72 static mutex_t hdlr_lock = DEFAULTMUTEX;
  73 static int hdlr_installed = 0;
  74 
  75 /* private const data */
  76 static const int te_bit[FEX_NUM_EXC] = {
  77         1 << fp_trap_inexact,
  78         1 << fp_trap_division,
  79         1 << fp_trap_underflow,
  80         1 << fp_trap_overflow,
  81         1 << fp_trap_invalid,
  82         1 << fp_trap_invalid,
  83         1 << fp_trap_invalid,


 128 __fex_sync_with_libmtsk(int begin, int master)
 129 {
 130         static fenv_t master_env;
 131         static int env_initialized = 0;
 132         static mutex_t env_lock = DEFAULTMUTEX;
 133 
 134         if (begin) {
 135                 mutex_lock(&env_lock);
 136                 if (master) {
 137                         (void) fegetenv(&master_env);
 138                         env_initialized = 1;
 139                 }
 140                 else if (env_initialized)
 141                         (void) fesetenv(&master_env);
 142                 mutex_unlock(&env_lock);
 143         }
 144         else if (master && fex_get_log())
 145                 __fex_update_te();
 146 }
 147 
 148 #ifdef LIBM_MT_FEX_SYNC
 149 /*
 150 *  The following function may be used for synchronization with any
 151 *  internal project that manages multiple threads
 152 */
 153 enum __libm_mt_fex_sync_actions {
 154         __libm_mt_fex_start_master = 0,
 155         __libm_mt_fex_start_slave,
 156         __libm_mt_fex_finish_master,
 157         __libm_mt_fex_finish_slave
 158 };
 159 
 160 struct __libm_mt_fex_sync_data {
 161         fenv_t  master_env;
 162         int             initialized;
 163         mutex_t lock;
 164 };
 165 
 166 static void
 167 __fex_sync_with_threads(enum __libm_mt_fex_sync_actions action,
 168         struct __libm_mt_fex_sync_data *thr_env)


 187                 __fex_update_te();
 188 #else
 189                 if (fex_get_log())
 190                         __fex_update_te();
 191 #endif
 192                 break;
 193 
 194         case __libm_mt_fex_finish_slave:
 195 #if defined(__x86)
 196                 /* clear traps, making all accrued flags visible in status word */
 197                 {
 198                         unsigned long   fsr;
 199                         __fenv_getfsr(&fsr);
 200                         __fenv_set_te(fsr, 0);
 201                         __fenv_setfsr(&fsr);
 202                 }
 203 #endif
 204                 break;
 205         }
 206 }
 207 #endif
 208 
 209 #if defined(__sparc)
 210 
 211 /*
 212 *  Code for setting or clearing interval mode on US-III and above.
 213 *  This is embedded as data so we don't have to mark the library
 214 *  as a v8plusb/v9b object.  (I could have just used one entry and
 215 *  modified the second word to set the bits I want, but that would
 216 *  have required another mutex.)
 217 */
 218 static const unsigned int siam[][2] = {
 219         { 0x81c3e008, 0x81b01020 }, /* retl, siam 0 */
 220         { 0x81c3e008, 0x81b01024 }, /* retl, siam 4 */
 221         { 0x81c3e008, 0x81b01025 }, /* retl, siam 5 */
 222         { 0x81c3e008, 0x81b01026 }, /* retl, siam 6 */
 223         { 0x81c3e008, 0x81b01027 }  /* retl, siam 7 */
 224 };
 225 
 226 /*
 227 *  If a handling mode is in effect, apply it; otherwise invoke the


 825                 sigaction(SIGFPE, &act, &tmpact);
 826                 if (tmpact.sa_handler != __fex_hdlr)
 827                 {
 828                         mutex_lock(&hdlr_lock);
 829                         oact = tmpact;
 830                         mutex_unlock(&hdlr_lock);
 831                 }
 832                 hdlr_installed = 1;
 833         }
 834 
 835         /* set the new trap enable bits (only if SIGFPE is not blocked) */
 836         if (sigprocmask(0, NULL, &blocked) == 0 &&
 837                 !sigismember(&blocked, SIGFPE)) {
 838                 __fenv_set_te(fsr, te);
 839                 __fenv_setfsr(&fsr);
 840         }
 841 
 842         /* synchronize with libmtsk */
 843         __mt_fex_sync = __fex_sync_with_libmtsk;
 844 
 845 #ifdef LIBM_MT_FEX_SYNC
 846         /* synchronize with other projects */
 847         __libm_mt_fex_sync = __fex_sync_with_threads;
 848 #endif
 849 }


  40 #if defined(__SUNPRO_C)
  41 #include <sunmath.h>
  42 #endif
  43 #include <fenv.h>
  44 #include "fex_handler.h"
  45 #include "fenv_inlines.h"
  46 
  47 #if defined(__sparc) && !defined(__sparcv9)
  48 #include <sys/procfs.h>
  49 #endif
  50 
  51 /* 2.x signal.h doesn't declare sigemptyset or sigismember
  52    if they're #defined (see sys/signal.h) */
  53 extern int sigemptyset(sigset_t *);
  54 extern int sigismember(const sigset_t *, int);
  55 
  56 /* external globals */
  57 void (*__mt_fex_sync)() = NULL; /* for synchronization with libmtsk */
  58 #pragma weak __mt_fex_sync
  59 

  60 void (*__libm_mt_fex_sync)() = NULL; /* new, improved version of above */
  61 #pragma weak __libm_mt_fex_sync

  62 
  63 /* private variables */
  64 static fex_handler_t main_handlers;
  65 static int handlers_initialized = 0;
  66 static thread_key_t handlers_key;
  67 static mutex_t handlers_key_lock = DEFAULTMUTEX;
  68 
  69 static struct sigaction oact = { 0, SIG_DFL };
  70 static mutex_t hdlr_lock = DEFAULTMUTEX;
  71 static int hdlr_installed = 0;
  72 
  73 /* private const data */
  74 static const int te_bit[FEX_NUM_EXC] = {
  75         1 << fp_trap_inexact,
  76         1 << fp_trap_division,
  77         1 << fp_trap_underflow,
  78         1 << fp_trap_overflow,
  79         1 << fp_trap_invalid,
  80         1 << fp_trap_invalid,
  81         1 << fp_trap_invalid,


 126 __fex_sync_with_libmtsk(int begin, int master)
 127 {
 128         static fenv_t master_env;
 129         static int env_initialized = 0;
 130         static mutex_t env_lock = DEFAULTMUTEX;
 131 
 132         if (begin) {
 133                 mutex_lock(&env_lock);
 134                 if (master) {
 135                         (void) fegetenv(&master_env);
 136                         env_initialized = 1;
 137                 }
 138                 else if (env_initialized)
 139                         (void) fesetenv(&master_env);
 140                 mutex_unlock(&env_lock);
 141         }
 142         else if (master && fex_get_log())
 143                 __fex_update_te();
 144 }
 145 

 146 /*
 147 *  The following function may be used for synchronization with any
 148 *  internal project that manages multiple threads
 149 */
 150 enum __libm_mt_fex_sync_actions {
 151         __libm_mt_fex_start_master = 0,
 152         __libm_mt_fex_start_slave,
 153         __libm_mt_fex_finish_master,
 154         __libm_mt_fex_finish_slave
 155 };
 156 
 157 struct __libm_mt_fex_sync_data {
 158         fenv_t  master_env;
 159         int             initialized;
 160         mutex_t lock;
 161 };
 162 
 163 static void
 164 __fex_sync_with_threads(enum __libm_mt_fex_sync_actions action,
 165         struct __libm_mt_fex_sync_data *thr_env)


 184                 __fex_update_te();
 185 #else
 186                 if (fex_get_log())
 187                         __fex_update_te();
 188 #endif
 189                 break;
 190 
 191         case __libm_mt_fex_finish_slave:
 192 #if defined(__x86)
 193                 /* clear traps, making all accrued flags visible in status word */
 194                 {
 195                         unsigned long   fsr;
 196                         __fenv_getfsr(&fsr);
 197                         __fenv_set_te(fsr, 0);
 198                         __fenv_setfsr(&fsr);
 199                 }
 200 #endif
 201                 break;
 202         }
 203 }

 204 
 205 #if defined(__sparc)
 206 
 207 /*
 208 *  Code for setting or clearing interval mode on US-III and above.
 209 *  This is embedded as data so we don't have to mark the library
 210 *  as a v8plusb/v9b object.  (I could have just used one entry and
 211 *  modified the second word to set the bits I want, but that would
 212 *  have required another mutex.)
 213 */
 214 static const unsigned int siam[][2] = {
 215         { 0x81c3e008, 0x81b01020 }, /* retl, siam 0 */
 216         { 0x81c3e008, 0x81b01024 }, /* retl, siam 4 */
 217         { 0x81c3e008, 0x81b01025 }, /* retl, siam 5 */
 218         { 0x81c3e008, 0x81b01026 }, /* retl, siam 6 */
 219         { 0x81c3e008, 0x81b01027 }  /* retl, siam 7 */
 220 };
 221 
 222 /*
 223 *  If a handling mode is in effect, apply it; otherwise invoke the


 821                 sigaction(SIGFPE, &act, &tmpact);
 822                 if (tmpact.sa_handler != __fex_hdlr)
 823                 {
 824                         mutex_lock(&hdlr_lock);
 825                         oact = tmpact;
 826                         mutex_unlock(&hdlr_lock);
 827                 }
 828                 hdlr_installed = 1;
 829         }
 830 
 831         /* set the new trap enable bits (only if SIGFPE is not blocked) */
 832         if (sigprocmask(0, NULL, &blocked) == 0 &&
 833                 !sigismember(&blocked, SIGFPE)) {
 834                 __fenv_set_te(fsr, te);
 835                 __fenv_setfsr(&fsr);
 836         }
 837 
 838         /* synchronize with libmtsk */
 839         __mt_fex_sync = __fex_sync_with_libmtsk;
 840 

 841         /* synchronize with other projects */
 842         __libm_mt_fex_sync = __fex_sync_with_threads;

 843 }