mirror of
https://codeberg.org/1414codeforge/ubgpsuite.git
synced 2025-06-05 21:29:11 +02:00
[*] Initial commit
This commit is contained in:
154
lonetix/include/df/sys/sys.h
Executable file
154
lonetix/include/df/sys/sys.h
Executable file
@ -0,0 +1,154 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
/**
|
||||
* \file sys/sys.h
|
||||
*
|
||||
* Miscellaneous system functionality.
|
||||
*
|
||||
* \copyright The DoubleFourteen Code Forge (C) All Rights Reserved
|
||||
* \author Lorenzo Cogotti
|
||||
*/
|
||||
|
||||
#ifndef DF_SYS_ERR_H_
|
||||
#define DF_SYS_ERR_H_
|
||||
|
||||
#include "srcloc.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// for Sys_WipeMemory()
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \typedef SysRet
|
||||
* \brief Platform-specific error code for system operations.
|
||||
*/
|
||||
typedef int SysRet; // errno type
|
||||
|
||||
/**
|
||||
* \brief Error status structure.
|
||||
*
|
||||
* Stores latest operation result and current error handling callback.
|
||||
*/
|
||||
typedef struct {
|
||||
/// Latest operation result status.
|
||||
SysRet code;
|
||||
/**
|
||||
* \brief Error handler callback.
|
||||
*
|
||||
* \param [in] code System error code
|
||||
* \param [in] reason Human readable concise message providing context to error, never `NULL`
|
||||
* \param [in] loc Source location where error occurred, `NULL` if unavailable
|
||||
* \param [in] obj User defined additional data forwarded to callback unaltered
|
||||
*/
|
||||
void (*func)(SysRet code, const char *reason, Srcloc *loc, void *obj);
|
||||
/// Additional user data to be forwarded to `func`.
|
||||
void *obj;
|
||||
} SysErrStat;
|
||||
|
||||
/**
|
||||
* \brief Abort error handler callback.
|
||||
*
|
||||
* This error handler terminates execution abnormally,
|
||||
* attempting to log an error message as accurate as possible using system
|
||||
* specific facilities.
|
||||
*
|
||||
* If this handler is registered, execution shall terminate as soon as an
|
||||
* exceptional error condition is encountered in the system layer.
|
||||
*/
|
||||
#define SYS_ERR_ABORT ((void (*)(SysRet, const char *, Srcloc *, void *)) -1)
|
||||
/**
|
||||
* \brief Ignoring error handler callback.
|
||||
*
|
||||
* If this handler is registered any system error is ignored.
|
||||
*/
|
||||
#define SYS_ERR_IGN ((void (*)(SysRet, const char *, Srcloc *, void *)) 0)
|
||||
/**
|
||||
* \brief Terminating error handler callback.
|
||||
*
|
||||
* Terminates execution providing sensible error message, it differs
|
||||
* from `SYS_ERR_ABORT` in that no exceptional termination semantics is
|
||||
* implied, but rather an unsuccessful event that caused immediate exit
|
||||
* (no core dump or stack traces are left behind).
|
||||
*/
|
||||
#define SYS_ERR_QUIT ((void (*)(SysRet, const char *, Srcloc *, void *)) 1)
|
||||
|
||||
/**
|
||||
* \brief Install a system error handler callback.
|
||||
*
|
||||
* Initially installed handler is `SYS_ERR_IGN`,
|
||||
* thus any error is effectively ignored unless a new handler is installed.
|
||||
*
|
||||
* Once installed, the error callback is called immediately for every
|
||||
* exceptional error condition encountered inside system layer.
|
||||
*
|
||||
* Error handlers are thread-local, thus different threads may implement
|
||||
* appropriate error handling policy without interfering with each other.
|
||||
*
|
||||
* \param [in] func Error handler function
|
||||
* \param [in] obj Custom user-provided object passed unaltered upon callback
|
||||
*
|
||||
* \see `SysErrStat` for callback documentation
|
||||
*/
|
||||
void Sys_SetErrFunc(void (*func)(SysRet, const char *, Srcloc *, void *), void *obj);
|
||||
|
||||
/**
|
||||
* Retrieve the system error status.
|
||||
*
|
||||
* \param [out] stat Storage for returned error status, may be `NULL`
|
||||
*
|
||||
* \return Last operation result status.
|
||||
*/
|
||||
SysRet Sys_GetErrStat(SysErrStat *stat);
|
||||
|
||||
/**
|
||||
* Trigger an out of memory error.
|
||||
*
|
||||
* @note Depending on the current error policy, execution may
|
||||
* very well continue after call returns.
|
||||
*/
|
||||
#define Sys_OutOfMemory() _Sys_OutOfMemory(__FILE__, __func__, __LINE__, 0)
|
||||
|
||||
// NOTE: implementation detail, should always be called through `Sys_OutOfMemory()`.
|
||||
NOINLINE void _Sys_OutOfMemory(const char *,
|
||||
const char *,
|
||||
unsigned long long,
|
||||
unsigned);
|
||||
|
||||
/**
|
||||
* \brief Zero-out `nbytes` bytes inside `data`, preventing compiler optimization.
|
||||
*
|
||||
* A compiler might optimize-out `memset()` or similar operations if `data`
|
||||
* is never read again.
|
||||
* This function ensures such operation is never optimized away, which
|
||||
* may be useful to zero-out sensitive data.
|
||||
*/
|
||||
FORCE_INLINE void Sys_WipeMemory(volatile void *data, size_t nbytes)
|
||||
{
|
||||
#if defined(_MSC_VER) || defined(__GNUC__)
|
||||
EXTERNC void *memset(void *, int, size_t);
|
||||
|
||||
memset((void *) data, 0, nbytes);
|
||||
|
||||
// Compiler fence
|
||||
#ifdef _MSC_VER
|
||||
_ReadWriteBarrier();
|
||||
#else
|
||||
__asm__ __volatile__ ("" : : : "memory");
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Slow but portable
|
||||
volatile Uint8 *p = (volatile Uint8 *) data;
|
||||
while (nbytes--)
|
||||
*p++ = 0x00;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Sleep *at least* for the specified amount of **milliseconds**.
|
||||
void Sys_SleepMillis(Uint32 millis);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user