/* ************************************************************************* */ /* * * */ /* * HPE CONFIDENTIAL. This software is confidential proprietary software * */ /* * licensed by Hewlett Packard Enterprise Development, LP, and is not * */ /* * authorized to be used, duplicated or disclosed to anyone without the * */ /* * prior written permission of HPE. * */ /* * Copyright 2019 Hewlett Packard Enterprise Development, LP * */ /* * * */ /* * VMS SOFTWARE, INC. CONFIDENTIAL. This software is confidential * */ /* * proprietary software licensed by VMS Software, Inc., and is not * */ /* * authorized to be used, duplicated or disclosed to anyone without * */ /* * the prior written permission of VMS Software, Inc. * */ /* * Copyright 2019-2020 VMS Software, Inc. * */ /* * * */ /* ************************************************************************* */ /* * FACILITY: * * DECthreads core * * FILENAME: * * pthread_exception.h * * ABSTRACT: * * Header file for exception handling in C * * AUTHORS: * * Eric Roberts * Bob Conti * Dave Butenhof * * CREATION DATE: * * 15 March 1989 * * NEW MODIFICATION HISTORY * * X-44 CV-0572 Camiel Vanderhoeven 13-Aug-2020 * Use RBP (frame) field to compare stack frames rather than the * more expensive invocation context handle * * X-43 CV-0535 Camiel Vanderhoeven 19-Jun-2020 * Add omitted end-of-comment in lasy checkin. * * X-42 CV-0529 Camiel Vanderhoeven 19-Jun-2020 * Since x86_64 has no preserved floating point registers, there * is no need for an extended jump buffer for exceptions on x86, * and no need for 64-byte alignment of the exception context. * * X-41 CV-0520 Camiel Vanderhoeven 8-Jun-2020 * Fix size of jump buffer extension for x86. * * X-40 CV-0504 Camiel Vanderhoeven 22-May-2020 * Remove UNIX code and add x86 specifics. * * X-39 CEG0680 Clair Grant 04-Mar-2019 * Verify conditionals for x86 port. * Update copyright to VSI. * * * MODIFIED BY: * * Dave Butenhof * Bob Conti * Paul Curtin * Webb Scales * Peter Portante * Brian Silver * Mark Simons * Richard Love * Tom Dahl * * LAST MODIFICATION DATE: * * 21 October 1999 */ /* * This header file consists of two sections. The first is ANSI/POSIX * "clean", with no names disallowed by the standards (all names either begin * with "_" and a capital letter, or "__" and a lower case letter, or use the * POSIX 1003.1c-1995 "extension" namespace "PTHREAD" prefix with "_NP" * suffix or "pthread" prefix with "_np" suffix). The second contains the * "namespace-polluting" (non-standard) definitions that we've traditionally * documented for client use -- TRY, ENDTRY, and so forth. The two sections * each have separate "ifndef" tests, which allows this header file to be * included twice by the same module (once for the clean definitions and once * for the polluting definitions) and have everything work out nicely. Note * that always includes this header, so a separate include of * after will automatically activate the * "unclean" definitions. (A strictly conforming standard application must not * do this, since is not defined by any standard.) */ #ifndef _PTHREAD_EXCEPTION_CLEAN # define _PTHREAD_EXCEPTION_CLEAN # ifdef __cplusplus extern "C" { # endif /* * INCLUDE FILES */ # if defined (__DECCXX) # define _PTHREAD_EXC_CXX # define _PTHREAD_EXC_DECCXX # elif defined (__cplusplus) # define _PTHREAD_EXC_CXX # elif defined (__DECC) || defined (__decc) # define _PTHREAD_EXC_DECC # elif defined (__INTEL_COMPILER) # define _PTHREAD_EXC_INTELC # endif # define _PTHREAD_EXC_VMS # if defined (__alpha) || defined (__ALPHA) /* Verified for x86 port - Clair Grant */ # define _PTHREAD_EXC_ALPHA # elif defined (__ia64__) # define _PTHREAD_EXC_IA64 # elif defined (__x86_64) # define _PTHREAD_EXC_X86_64 # endif # pragma __extern_model __save # pragma __extern_model __strict_refdef # define _PTHREAD_EXC_IMPORT_ extern # include /* * Include the appropriate header files for the different operating systems. */ # include # include # include # include /* * This constant helps to identify a context block or exception created with * DECthreads BL9 or later; the new structures include a version field to * better manage future changes. */ # define _PTHREAD_EXC_NEWMAGIC 0x45586732 /* Identify ctx block with version */ # define _PTHREAD_EXC_THDBASE (_PTHREAD_EXC_NEWMAGIC | 0x01) /* * Define version constants to be put into exception structures. * * o V2 is for OpenVMS and non-native Tru64 UNIX exception handling. * o V3 is for native Tru64 UNIX exception handling (as defined before the * __flags field was added to _pthreadExcExt_t). * o V4 is for native Tru64 UNIX exception handling with the __flags field. * * This code checks the version to see how it should behave. */ # define _PTHREAD_EXC_VER_V2 2 # define _PTHREAD_EXC_VER_V3 3 # define _PTHREAD_EXC_VER_V4 4 # define _PTHREAD_EXC_VER_CUR _PTHREAD_EXC_VER_V2 # define _PTHREAD_EXC_FACILITY 00020100000 # define _PTHREAD_STATUS_(_val_, _sev_) \ ((__pthreadStatus_t)(_PTHREAD_EXC_FACILITY | ((_val_) << 3) | (_sev_))) /* * Define all of the status codes used by DECthreads. * * These must remain in synch with the CMA_MESSAGE.MSG message file. * * These values cannot be altered, as they have already been shipped! */ /* * Messages directly related to exceptions */ # define __pthread_exception_s _PTHREAD_STATUS_ (1, 4) # define __pthread_exccop_s _PTHREAD_STATUS_ (2, 4) # define __pthread_uninitexc_s _PTHREAD_STATUS_ (3, 4) # define __pthread_unkstatus_s _PTHREAD_STATUS_ (128, 4) # define __pthread_exccoplos_s _PTHREAD_STATUS_ (129, 4) # define __pthread_noexcmem_s _PTHREAD_STATUS_ (131, 4) /* * These should be set to match with underlying system exception codes on * platforms where that is appropriate (e.g., ss$_ codes on VMS). */ # pragma nostandard /* * A few of these codes are somewhat imaginary, since VMS doesn't support * condition codes that very closely approximate the sense of some UNIX * signals. SIGTRAP, SIGABRT, and SIGEMT have no clear parallels, and the * values chosen are fairly arbitrary. For two others, we chose what seemed * close equivalents: SIGPIPE becomes "no mailbox", and SIGXFSZ becomes "disk * quota exceeded". */ # define __pthread_illaddr_s SS$_ACCVIO # define __pthread_exquota_s SS$_EXQUOTA # define __pthread_insfmem_s SS$_INSFMEM # define __pthread_nopriv_s SS$_NOPRIV # define __pthread_normal_s SS$_NORMAL # define __pthread_illinstr_s SS$_OPCDEC # define __pthread_resaddr_s SS$_RADRMOD # define __pthread_privinst_s SS$_OPCDEC # define __pthread_resoper_s SS$_ROPRAND # define __pthread_SIGTRAP_s SS$_BREAK # define __pthread_SIGABRT_s SS$_ABORT # define __pthread_SIGEMT_s SS$_COMPAT # define __pthread_aritherr_s SS$_FLTOVF # define __pthread_SIGSYS_s SS$_BADPARAM # define __pthread_SIGPIPE_s SS$_NOMBX # define __pthread_excpu_s SS$_EXCPUTIM # define __pthread_exfilsiz_s SS$_EXDISKQUOTA # define __pthread_intovf_s SS$_INTOVF # define __pthread_intdiv_s SS$_INTDIV # define __pthread_fltovf_s SS$_FLTOVF # define __pthread_fltdiv_s SS$_FLTDIV # define __pthread_fltund_s SS$_FLTUND # define __pthread_decovf_s SS$_DECOVF # define __pthread_subrng_s SS$_SUBRNG # define __pthread_stackovf_s SS$_STKOVF # pragma standard /* * Synonyms for signal-based exception statuses. */ # define __pthread_SIGIOT_s __pthread_SIGABRT_s # define __pthread_SIGSEGV_s __pthread_illaddr_s # define __pthread_SIGBUS_s __pthread_resaddr_s # define __pthread_SIGFPE_s __pthread_aritherr_s /* * Internal DECthreads exception statuses. */ # define __pthread_cancel_s _PTHREAD_STATUS_ (48, 4) # define __pthread_exit_s _PTHREAD_STATUS_ (52, 4) /* * The DECthreads "uniplemented" status. */ # define _PTHREAD_UNIMP_S _PTHREAD_STATUS_ (61, 4) /* * TYPEDEFS */ # ifdef __INITIAL_POINTER_SIZE # pragma __required_pointer_size __save # pragma __required_pointer_size __short # endif typedef void *__pthreadExcAddr_t, **__pthreadExcAddr_p; typedef long __pthreadExcLong_t, *__pthreadExcLong_p; typedef short __pthreadExcShort_t, *__pthreadExcShort_p; typedef unsigned long __pthreadExcUns_t, *__pthreadExcUns_p; typedef unsigned long __pthreadStatus_t; /* * Constants for the kind of an exception object. * * There are *currently* only two kinds. In the address-kind, the identity * of an exception object is its address; in the value-kind, the * identity of an exception object is an integer, typically, * a system-defined-status-value. These coded kinds also * serve as sentinels to help detect uninitialized exceptions. */ typedef enum __pthreadExcKind_t { _PTHREAD_EXC_KIND_NONE = 0, _PTHREAD_EXC_KIND_ADDR = 0x02130455, _PTHREAD_EXC_KIND_STATUS = 0x02130456 } __pthreadExcKind_t; typedef unsigned __int64 __pthreadExcJumpBuf_t[(14+8+3)]; # if defined (_PTHREAD_EXC_IA64) /* Verified for x86 port - Camiel Vanderhoeven */ typedef long double __pthreadExcJumpBufExt_t[(20)]; # endif typedef __int64 __pthreadExcArg_t, *__pthreadExcArg_p; /* * Flags which are stored in the __flags field below. */ # define _PTHREAD_EXC_FLG_NATEXC 0x1 /* __args pts to native exc */ # define _PTHREAD_EXC_FLG_HEAPARG 0x2 /* __args points to heap mem */ typedef struct __pthreadExcExt { __pthreadExcLong_t __sentinel; __pthreadExcShort_t __version; __pthreadExcShort_t __flags; __pthreadExcAddr_t __extend; __pthreadExcArg_p __args; } __pthreadExcExt_t; typedef struct __pthreadExcKindV1Addr { __pthreadExcKind_t __kind; __pthreadExcAddr_t __address; __pthreadExcUns_t __filler[6]; } __pthreadExcKindV1Addr_t; typedef struct __pthreadExcKindV1Status { __pthreadExcKind_t __kind; __pthreadExcUns_t __status; __pthreadExcUns_t __filler[6]; } __pthreadExcKindV1Status_t; typedef struct __pthreadExcKindAddr { __pthreadExcKind_t __kind; __pthreadExcAddr_t __address; __pthreadExcExt_t __ext; } __pthreadExcKindAddr_t; typedef struct __pthreadExcKindStatus { __pthreadExcKind_t __kind; __pthreadStatus_t __status; __pthreadExcExt_t __ext; } __pthreadExcKindStatus_t; typedef union __pthreadExceptionObj { __pthreadExcKind_t __kind; __pthreadExcKindV1Status_t __v1status; __pthreadExcKindV1Addr_t __v1address; __pthreadExcKindStatus_t __status; __pthreadExcKindAddr_t __address; } __pthreadExceptionObj_t, *__pthreadExceptionObj_p; /* * Constants for the state of handling in the current TRY clause. * * The implementations of TRY/ENDTRY use the "NONE", "ACTIVE" and "HANDLED" * states. The state variable defined by the TRY macro is set to "NONE" when * no exception has been raised, "ACTIVE" when one has been raised but has not * been caught by a CATCH clause, and "HANDLED" after the exception has been * caught and handled by some CATCH clause. */ typedef enum __pthreadExcState_t { _PTHREAD_EXC_STATE_ACTIVE = 0, /* This must be the 0 state, see pop_ctx */ _PTHREAD_EXC_STATE_NONE = 1, _PTHREAD_EXC_STATE_HANDLED = 2, _PTHREAD_EXC_STATE_POPPED = 3 } __pthreadExcState_t; /* * Structure of a context block. * * A context block is allocated in the current stack frame for each * TRY clause. These context blocks are linked to form a stack of * all current TRY blocks in the current thread. Each context block * contains a jump buffer for use by setjmp and longjmp. Note that * for binary compatibility reasonse the jump buffer must be at the * beginning. */ # define _PTHREAD_EXC_ARGS 160 / sizeof (__pthreadExcArg_t) typedef struct __pthreadExcCtx { __pthreadExcJumpBuf_t __jmp; /* Jump buffer */ volatile struct __pthreadExcCtx *__link; /* Link to ctx block stack */ volatile __pthreadExceptionObj_t __cur_exception; /* Copy of exception */ volatile __pthreadExcState_t __exc_state; /* State of handling for TRY */ __pthreadExcAddr_t __current_frame; /* Addr of curr stack frame */ __pthreadExcLong_t __sentinel; /* Identify ctx block */ __pthreadExcLong_t __version; /* Client context version */ unsigned int __reserved1; /* Alignment padding */ __pthreadExcArg_t __exc_args[_PTHREAD_EXC_ARGS]; # if defined(_PTHREAD_EXC_IA64) /* Verified for x86 port - Camiel Vanderhoeven */ __pthreadExcJumpBufExt_t __jmpExt; /* IA-64 overflow jump buffer */ # endif # if !defined (_PTHREAD_EXC_ALPHA) /* Verified for x86 port - Clair Grant */ unsigned __int64 __current_invo; /* Estab's invo ctx handle */ unsigned __int64 __spare0; /* Spare */ unsigned __int64 __spare1; /* Spare */ unsigned __int64 __spare2; /* Spare */ unsigned __int64 __spare3; /* Spare */ # endif } __pthreadExcCtx_t, *__pthreadExcCtx_p; /* * On VMS IA-64, the exception context object allocated within a TRY block * must be octaword (16 byte) aligned. This ensures that the extended jump * buffer within the context object is octaword aligned (so that the floating * point register spill locations are octaword aligned). */ # if !defined (_PTHREAD_EXC_ALPHA) && defined (_PTHREAD_EXC_DECC) /* Verified for x86 port - Clair Grant */ # define __pthreadExcCtxAlign __align (octaword) # else # define __pthreadExcCtxAlign # endif # ifdef __INITIAL_POINTER_SIZE # pragma __required_pointer_size __restore # endif /* * EXTERNAL ROUTINES */ # if defined (_PTHREAD_CORE_BUILD_) /* Verified for x86 port - Clair Grant */ # define __pthread_exc_handler_np excCoreHandler # else # define __pthread_exc_handler_np pthread_exc_handler_np # endif # if !defined (_PTHREAD_EXC_ALPHA) && defined (_PTHREAD_EXC_DECC) /* Verified for x86 port - Clair Grant */ # define pthread_exc_savecontext_np __pthread_exc_savecontext_np # endif extern int pthread_exc_savecontext_np (volatile unsigned __int64 *); /* * Use an extern function to get the FP */ # if defined (_PTHREAD_EXC_IA64) /* Verified for x86 port - Clair Grant */ extern unsigned __int64 pthread_exc_fetch_fp_np (void); # else extern __pthreadExcAddr_t pthread_exc_fetch_fp_np (void); # endif extern void pthread_exc_get_message_np (__pthreadExceptionObj_p, int, char *); extern int pthread_exc_matches_np ( __pthreadExceptionObj_p, __pthreadExceptionObj_p); extern void pthread_exc_pop_ctx_np (__pthreadExcCtx_p); extern void pthread_exc_push_ctx_np (__pthreadExcCtx_p); extern void pthread_exc_raise_np (__pthreadExceptionObj_p); extern void pthread_exc_raise_status_np (__pthreadStatus_t); extern void pthread_exc_report_np (__pthreadExceptionObj_p); # if !defined (_PTHREAD_SUPPRESS_EXTERNALS_) /* Verified for x86 port - Clair Grant */ /* * System condition handler * * The declaration below is conditionalized to allow for compilation on * V7.1 systems. On OpenVMS V7.1, for the __NEW_STARLET case only, * chf$mech_array equates to a type (CHFDEF2), whereas for the default * (__OLD_STARLET) case, it equates to a structure tag. As of V7.2, * chfdef.h was modified to equate chf$mech_array to the structure tag * regardless of the __NEW_STARLET value. */ # pragma nostandard extern int # if (__VMS_VER < 70200000) && defined (__NEW_STARLET) __pthread_exc_handler_np (unsigned int[], chf$mech_array*); # else __pthread_exc_handler_np (unsigned int[], struct chf$mech_array*); # endif # pragma standard # endif /* * CONSTANTS AND MACROS */ /* * Define exception initializer macro. All exceptions *must* be initialized * using this macro. */ # define PTHREAD_EXCEPTION_INIT_NP(_e_) ( \ (_e_).__address.__address = (__pthreadExcAddr_t)&(_e_), \ (_e_).__address.__kind = _PTHREAD_EXC_KIND_ADDR, \ (_e_).__address.__ext.__sentinel = _PTHREAD_EXC_NEWMAGIC, \ (_e_).__address.__ext.__version = _PTHREAD_EXC_VER_CUR, \ (_e_).__address.__ext.__flags = 0, \ (_e_).__address.__ext.__extend = (__pthreadExcAddr_t)0L, \ (_e_).__address.__ext.__args = (__pthreadExcArg_p)0L) /* * Define a function to convert a portable address exception to a platform * specific status exception. */ # define pthread_exc_set_status_np(_e_,_s_) ( \ (_e_)->__status.__kind = _PTHREAD_EXC_KIND_STATUS, \ (_e_)->__status.__status = ((_s_) & ~7) | 4) /* * Define "routine" to return the status of an exception. Returns 0 if status * kind (and value of status in *s), or EINVAL if not status kind. */ # define pthread_exc_get_status_np(_e_,_s_) ( \ (_e_)->__status.__kind == _PTHREAD_EXC_KIND_STATUS ? \ (*(_s_) = (_e_)->__status.__status, 0) : \ EINVAL) /* * Define "statement" for clients to use to raise an exception. */ # define PTHREAD_RAISE_NP(_e_) pthread_exc_raise_np (&(_e_)) # pragma nostandard # if defined (_PTHREAD_EXC_IA64) /* Verified for x86 port - Clair Grant */ # define pthread_exc_estab_field __current_invo # else # define pthread_exc_estab_field __current_frame # endif # define pthread_exc_establish_np(_exc_ctx_) \ (_exc_ctx_)->pthread_exc_estab_field = pthread_exc_fetch_fp_np (); \ lib$establish (__pthread_exc_handler_np); # pragma standard # define pthread_exc_unestablish_np(_exc_ctx_) /* * Define version constants to be put into exception context structures. * * o V2 is for OpenVMS Alpha and non-native Tru64 UNIX exception handling. * o V3 is for native Tru64 UNIX exception handling. * o V4 was added in Tru64 UNIX V4.0D (with the __reserved0 field). * o V5 is for support of UNIX foreign exceptions (space added to hold a copy * of a small native exception with arguments). * o V6 is for support of IA-64 under OpenVMS V8.0 and V8.1, which requires a * larger jump buffer. * o V7 is for support of IA-64 under OpenVMS V8.2, which adds the current * invo field. * * This code checks the version to see how it should behave. */ # define _PTHREAD_EXC_CTX_V2 2 # define _PTHREAD_EXC_CTX_V3 3 # define _PTHREAD_EXC_CTX_V4 4 # define _PTHREAD_EXC_CTX_V5 5 # define _PTHREAD_EXC_CTX_V6 6 # define _PTHREAD_EXC_CTX_V7 7 # if !defined (_PTHREAD_EXC_ALPHA) /* Verified for x86 port - Clair Grant */ # define _PTHREAD_EXC_CTX_CUR _PTHREAD_EXC_CTX_V7 # else # define _PTHREAD_EXC_CTX_CUR _PTHREAD_EXC_CTX_V2 # endif /* * Start a new TRY block, which may contain exception handlers. * * Allocate a context block on the stack to remember the current exception. * Push it on the context block stack. Initialize this context block to * indicate that no exception is active. Do a SETJMP to snapshot this * environment (or return to it). Then, start a block of statements to be * guarded by the TRY clause. This block will be ended by one of the * following macros: CATCH, CATCH_ALL, FINALLY or ENDTRY. */ # define _PTHREAD_INIT_CTX(_ctx_) \ PTHREAD_EXCEPTION_INIT_NP (_ctx_.__cur_exception); \ _ctx_.__cur_exception.__kind = _PTHREAD_EXC_KIND_STATUS; \ _ctx_.__exc_state = _PTHREAD_EXC_STATE_NONE; \ _ctx_.__sentinel = _PTHREAD_EXC_NEWMAGIC; \ _ctx_.__version = _PTHREAD_EXC_CTX_CUR; \ _ctx_.__exc_args[0] = (__pthreadExcArg_t)0 # define PTHREAD_TRY_NP \ { \ __pthreadExcCtx_t __pthreadExcCtxAlign __exc_ctx__; \ _PTHREAD_INIT_CTX (__exc_ctx__); \ pthread_exc_push_ctx_np (&__exc_ctx__); \ pthread_exc_establish_np (&__exc_ctx__); \ if (!pthread_exc_savecontext_np (__exc_ctx__.__jmp)) { \ /* user's block of code goes here */ /* * Define an PTHREAD_CATCH_NP(_e_) clause (or exception handler). * * First, end the prior block. Then, check if the current exception matches * what the user is trying to catch with the CATCH clause. If there is a * match, a variable is declared to support lexical nesting of * PTHREAD_RERAISE_NP statements, and the state of the current exception is * changed to "handled". */ # define PTHREAD_CATCH_NP(_e_) \ } \ else if (pthread_exc_matches_np ( \ (__pthreadExceptionObj_p)&__exc_ctx__.__cur_exception, &(_e_))) { \ __pthreadExceptionObj_p PTHREAD_THIS_CATCH_NP = \ (__pthreadExceptionObj_p)&__exc_ctx__.__cur_exception; \ __exc_ctx__.__exc_state = _PTHREAD_EXC_STATE_HANDLED; /* user's block of code goes here */ /* * Define an PTHREAD_CATCH_ALL_NP clause (or "catchall" handler). * * First, end the prior block. Then, unconditionally, let execution enter * into the catchall code. As with a normal catch, a variable is declared * to support lexical nesting of PTHREAD_RERAISE_NP statements, and the * state of the current exception is changed to "handled". */ # define PTHREAD_CATCH_ALL_NP \ } \ else { \ __pthreadExceptionObj_p PTHREAD_THIS_CATCH_NP = \ (__pthreadExceptionObj_p)&__exc_ctx__.__cur_exception; \ __exc_ctx__.__exc_state = _PTHREAD_EXC_STATE_HANDLED; /* user's block of code goes here */ /* * Define a PTHREAD_RERAISE_NP statement. * * This "statement" is valid only if lexically nested in a CATCH or * CATCH_ALL clause. Reraise the current lexically visible exception. */ # define PTHREAD_RERAISE_NP pthread_exc_raise_np (PTHREAD_THIS_CATCH_NP) /* * Define a PTHREAD_FINALLY_NP clause * * This "keyword" starts a PTHREAD_FINALLY_NP clause. It must appear before * an ENDTRY. A PTHREAD_FINALLY_NP clause will be entered after normal exit * of the TRY block, or if an unhandled exception tries to propagate * out of the TRY block. * * Unlike Modula 3's TRY clause, we do not expend overhead trying to * enforce that FINALLY be mutually exclusive with CATCH clauses. Currently, * if they are used together, then control will drop into a FINALLY clause * under the following conditions: * o normal exit from TRY, * o an exception is raised and no CATCH is present (recommended usage) * o CATCH's are present but none matches the exception. * o CATCH's are present and one matches the exception, but it * does not raise or reraise any exceptions. * That is, FINALLY is always entered after TRY unless a CATCH clause raises * (or re-raises) an exception. * * ** WARNING ** * You should *avoid* using FINALLY with CATCH clauses, that is, use it * only as TRY {} FINALLY {} ENDTRY. Source code that combines CATCHes * with FINALLY in the same TRY clause is considered "unsupported" * -- that is, such code may be broken by a future version of this * package. * * There are several reasons this restriction is necessary: * o FINALLY may be added to C++ and its combination with CATCH * clauses may have different semantics than implemented by these macros. * o The restriction is consistant with the same restriction in Modula 3 * o It allows the use of the 2-phase or "debugging" implementation * technique of the SRC exception package for these same macros. */ # define PTHREAD_FINALLY_NP \ } \ if (__exc_ctx__.__exc_state == _PTHREAD_EXC_STATE_NONE) \ pthread_exc_pop_ctx_np (&__exc_ctx__); \ { \ __pthreadExceptionObj_p PTHREAD_THIS_CATCH_NP = \ (__pthreadExceptionObj_p)&__exc_ctx__.__cur_exception; /* user's block of code goes here */ /* * End the whole TRY clause * * We close off the block for the previous block and then tear down the * context we established in the opening TRY. If an exception never * occurred or we did not handle the exception, we pop the context block * off the context stack. Note that popping the context block off the stack * will cause an exception to be raised if the context block describes an * unhandled exception. */ # define PTHREAD_ENDTRY_NP \ } \ pthread_exc_unestablish_np (&__exc_ctx__); \ if ((__exc_ctx__.__exc_state == _PTHREAD_EXC_STATE_NONE) \ || (__exc_ctx__.__exc_state == _PTHREAD_EXC_STATE_ACTIVE)) \ pthread_exc_pop_ctx_np (&__exc_ctx__); \ } /* * Define the exception variables */ # if defined (__STDC__) || defined (_PTHREAD_EXC_DECC) || defined (_PTHREAD_EXC_CXX) # define _PTHREAD_EXCNAME(name) pthread_exc_##name##_e # define _PTHREAD_PTDNAME(name) pthread_##name##_e # else # define _PTHREAD_EXCNAME(name) pthread_exc_/**/name/**/_e # define _PTHREAD_PTDNAME(name) pthread_/**/name/**/_e # endif # if !defined (_EXC_NO_EXCEPTIONS_) && !defined (_PTHREAD_CORE_BUILD_) _PTHREAD_EXC_IMPORT_ __pthreadExceptionObj_t _PTHREAD_EXCNAME (uninitexc), _PTHREAD_EXCNAME (illaddr), _PTHREAD_EXCNAME (exquota), _PTHREAD_EXCNAME (insfmem), _PTHREAD_EXCNAME (nopriv), _PTHREAD_EXCNAME (illinstr), _PTHREAD_EXCNAME (resaddr), _PTHREAD_EXCNAME (privinst), _PTHREAD_EXCNAME (resoper), _PTHREAD_EXCNAME (SIGTRAP), _PTHREAD_EXCNAME (SIGABRT), _PTHREAD_EXCNAME (SIGEMT), _PTHREAD_EXCNAME (aritherr), _PTHREAD_EXCNAME (SIGSYS), _PTHREAD_EXCNAME (SIGPIPE), _PTHREAD_EXCNAME (excpu), _PTHREAD_EXCNAME (exfilsiz), _PTHREAD_EXCNAME (intovf), _PTHREAD_EXCNAME (intdiv), _PTHREAD_EXCNAME (fltovf), _PTHREAD_EXCNAME (fltdiv), _PTHREAD_EXCNAME (fltund), _PTHREAD_EXCNAME (decovf), _PTHREAD_EXCNAME (subrng), _PTHREAD_PTDNAME (cancel), _PTHREAD_PTDNAME (exit), _PTHREAD_PTDNAME (stackovf), _PTHREAD_EXCNAME (noexcmem); # define pthread_exc_SIGIOT_e pthread_exc_SIGABRT_e # define pthread_exc_SIGSEGV_e pthread_exc_illaddr_e # define pthread_exc_SIGBUS_e pthread_exc_resaddr_e # define pthread_exc_SIGFPE_e pthread_exc_aritherr_e # define pthread_exc_SIGILL_e pthread_exc_illinstr_e # endif # pragma __extern_model __restore # ifdef __cplusplus } # endif #endif /* _PTHREAD_EXCEPTION_CLEAN */ /* * The following section of this file contains definitions which are not in * the protected part of the namespace. */ #if !defined (_PTHREAD_EXCEPTION_POLLUTING) && !defined (_PTHREAD_EXC_INCL_CLEAN) # define _PTHREAD_EXCEPTION_POLLUTING # ifdef __cplusplus extern "C" { # endif /* * Define external version of status codes */ # define pthread_exception_s __pthread_exception_s # define pthread_exccop_s __pthread_exccop_s # define pthread_uninitexc_s __pthread_uninitexc_s # define pthread_unkstatus_s __pthread_unkstatus_s # define pthread_exccoplos_s __pthread_exccoplos_s # define pthread_noexcmem_s __pthread_noexcmem_s # define pthread_illaddr_s __pthread_illaddr_s # define pthread_exquota_s __pthread_exquota_s # define pthread_nopriv_s __pthread_nopriv_s # define pthread_insfmem_s __pthread_insfmem_s # define pthread_normal_s __pthread_normal_s # define pthread_illinstr_s __pthread_illinstr_s # define pthread_resaddr_s __pthread_resaddr_s # define pthread_privinst_s __pthread_privinst_s # define pthread_resoper_s __pthread_resoper_s # define pthread_SIGTRAP_s __pthread_SIGTRAP_s # define pthread_SIGABRT_s __pthread_SIGABRT_s # define pthread_SIGEMT_s __pthread_SIGEMT_s # define pthread_aritherr_s __pthread_aritherr_s # define pthread_SIGSYS_s __pthread_SIGSYS_s # define pthread_SIGPIPE_s __pthread_SIGPIPE_s # define pthread_excpu_s __pthread_excpu_s # define pthread_exfilsiz_s __pthread_exfilsiz_s # define pthread_intovf_s __pthread_intovf_s # define pthread_intdiv_s __pthread_intdiv_s # define pthread_fltovf_s __pthread_fltovf_s # define pthread_fltdiv_s __pthread_fltdiv_s # define pthread_fltund_s __pthread_fltund_s # define pthread_decovf_s __pthread_decovf_s # define pthread_subrng_s __pthread_subrng_s # define pthread_stackovf_s __pthread_stackovf_s # define pthread_SIGIOT_s __pthread_SIGABRT_s # define pthread_SIGSEGV_s __pthread_illaddr_s # define pthread_SIGBUS_s __pthread_resaddr_s # define pthread_SIGFPE_s __pthread_aritherr_s # define pthread_cancel_s __pthread_cancel_s # define pthread_exit_s __pthread_exit_s typedef __pthreadExceptionObj_t EXCEPTION; /* * Define the documented ("polluted") external names for the exception * macros. */ # define EXCEPTION_INIT(__e) PTHREAD_EXCEPTION_INIT_NP (__e) # define RAISE(__e) PTHREAD_RAISE_NP (__e) # define TRY PTHREAD_TRY_NP # define ENDTRY PTHREAD_ENDTRY_NP # define FINALLY PTHREAD_FINALLY_NP # define CATCH_ALL PTHREAD_CATCH_ALL_NP # define RERAISE PTHREAD_RERAISE_NP # define THIS_CATCH PTHREAD_THIS_CATCH_NP # define CATCH(__e) PTHREAD_CATCH_NP (__e) # ifdef __cplusplus } # endif #endif