The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/include/setjmp.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* The <setjmp.h> header relates to the C phenomenon known as setjmp/longjmp.
    2  * It is used to escape out of the current situation into a previous one.
    3  * A typical example is in an editor, where hitting DEL breaks off the current
    4  * command and puts the editor back in the main loop, though care has to be
    5  * taken when the DEL occurs while executing a library function, since
    6  * some of them are not reentrant.
    7  *
    8  * POSIX does not require the process signal mask to be saved and restored
    9  * during setjmp/longjmp.  However, the current implementation does this
   10  * in order to agree with OSF/1 and other BSD derived systems.
   11  *
   12  * The pair of functions _setjmp/_longjmp may be used when the signal
   13  * mask is not to be saved/restored.  These functions are traditional
   14  * in BSD systems.
   15  *
   16  * There are different ways of implementing setjmp/longjmp.  Probably
   17  * the best way is to unify it with signal handling.  This is true for the
   18  * following reasons:  Both setjmp/longjmp and signal delivery must save 
   19  * a context so that it may be restored later.  The jmp_buf necessarily 
   20  * contains signal information, namely the signal mask to restore.  Both
   21  * longjmp and the return of a signal handler must trap to the operating
   22  * system to restore the previous signal mask.  Finally, the jmp_buf
   23  * and the sigcontext structure contain the registers to restore.
   24  *
   25  * Some compilers, namely ACK, will not enregister any variables inside a
   26  * function containing a call to setjmp, even if those variables are
   27  * explicitly declared as register variables.  Thus for ACK, the
   28  * identification of the jmp_buf with a sigcontext structure would cause
   29  * unnecessary overhead: the jmp_buf has room for all the registers, but
   30  * the only registers that need to be saved are the stack pointer, 
   31  * frame pointer, and program counter.
   32  *
   33  * So, for ACK a jmp_buf is much smaller than a sigcontext structure, and
   34  * longjmp does not directly call sigreturn.  Instead, longjmp calls a
   35  * front-end function which initializes the appropriate fields of a
   36  * sigcontext structure, marks this structure as containing no valid
   37  * general purpose registers, and then calls sigreturn.
   38  *
   39  * The POSIX sigjmp_buf is identical to the jmp_buf in all cases.
   40  *
   41  * Different compilers have different symbols that they recognize as
   42  * setjmp symbols.  ACK recognizes __setjmp, the GNU C compiler
   43  * recognizes setjmp and _setjmp, and BCC recognizes all three.
   44  * When these symbols occur within a function, the compiler may keep 
   45  * all local variables on the stack, avoid certain optimizations, or
   46  * pass hidden arguments to the setjmp function.
   47  *  
   48  * Thus, setjmp implementations vary in two independent ways which may
   49  * be identified through the following preprocessor tokens:
   50  *
   51  * _SETJMP_SYMBOL -- If 0, this means the compiler treats setjmp and _setjmp
   52  * specially.  If 1, this means the compiler treats __setjmp specially.
   53  *
   54  * _SETJMP_SAVES_REGS -- If 1, this means setjmp/longjmp must explicitly
   55  * save and restore all registers.  This also implies that a jmp_buf is
   56  * different than a sigcontext structure.  If 0, this means that the compiler
   57  * will not use register variables within a function that calls one of 
   58  * its SETJMP_SYMBOLs. 
   59  * 
   60  * When _SETJMP_SYMBOL = 1, the implementation has a few dozen bytes of
   61  * unnecessary overhead.  This happens in the following manner:  a program uses
   62  * _setjmp/_longjmp because it is not interested in saving and restoring the
   63  * signal mask. Nevertheless, because _setjmp expands to the general purpose
   64  * function __setjmp, code for sigprocmask(2) is linked into the program.  
   65  */
   66 
   67 #ifndef _SETJMP_H
   68 #define _SETJMP_H
   69 
   70 #ifndef _ANSI_H
   71 #include <ansi.h>
   72 #endif
   73 
   74 #if !defined(__ACK__) && !defined(__BCC__) && !defined(__GNUC__)
   75 #define __ACK__
   76 #endif
   77 
   78 #ifdef __ACK__
   79 #define _SETJMP_SYMBOL 1
   80 #define _SETJMP_SAVES_REGS 0
   81 #endif
   82 #ifdef __BCC__
   83 #define _SETJMP_SYMBOL 0
   84 #define _SETJMP_SAVES_REGS 1
   85 #endif
   86 #ifdef __GNUC__
   87 #define _SETJMP_SYMBOL 1
   88 #define _SETJMP_SAVES_REGS 1
   89 #endif
   90 
   91 /* The jmp_buf data type.  Do not change the order of these fields -- some
   92  * C library code refers to these fields by name.  When _SETJMP_SAVES_REGS
   93  * is 1, the file <sys/jmp_buf.h> gives the usage of the sixteen registers.
   94  */
   95 typedef struct {
   96   int __flags;                  /* XXX - long might give better alignment */
   97   long __mask;                  /* must have size >= sizeof(sigset_t) */
   98 #if (_SETJMP_SAVES_REGS == 0)
   99   _PROTOTYPE(void (*__pc),(void));      /* program counter */
  100   void *__sp;                   /* stack pointer */
  101   void *__lb;                   /* local base (ACKspeak for frame pointer) */
  102 #else
  103   void *__regs[16];             /* size is machine dependent */
  104 #endif
  105 } jmp_buf[1];
  106 
  107 #if (_SETJMP_SYMBOL == 1)
  108 
  109 _PROTOTYPE( int __setjmp, (jmp_buf _env, int _savemask)                 );
  110 _PROTOTYPE( void longjmp, (jmp_buf _env, int _val)                      );
  111 _PROTOTYPE(int sigjmp, (jmp_buf _jb, int _retval)                       );
  112 
  113 #define setjmp(env)     __setjmp((env), 1)
  114 
  115 #ifdef _MINIX
  116 #define _setjmp(env)    __setjmp((env), 0)
  117 _PROTOTYPE(void _longjmp, (jmp_buf _env, int _val)                      );
  118 #endif
  119 
  120 #ifdef _POSIX_SOURCE
  121 typedef jmp_buf sigjmp_buf;
  122 #ifdef __GNUC__
  123 #define siglongjmp longjmp
  124 #else
  125 _PROTOTYPE( void siglongjmp, (sigjmp_buf _env, int _val)                );
  126 #endif
  127 
  128 #define sigsetjmp(env, savemask) __setjmp((env), (savemask))
  129 #endif /* _POSIX_SOURCE */
  130 
  131 #endif /* _SETJMP_SYMBOL == 1 */
  132 
  133 #if (_SETJMP_SYMBOL == 0)
  134 
  135 _PROTOTYPE( int setjmp, (jmp_buf _env)                                  );
  136 _PROTOTYPE( void longjmp, (jmp_buf _env, int _val)                      );
  137 
  138 #ifdef _MINIX
  139 _PROTOTYPE( int _setjmp, (jmp_buf _env)                                 );
  140 _PROTOTYPE( void _longjmp, (jmp_buf _env, int _val)                     );
  141 #endif
  142 
  143 #ifdef _POSIX_SOURCE
  144 #define sigjmp_buf jmp_buf
  145 _PROTOTYPE( void siglongjmp, (sigjmp_buf _env, int _val)                );
  146 /* XXX - the name _setjmp is no good - that's why ACK used __setjmp. */
  147 #define sigsetjmp(env, savemask) ((savemask) ? setjmp(env) : _setjmp(env))
  148 #endif /* _POSIX_SOURCE */
  149 
  150 #endif /* _SETJMP_SYMBOL == 0 */
  151 
  152 #endif /* _SETJMP_H */

Cache object: 9853928a94c472b7a01829238d328a96


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.