static VOID i_EX_t_setcontext( EX_CONTEXT *context ) { EX_CONTEXT **ex_psptr; STATUS status; if ( EXcontextkey == 0 ) { ME_tls_createkey( &EXcontextkey, &status ); ME_tls_set( EXcontextkey, NULL, &status ); if ( EXcontextkey == 0 ) { /* not linked with threaded libraries */ EXcontextkey = -1; } } if ( EXcontextkey == -1 ) { /* not linked with threaded libraries */ ex_sptr = context; } else { ex_psptr = (EX_CONTEXT **) MEreqmem( 0, sizeof(EX_CONTEXT **), TRUE, NULL ); ME_tls_set( EXcontextkey, (PTR)ex_psptr, &status ); *ex_psptr = context; } return; }
STATUS FPdmath(int op, double *x, double *y, double *result) { double internal_result; STATUS status; TYPESIG fpmathsig(); jmp_buf *fpmathjmp_ptr = NULL; if (!FPdfinite(x) || !FPdfinite(y)) { status = FP_NOT_FINITE_ARGUMENT; } else if (op == FDIV && *y == 0.0) { status = FP_DIVIDE_BY_ZERO; } else { status = FAIL; # ifndef DESKTOP # ifdef OS_THREADS_USED if ( FPfpmathkey == 0 ) { ME_tls_createkey( &FPfpmathkey, &status ); ME_tls_set( FPfpmathkey, NULL, &status ); } if ( FPfpmathkey == 0 ) { /* not linked with threading libraries */ FPfpmathkey = -1; } if ( FPfpmathkey == -1 ) { fpmathjmp_ptr = &fpmathjmp; } else { ME_tls_get( FPfpmathkey, (PTR *)&fpmathjmp_ptr, &status ); if ( fpmathjmp_ptr == NULL ) { fpmathjmp_ptr = (jmp_buf *) MEreqmem( 0, sizeof(jmp_buf), TRUE, NULL ); ME_tls_set( FPfpmathkey, (PTR)fpmathjmp_ptr, &status ); } } # else /* OS_THREADS_USED */ fpmathjmp_ptr = &fpmathjmp; # endif /* OS_THREADS_USED */ if (!setjmp(*fpmathjmp_ptr)) { i_EXsetothersig(SIGFPE, fpmathsig); errno = NOERR; switch(op) { case FADD: internal_result = *x + *y; break; case FSUB: internal_result = *x - *y; break; case FMUL: internal_result = *x * *y; break; case FDIV: internal_result = *x / *y; break; } /* Check to make sure the result is a finite number */ if (errno == NOERR && FPdfinite(&internal_result)) { *result = internal_result; status = OK; } } if (status != OK) status = (internal_result == 0.0) ? FP_UNDERFLOW : FP_OVERFLOW; i_EXrestoreorigsig(SIGFPE); # else /* DESKTOP */ __try { switch(op) { case FADD: internal_result = *x + *y; break; case FSUB: internal_result = *x - *y; break; case FMUL: internal_result = *x * *y; break; case FDIV: internal_result = *x / *y; break; } /* Check to make sure the result is a finite number */ if (FPdfinite(&internal_result)) { *result = internal_result; status = OK; } } __except (EXCEPTION_EXECUTE_HANDLER) { switch (GetExceptionCode()) { case EXCEPTION_FLT_OVERFLOW: status = FP_OVERFLOW; break; case EXCEPTION_FLT_UNDERFLOW: status = FP_UNDERFLOW; break; default: status = FP_OVERFLOW; break; } } # endif /* DESKTOP */ } return(status); }