/* $Source: bitbucket.org:berkeleylab/gasnet.git/other/amx/amx_internal.c $ * Description: AMX internal support code * Copyright 2002, Dan Bonachea * Copyright 2018, The Regents of the University of California * Terms of use are as specified in license.txt */ #ifndef _AMX_INTERNAL_H #error header inclusion error #endif /* definitions for internal declarations */ int amx_Initialized = 0; #if AMX_DEBUG_VERBOSE int AMX_VerboseErrors = 1; #else int AMX_VerboseErrors = 0; #endif int AMX_SilentMode = 0; const char *AMX_ProcessLabel = NULL; volatile int amx_frozen = 1; /* non-static to prevent a SunC problem (bug1626) */ /* all this to make sure we get a full stack frame for debugger */ AMX_NEVER_INLINE(_freezeForDebugger, static void _freezeForDebugger(int depth)) { if (!depth) _freezeForDebugger(1); else { volatile int i = 0; while (amx_frozen) { i++; AMX_sched_yield(); } } } extern void AMX_freezeForDebugger(void) { char name[255]; gethostname(name, sizeof(name)); AMX_Info("worker frozen for debugger: host=%s pid=%i : Attach and set amx_frozen=0", name, (int)getpid()); _freezeForDebugger(0); } /* ------------------------------------------------------------------------------------ */ /* error handling */ AMX_FORMAT_PRINTF(AMX_Msg,2,0, static int AMX_Msg(const char *prefix, const char *msg, va_list argptr)) { static char _expandedmsg[255]; // use static storage when possible for robustness in panic-mode static char plabel[80]; char *expandedmsg; size_t sz; int chk,retval; if (AMX_ProcessLabel && !*plabel) snprintf(plabel, sizeof(plabel), "(%s)", AMX_ProcessLabel); expandedmsg = _expandedmsg; sz = strlen(prefix) + strlen(plabel) + strlen(msg) + 8; if (sz > sizeof(_expandedmsg)) expandedmsg = (char *)AMX_malloc(sz); chk = snprintf(expandedmsg, sz, "%s%s: %s\n", prefix, plabel, msg); AMX_assert(chk < (int)sz); // truncation should not occur retval = vfprintf(stderr, expandedmsg, argptr); fflush(stderr); if (expandedmsg != _expandedmsg) AMX_free(expandedmsg); return retval; } extern int AMX_Info(const char *msg, ...) { va_list argptr; int retval; va_start(argptr, msg); // pass in last argument retval = AMX_Msg(AMX_ENV_PREFIX_STR, msg, argptr); va_end(argptr); return retval; } extern int AMX_Warn(const char *msg, ...) { va_list argptr; int retval; va_start(argptr, msg); // pass in last argument retval = AMX_Msg("*** " AMX_ENV_PREFIX_STR " WARNING", msg, argptr); va_end(argptr); return retval; } extern int AMX_Err(const char *msg, ...) { va_list argptr; int retval; va_start(argptr, msg); // pass in last argument retval = AMX_Msg("*** " AMX_ENV_PREFIX_STR " ERROR", msg, argptr); va_end(argptr); return retval; } extern void AMX_FatalErr(const char *msg, ...) { va_list argptr; va_start(argptr, msg); // pass in last argument AMX_Msg("*** FATAL ERROR", msg, argptr); va_end(argptr); abort(); } /* ------------------------------------------------------------------------------------ */ static void AMX_defaultAMHandler(void *token) { int srcnode = -1; handler_t hidx; amx_category_t category; int is_req; AMX_GetSourceId(token, &srcnode); AMX_GetTokenInfo(token,&hidx,&category,&is_req); AMX_FatalErr(AMX_LIB_STR" received an AM %s from node %i for a handler index %i " "with no associated AM handler function registered", (is_req?"Request":"Reply"), srcnode, (int)hidx); } amx_handler_fn_t amx_unused_handler = (amx_handler_fn_t)&AMX_defaultAMHandler; /*------------------------------------------------------------------------------------ * System initialization/termination *------------------------------------------------------------------------------------ */ extern int AMX_Init(void) { int firstcall = (amx_Initialized == 0); if (firstcall) { /* check system attributes */ AMX_assert(sizeof(int8_t) == 1); AMX_assert(sizeof(uint8_t) == 1); #ifndef INTTYPES_16BIT_MISSING AMX_assert(sizeof(int16_t) == 2); AMX_assert(sizeof(uint16_t) == 2); #endif AMX_assert(sizeof(int32_t) == 4); AMX_assert(sizeof(uint32_t) == 4); AMX_assert(sizeof(int64_t) == 8); AMX_assert(sizeof(uint64_t) == 8); AMX_assert(sizeof(uintptr_t) >= sizeof(void *)); } amx_Initialized++; return firstcall; } /* ------------------------------------------------------------------------------------ */ extern int AMX_Terminate(void) { int lastcall; AMX_CHECKINIT(); lastcall = (amx_Initialized == 1); amx_Initialized--; return lastcall; } /* ------------------------------------------------------------------------------------ */