The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Интерактивная система просмотра системных руководств (man-ов)

 ТемаНаборКатегория 
 
 [Cписок руководств | Печать]

ieee_handler (3)
  • >> ieee_handler (3) ( Solaris man: Библиотечные вызовы )
  • 
    NAME
         ieee_handler - IEEE exception trap handler function
    
    SYNOPSIS
         cc [ flag ... ] file ...  -lsunmath -lm [ library ... ]
    
         #include <sunmath.h>
    
         long ieee_handler(const char *action, const char *exception,
         sigfpe_handler_type hdl);
    
    DESCRIPTION
         This function provides easy exception  handling  to  exploit
         ANSI/IEEE Std 754-1985 arithmetic in a C program.  The first
         two arguments are  pointers  to  strings.   For  efficiency,
         results  arising from invalid arguments and invalid combina-
         tions are undefined.
    
         There are three types of  action  :  ``get'',  ``set'',  and
         ``clear''.  There are five types of exception :
              ``inexact''
              ``division''   ... division by zero exception
              ``underflow''
              ``overflow''
              ``invalid''
              ``all''        ... all five exceptions above
              ``common''     ...  invalid,  overflow,  and   division
                             exceptions
    
         Note: ``all'' and ``common'' only make sense with ``set'' or
         ``clear''.
    
         hdl contains  the  address  of  a  signal-handling  routine.
         <floatingpoint.h> defines sigfpe_handler_type .
    
         ``get'' will return the location of the current handler rou-
         tine for exception cast to a long.
    
         ``set'' will set the routine pointed at by  hdl  to  be  the
         handler  routine  and  at  the  same time enable the trap on
         exception,   except   when   hdl   ==   SIGFPE_DEFAULT    or
         SIGFPE_IGNORE;  then ieee_handler() will disable the trap on
         exception.  When hdl == SIGFPE_ABORT, any trap on  exception
         will dump core using abort(3).
    
         ``clear''  disables  trapping  on  exception  and  sets  the
         handler  routine for exception to SIGFPE_DEFAULT.  ``clear''
         ``all'' disables trapping on all five  exceptions  and  sets
         the   handler   routine   for   all   five   exceptions   to
         SIGFPE_DEFAULT.
    
    
         Two steps are required to intercept an  IEEE-related  SIGFPE
         code with ieee_handler:
    
         1)   Set up a handler with ieee_handler.
    
         2)   Perform a floating-point operation that  generates  the
              intended IEEE exception.
    
         ieee_handler() also  adjusts  floating-point  hardware  mode
         bits   affecting  IEEE  trapping.   For  ``clear'',  ``set''
         SIGFPE_DEFAULT, or ``set'' SIGFPE_IGNORE, the hardware  trap
         is  disabled.   For  any other ``set'', the hardware trap is
         enabled.
    
         SIGFPE   signals   can   be   handled   using   sigaction(2)
         ieee_handler(3M), or fex_set_handling(3M).
    
         In a particular program, to avoid confusion, use only one of
         these interfaces to handle SIGFPE signals.
    
    
    DIAGNOSTICS
         ieee_handler() normally returns 0 for  ``set'';  1  will  be
         returned  if  the action is not available (for instance, not
         supported in hardware).  For ``get'',  the  address  of  the
         current handler is returned, cast to a long.
    
    EXAMPLE
         Here we give an example of how to trap an invalid signal and
         change the default output (NaN) to a user given value if the
         exception is caused by  zero/zero.   Following  is  a  user-
         specified  signal  handler  (appropriate  for  SPARC systems
         only):
    
              /*
               * Sample user exception handler routine. In this example, we trap on the
               * invalid signal. Then we check if the exception is of zero/zero type. If
               * yes, we set the result = zero_over_zero_value (user given).
               */
    
              #include <sunmath.h>
              #include <siginfo.h>
              #include <ucontext.h>
    
              extern double zero_over_zero_value;
    
              void zero_over_zero_handler(int sig, siginfo_t *sip, ucontext_t *uap) {
                   fpregset_t *uc = &uap->uc_mcontext.fpregs; /* see <sys/reg.h> for structure fpregset_t */
                   const int fopshift = 5, frdshift = 25, frs1shift = 14, frs2shift = 0;
                   int  i, j, fop, frd, frs1, frs2;
                   int  *con = (int *) &zero_over_zero_value;
              /*
               * find out registers rd, rs1, rs2, and opf
               */
                   fop = ((uc->fpu_q->FQu.fpq.fpq_instr)>>fopshift) &0x1ff;
                   frd = ((uc->fpu_q->FQu.fpq.fpq_instr)>>frdshift) &0x1f;
                   frs1= ((uc->fpu_q->FQu.fpq.fpq_instr)>>frs1shift)&0x1f;
                   frs2= ((uc->fpu_q->FQu.fpq.fpq_instr)>>frs2shift )&0x1f;
              /*
               * check if both rs1 and rs2 are zero (0/0 case)
               */
                   i = (uc->fpu_fr.fpu_regs[frs2]&0x7fffffff)|uc->fpu_fr.fpu_regs[frs2+1];
                   j = (uc->fpu_fr.fpu_regs[frs1]&0x7fffffff)|uc->fpu_fr.fpu_regs[frs1+1];
                   switch (fop) {
                        case 0x4e:     /* fdivd */
                        if((i|j) == 0) {    /* 0/0 , set rd to be zero_over_zero_value */
                             uc->fpu_fr.fpu_regs[frd] = con[0];
                             uc->fpu_fr.fpu_regs[frd+1] = con[1];
                        }
                        break;
                   }
              }
    
    
         and it might be set up like this:
    
              #include <stdio.h>
              #include <stdlib.h>
              #include <sunmath.h>
              #include <siginfo.h>
              #include <ucontext.h>
              extern void zero_over_zero_handler(int, siginfo_t *, ucontext_t *);
              double zero_over_zero_value;
    
              void
              main(void) {
                   extern double sin(double);
                   double x, w;
                   int i, k;
                   sigfpe_handler_type hdl, old_handler1;
              /*
               * save current invalid handler
               */
                   old_handler1 = (sigfpe_handler_type) ieee_handler("get", "invalid", (sigfpe_handler_type)0);
              /*
               * set up new invalid handler
               */
                   hdl = (sigfpe_handler_type) zero_over_zero_handler;
                   (void) ieee_handler("set", "invalid", hdl);
              /*
               *  compute (k*x)/sin(x) for k=2, x=0.5, 0.4, ..., 0.1, 0.0
               */
                   k = 2.0;  /* user specified */
                   (void) printf("Evaluating f(x) = (k*x)/sin(x)\n\n");
                   zero_over_zero_value = k;
                   for (i = 5; i >= 0; i--) {
                           x = (double) i * 0.1;
                           w = (k * x) / sin(x);
                           (void) printf("\tx=%3.3f\t f(x) = % 1.20e\n", x, w);
                   }
              /*
               * restore old invalid handler
               */
                   (void) ieee_handler("set", "invalid", old_handler1);
                   exit(0);
                   /* NOTREACHED */
              }
    
         Here is what the output looks like:
              Evaluating f(x) = (k*x)/sin(x)
    
                   x=0.500  f(x) =  2.08582964293348816000e+00
                   x=0.400  f(x) =  2.05434596443822626000e+00
                   x=0.300  f(x) =  2.03031801709447368000e+00
                   x=0.200  f(x) =  2.01339581906893761000e+00
                   x=0.100  f(x) =  2.00333722632695554000e+00
                   x=0.000  f(x) =  2.00000000000000000000e+00
    
         Note that when x=0, f(x) =  0/0  and  an  invalid  exception
         occurs. The value of 0/0 is set to be 2.0 in this example.
    
    ATTRIBUTES
         See attributes(5) for descriptions of the  following  attri-
         butes:
    
         _______________________________________
        |   ATTRIBUTE TYPE   |  ATTRIBUTE VALUE|
        |____________________|__________________|_
        | Availability       |  SPROlang       |
        | Interface Stability|  Evolving       |
        | MT-Level           |  MT-Safe        |
        |____________________|_________________|
    
    SEE ALSO
         sigaction(2),     signal(2),      sigfpe(3),      abort(3C),
         fex_set_handling(3M),  ieee_flags(3M),  attributes(5),  sig-
         info(5), signal(5), ucontext(5)
    
    NOTES
         On Intel systems, the floating point hardware traps whenever
         an  exception's  trap  is  enabled  (i.e.,  the exception is
         "unmasked") and its corresponding  flag  is  raised.   Thus,
         enabling  a  trap  for  an exception via ieee_handler() will
         provoke a subsequent trap if the exception's flag is already
         raised  when ieee_handler() is called.  To avoid such spuri-
         ous traps, a program should clear the flags corresponding to
         each  exception  for  which  trapping will be enabled before
         calling ieee_handler().  (The ieee_flags(3M)  function  pro-
         vides one way to clear exception flags.)
    
    
    
    


    Поиск по тексту MAN-ов: 




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру