Print this page
5261 libm should stop using synonyms.h
5298 fabs is 0-sized, confuses dis(1) and others
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Approved by: Gordon Ross <gwr@nexenta.com>
5262 libm needs to be carefully unifdef'd
5268 libm doesn't need to hide symbols which are already local
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Reviewed by: Gordon Ross <gwr@nexenta.com>
Approved by: Gordon Ross <gwr@nexenta.com>


  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 /*
  26  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 #include "fenv_synonyms.h"
  31 #undef lint
  32 #include <signal.h>
  33 #include <siginfo.h>
  34 #include <ucontext.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <unistd.h>
  38 #include <thread.h>
  39 #include <math.h>
  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 }


  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 /*
  26  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 

  30 #undef lint
  31 #include <signal.h>
  32 #include <siginfo.h>
  33 #include <ucontext.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <unistd.h>
  37 #include <thread.h>
  38 #include <math.h>
  39 #if defined(__SUNPRO_C)
  40 #include <sunmath.h>
  41 #endif
  42 #include <fenv.h>
  43 #include "fex_handler.h"
  44 #include "fenv_inlines.h"
  45 
  46 #if defined(__sparc) && !defined(__sparcv9)
  47 #include <sys/procfs.h>
  48 #endif
  49 
  50 /* 2.x signal.h doesn't declare sigemptyset or sigismember
  51    if they're #defined (see sys/signal.h) */
  52 extern int sigemptyset(sigset_t *);
  53 extern int sigismember(const sigset_t *, int);
  54 
  55 /* external globals */
  56 void (*__mt_fex_sync)() = NULL; /* for synchronization with libmtsk */
  57 #pragma weak __mt_fex_sync
  58 

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

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


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

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


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

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


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

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

 842 }