From 2ffe227d82916ae37b4916cbd8a714f4ef627f78 Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Sat, 15 Jul 2023 23:18:21 -0700 Subject: [PATCH] Add SmartHeap (#83) * add smartheap * cmake: bump even further * this seemed to be necessary but now it isn't? ok * cmake: force include smrtheap.hpp Co-authored-by: Anonymous Maarten * cmake: force include smrtheap.hpp 2 Co-authored-by: Anonymous Maarten * remove compiler defs - unnecessary if force-including anyway * cmake: use interface for cleaner code --------- Co-authored-by: Anonymous Maarten --- .github/workflows/build.yml | 2 +- 3rdparty/smartheap/SHLW32MT.LIB | Bin 0 -> 106886 bytes 3rdparty/smartheap/SHMALLOC.H | 63 +++ 3rdparty/smartheap/SHMFC4M.LIB | Bin 0 -> 3206 bytes 3rdparty/smartheap/SMRTHEAP.H | 656 ++++++++++++++++++++++++++++++++ 3rdparty/smartheap/SMRTHEAP.HPP | 159 ++++++++ CMakeLists.txt | 17 +- 7 files changed, 895 insertions(+), 2 deletions(-) create mode 100644 3rdparty/smartheap/SHLW32MT.LIB create mode 100644 3rdparty/smartheap/SHMALLOC.H create mode 100644 3rdparty/smartheap/SHMFC4M.LIB create mode 100644 3rdparty/smartheap/SMRTHEAP.H create mode 100644 3rdparty/smartheap/SMRTHEAP.HPP diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af1dac3b..c846a9f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,7 +46,7 @@ jobs: uses: jwlawson/actions-setup-cmake@v1.13 with: # Use minimum supported version - cmake-version: '3.0.x' + cmake-version: '3.13.x' - name: Build shell: cmd diff --git a/3rdparty/smartheap/SHLW32MT.LIB b/3rdparty/smartheap/SHLW32MT.LIB new file mode 100644 index 0000000000000000000000000000000000000000..732aedf81e8fa402cb197f1a72a1966e3705d432 GIT binary patch literal 106886 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 aOWw*zl9QwVgJhh~`Y|eNCZ)L5W%4KBGcqOs literal 0 HcmV?d00001 diff --git a/3rdparty/smartheap/SMRTHEAP.H b/3rdparty/smartheap/SMRTHEAP.H new file mode 100644 index 00000000..aab58b84 --- /dev/null +++ b/3rdparty/smartheap/SMRTHEAP.H @@ -0,0 +1,656 @@ +/* smrtheap.h -- SmartHeap (tm) public C header file + * Professional Memory Management Library + * + * Copyright (C) 1991-1997 by Arthur D. Applegate. All Rights Reserved. + * All Rights Reserved. + * + * No part of this source code may be copied, modified or reproduced + * in any form without retaining the above copyright notice. + * This source code, or source code derived from it, may not be redistributed + * without express written permission of the author. + * + */ + +#if !defined(_SMARTHEAP_H) +#define _SMARTHEAP_H + +#include +#include + +#if !defined(macintosh) && !defined(THINK_C) && !defined(__MWERKS__) \ + && !defined(SHANSI) && UINT_MAX == 0xFFFFu \ + && (defined(_Windows) || defined(_WINDOWS) || defined(__WINDOWS__)) + #define MEM_WIN16 +#endif + +#if (UINT_MAX == 0xFFFFu) && (defined(MEM_WIN16) \ + || defined(MSDOS) || defined(__MSDOS__) || defined(__DOS__)) + /* 16-bit X86 */ + #if defined(SYS_DLL) + #if defined(_MSC_VER) && _MSC_VER <= 600 + #define MEM_ENTRY _export _loadds far pascal + #else + #define MEM_ENTRY _export far pascal + #endif + #else + #define MEM_ENTRY far pascal + #endif + #ifdef __WATCOMC__ + #define MEM_ENTRY_ANSI __far + #else + #define MEM_ENTRY_ANSI far cdecl + #endif + #define MEM_FAR far + #if defined(MEM_WIN16) + #define MEM_ENTRY2 _export far pascal + #elif defined(DOS16M) || defined(DOSX286) + #define MEM_ENTRY2 _export _loadds far pascal + #endif + +#else /* not 16-bit X86 */ + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) \ + || defined(__WIN32__) || defined(__NT__) + #define MEM_WIN32 + #if defined(_MSC_VER) + #if defined(_SHI_Pool) && defined(SYS_DLL) + #define MEM_ENTRY1 __declspec(dllexport) + #define MEM_ENTRY4 __declspec(dllexport) extern + #elif !defined(_SHI_Pool) && (defined(MEM_DEBUG) || defined(MEM_DLL)) + #define MEM_ENTRY1 __declspec(dllimport) + #if defined(_M_IX86) || defined(_X86_) + #define MemDefaultPool shi_MemDefaultPool + #define MEM_ENTRY4 __declspec(dllimport) + #endif + #endif + #endif + #if !defined(_MSC_VER) || defined(_M_IX86) || defined(_X86_) + #define MEM_ENTRY __stdcall + #else + #define MEM_ENTRY __cdecl /* for NT/RISC */ + #endif + #ifndef __WATCOMC__ + #define MEM_ENTRY_ANSI __cdecl + #endif + +#elif defined(__OS2__) + #if defined(__BORLANDC__) || defined(__WATCOMC__) + #if defined(SYS_DLL) + #define MEM_ENTRY __export __syscall + #else + #define MEM_ENTRY __syscall + #endif /* SYS_DLL */ + #ifdef __BORLANDC__ + #define MEM_ENTRY_ANSI __stdcall + #endif + #elif defined(__IBMC__) || defined(__IBMCPP__) + #if defined(SYS_DLL) && 0 + #define MEM_ENTRY _Export _System + #else + #define MEM_ENTRY _System + #endif + #define MEM_ENTRY_ANSI _Optlink + #define MEM_ENTRY3 MEM_ENTRY + #define MEM_CALLBACK MEM_ENTRY3 + #define MEM_ENTRY2 + #endif +#endif /* __OS2__ */ + +#if defined(__WATCOMC__) && defined(__SW_3S) + /* Watcom stack calling convention */ +#ifndef __OS2__ +#ifdef __WINDOWS_386__ + #pragma aux syscall "*_" parm routine [eax ebx ecx edx fs gs] modify [eax]; +#else + #pragma aux syscall "*_" parm routine [eax ebx ecx edx] modify [eax]; +#endif +#ifndef MEM_ENTRY + #define MEM_ENTRY __syscall +#endif /* MEM_ENTRY */ +#endif +#endif /* Watcom stack calling convention */ + +#endif /* end of system-specific declarations */ + +#ifndef MEM_ENTRY + #define MEM_ENTRY +#endif +#ifndef MEM_ENTRY1 + #define MEM_ENTRY1 +#endif +#ifndef MEM_ENTRY2 + #define MEM_ENTRY2 MEM_ENTRY +#endif +#ifndef MEM_ENTRY3 + #define MEM_ENTRY3 +#endif +#ifndef MEM_ENTRY4 + #define MEM_ENTRY4 extern +#endif +#ifndef MEM_CALLBACK +#define MEM_CALLBACK MEM_ENTRY2 +#endif +#ifndef MEM_ENTRY_ANSI + #define MEM_ENTRY_ANSI +#endif +#ifndef MEM_FAR + #define MEM_FAR +#endif + +#ifdef applec +/* Macintosh: Apple MPW C/C++ passes char/short parms as longs (4 bytes), + * whereas Symantec C/C++ for MPW passes these as words (2 bytes); + * therefore, canonicalize all integer parms as 'int' for this platform. + */ + #define MEM_USHORT unsigned + #define MEM_UCHAR unsigned +#else + #define MEM_USHORT unsigned short + #define MEM_UCHAR unsigned char +#endif /* applec */ + +#ifdef MEM_DEBUG +#include "heapagnt.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*** Types ***/ + +#ifndef MEM_BOOL_DEFINED +#define MEM_BOOL_DEFINED +typedef int MEM_BOOL; +#endif + +/* Version Masks */ +typedef unsigned MEM_VERSION; +#define MEM_MAJOR_VERSION(v) (((v) & 0xF000u) >> 12) +#define MEM_MINOR_VERSION(v) (((v) & 0x0F00u) >> 8) +#define MEM_UPDATE_VERSION(v) ((v) & 0x00FFu) + +/* Note: these types are struct's rather than integral types to facilitate + * compile-time type-checking. MEM_POOL and MEM_HANDLE should be regarded + * as black boxes, and treated just like handles. + * You should not have any type casts to or from MEM_POOL or MEM_HANDLE; + * nor should you dereference variables of type MEM_POOL or MEM_HANDLE + * (unless you are using SmartHeap to replace NewHandle on the Mac, and + * you have existing code that dereferences handles). + */ +#ifndef MEM_POOL_DEFINED +#define MEM_POOL_DEFINED +#ifdef _SHI_Pool + typedef struct _SHI_Pool MEM_FAR *MEM_POOL; + typedef struct _SHI_MovHandle MEM_FAR *MEM_HANDLE; +#else + #ifdef THINK_C + typedef void *MEM_POOL; + typedef void **MEM_HANDLE; + #else + typedef struct _SHI_Pool { int reserved; } MEM_FAR *MEM_POOL; + typedef struct _SHI_MovHandle { int reserved; } MEM_FAR *MEM_HANDLE; + #endif +#endif +#endif /* MEM_POOL_DEFINED */ + + +#if !defined(MEM_DEBUG) || !(defined(MEM_WIN16) || defined(MEM_WIN32)) +#define SHI_MAJOR_VERSION 3 +#define SHI_MINOR_VERSION 3 +#define SHI_UPDATE_LEVEL 0 +#endif /* !WINDOWS */ + +#ifndef MEM_DEBUG + +/* Error codes: errorCode field of MEM_ERROR_INFO */ +#ifndef MEM_ERROR_CODE_DEFINED +#define MEM_ERROR_CODE_DEFINED +typedef enum +{ + MEM_NO_ERROR=0, + MEM_INTERNAL_ERROR, + MEM_OUT_OF_MEMORY, + MEM_BLOCK_TOO_BIG, + MEM_ALLOC_ZERO, + MEM_RESIZE_FAILED, + MEM_LOCK_ERROR, + MEM_EXCEEDED_CEILING, + MEM_TOO_MANY_PAGES, + MEM_TOO_MANY_TASKS, + MEM_BAD_MEM_POOL, + MEM_BAD_BLOCK, + MEM_BAD_FREE_BLOCK, + MEM_BAD_HANDLE, + MEM_BAD_POINTER, + MEM_WRONG_TASK, + MEM_NOT_FIXED_SIZE, + MEM_BAD_FLAGS, + MEM_ERROR_CODE_INT_MAX = INT_MAX /* to ensure enum is full int in size */ +} MEM_ERROR_CODE; +#endif /* MEM_ERROR_CODE_DEFINED */ + + +/* ### we should have packing pragma around these structure decls in case + * ### user is compiling with non-default packing directive (only needed + * ### if user is packing more strictly than native int size *and* if + * ### native int size is != native long and ptr sizes) + */ + +/* Error info, passed to error-handling callback routine */ +#ifndef MEM_ERROR_INFO_DEFINED +#define MEM_ERROR_INFO_DEFINED +typedef struct _MEM_ERROR_INFO +{ + MEM_ERROR_CODE errorCode; /* error code identifying type of error */ + MEM_POOL pool; /* pool in which error occurred, if known */ +} MEM_ERROR_INFO; + +/* Error handling callback function */ +typedef MEM_BOOL (MEM_ENTRY2 * MEM_ENTRY3 MEM_ERROR_FN) + (MEM_ERROR_INFO MEM_FAR *); + +#endif /* MEM_ERROR_INFO_DEFINED */ + +#endif /* MEM_DEBUG */ + + +#ifndef MEM_BLOCK_TYPE_DEFINED +#define MEM_BLOCK_TYPE_DEFINED +/* Block Type: field of MEM_POOL_ENTRY, field of MEM_POOL_INFO, + * parameter to MemPoolPreAllocate + */ +typedef enum +{ + MEM_FS_BLOCK = 0x0001u, + MEM_VAR_MOVEABLE_BLOCK = 0x0002u, + MEM_VAR_FIXED_BLOCK = 0x0004u, + MEM_EXTERNAL_BLOCK = 0x0008u, + MEM_BLOCK_TYPE_INT_MAX = INT_MAX /* to ensure enum is full int in size */ +} MEM_BLOCK_TYPE; +#endif /* MEM_BLOCK_TYPE_DEFINED */ + +#ifndef MEM_POOL_ENTRY_DEFINED +#define MEM_POOL_ENTRY_DEFINED +/* Pool Entry: parameter to MemPoolWalk */ +typedef struct +{ + void MEM_FAR *entry; + MEM_POOL pool; + MEM_BLOCK_TYPE type; + MEM_BOOL isInUse; + unsigned long size; + MEM_HANDLE handle; + unsigned lockCount; + void MEM_FAR *reserved_ptr; +} MEM_POOL_ENTRY; +#endif /* MEM_POOL_ENTRY_DEFINED */ + +#ifndef MEM_POOL_STATUS_DEFINED +#define MEM_POOL_STATUS_DEFINED +/* Pool Status: returned by MemPoolWalk, MemPoolFirst, MemPoolNext */ +typedef enum +{ + MEM_POOL_OK = 1, + MEM_POOL_CORRUPT = -1, + MEM_POOL_CORRUPT_FATAL = -2, + MEM_POOL_END = 0, + MEM_POOL_STATUS_INT_MAX = INT_MAX /* to ensure enum is full int in size */ +} MEM_POOL_STATUS; +#endif /* MEM_POOL_STATUS_DEFINED */ + +#ifndef MEM_POINTER_STATUS_DEFINED +#define MEM_POINTER_STATUS_DEFINED +/* Pointer Status: returned by MemCheckPtr */ +typedef enum +{ + MEM_POINTER_OK = 1, + MEM_POINTER_WILD = 0, + MEM_POINTER_FREE = -1, + MEM_POINTER_STATUS_INT_MAX = INT_MAX /* to ensure enum is full int in size */ +} MEM_POINTER_STATUS; +#endif /* MEM_POINTER_STATUS_DEFINED */ + +/* Pool Info: parameter to MemPoolInfo, MemPoolFirst, MemPoolNext */ +typedef struct +{ + MEM_POOL pool; + MEM_BLOCK_TYPE type; /* disjunctive combination of block type flags */ + unsigned short blockSizeFS; + unsigned short smallBlockSize; + unsigned pageSize; + unsigned long floor; + unsigned long ceiling; + unsigned flags; + MEM_ERROR_FN errorFn; +} MEM_POOL_INFO; + +/* Flags passed to MemAlloc, MemAllocPtr, MemReAlloc, MemReAllocPtr */ +#define MEM_FIXED 0x0000u /* fixed handle-based block */ +#define MEM_ZEROINIT 0x0001u /* == TRUE for SH 1.5 compatibility */ +#define MEM_MOVEABLE 0x0002u /* moveable handle-based block */ +#define MEM_RESIZEABLE 0x0004u /* reserve space above block */ +#define MEM_RESIZE_IN_PLACE 0x0008u /* do not move block (realloc) */ +#define MEM_NOGROW 0x0010u /* do not grow heap to satisfy request */ +#define MEM_NOEXTERNAL 0x0020u /* reserved for internal use */ +#define MEM_NOCOMPACT 0x0040u /* do not compact to satisfy request */ +#define MEM_NO_SERIALIZE 0x0080u /* do not serialize this request */ +#define MEM_HANDLEBASED 0x4000u /* for internal use */ +#define MEM_RESERVED 0x8000u /* for internal use */ + +#define MEM_UNLOCK_FAILED USHRT_MAX + +/* Flags passed to MemPoolInit, MemPoolInitFS */ +#ifndef MEM_POOL_SHARED +#define MEM_POOL_SHARED 0x0001u /* == TRUE for SH 1.5 compatibility */ +#define MEM_POOL_SERIALIZE 0x0002u /* pool used in more than one thread */ +#define MEM_POOL_VIRTUAL_LOCK 0x0004u /* pool is locked in physical memory */ +#define MEM_POOL_ZEROINIT 0x0008u /* malloc/new from pool zero-inits */ +#define MEM_POOL_REGION 0x0010u /* store pool in user-supplied region*/ +#define MEM_POOL_DEFAULT 0x8000u /* pool with default characteristics */ +#endif /* MEM_POOL_SHARED */ + +MEM_ENTRY4 MEM_POOL MemDefaultPool; + +/* Default memory pool for C malloc, C++ new (for backwards compatibility) */ +#define MEM_DEFAULT_POOL MemDefaultPool + +/* define and initialize these variables at file scope to change defaults */ +extern unsigned short MemDefaultPoolBlockSizeFS; +extern unsigned MemDefaultPoolPageSize; +extern unsigned MemDefaultPoolFlags; + +/* define SmartHeap_malloc at file scope if you + * are intentionally _NOT_ linking in the SmartHeap malloc definition + * ditto for SmartHeap operator new, and fmalloc et al. + */ +extern int SmartHeap_malloc; +extern int SmartHeap_far_malloc; +extern int SmartHeap_new; + +#define MEM_ERROR_RET ULONG_MAX + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(_SMARTHEAP_H) */ + + +/*** Function Prototypes ***/ + +#ifndef _SMARTHEAP_PROT +#define _SMARTHEAP_PROT + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _shAPI + #if defined(MEM_DEBUG) && !defined(SHI_NO_MEM_DEBUG) + #define _shAPI(ret, name) MEM_ENTRY1 ret MEM_ENTRY _dbg ## name + #else + #define _shAPI(ret, name) MEM_ENTRY1 ret MEM_ENTRY name + #endif +#endif + +#ifndef _dbgARGS + #if defined(MEM_DEBUG) && !defined(SHI_NO_MEM_DEBUG) + #define _dbgARGS1 const char MEM_FAR *, int + #define _dbgARGS , _dbgARGS1 + #else + #define _dbgARGS1 void + #define _dbgARGS + #endif +#endif + + +/**** HOW TO READ SmartHeap PROTOTYPES **** + * prototypes below have the follow syntax in order to support both debug + * and non-debug APIs with single-source: + * + * _shiAPI(, )([] _dbgARGS); + * + * the above translates to a C prototype as follows: + * + * ([]); + */ + +/* Library Version */ +MEM_ENTRY1 MEM_VERSION MEM_ENTRY MemVersion(void); + +/* Library Registration */ +_shAPI(MEM_BOOL, MemRegisterTask)(_dbgARGS1); +_shAPI(MEM_BOOL, MemUnregisterTask)(_dbgARGS1); + +/* Memory Pool Functions */ +_shAPI(MEM_POOL, MemPoolInit)(unsigned _dbgARGS); +_shAPI(MEM_POOL, MemPoolInitFS)(MEM_USHORT, unsigned long, + unsigned _dbgARGS); +_shAPI(MEM_POOL, MemPoolInitRegion)(void MEM_FAR *, + unsigned long size, unsigned _dbgARGS); +_shAPI(MEM_POOL, MemPoolInitNamedShared)(const char MEM_FAR *, + unsigned long size,unsigned _dbgARGS); +_shAPI(MEM_POOL, MemPoolInitNamedSharedEx)(void MEM_FAR *addr, + unsigned pidCount, unsigned long MEM_FAR *pids, void MEM_FAR *security, + const char MEM_FAR *name, unsigned long size, unsigned flags _dbgARGS); +_shAPI(MEM_POOL, MemPoolAttachShared)(MEM_POOL, const char MEM_FAR * _dbgARGS); +_shAPI(MEM_BOOL, MemPoolFree)(MEM_POOL _dbgARGS); +MEM_POOL MEM_ENTRY MemInitDefaultPool(void); +MEM_BOOL MEM_ENTRY MemFreeDefaultPool(void); +_shAPI(unsigned, MemPoolSetPageSize)(MEM_POOL, unsigned _dbgARGS); +_shAPI(MEM_BOOL, MemPoolSetBlockSizeFS)(MEM_POOL, MEM_USHORT _dbgARGS); +_shAPI(MEM_BOOL, MemPoolSetSmallBlockSize)(MEM_POOL, MEM_USHORT _dbgARGS); +_shAPI(unsigned long, MemPoolSetFloor)(MEM_POOL, unsigned long _dbgARGS); +_shAPI(unsigned long, MemPoolSetCeiling)(MEM_POOL, unsigned long _dbgARGS); +_shAPI(unsigned long, MemPoolPreAllocate)(MEM_POOL, unsigned long, + MEM_BLOCK_TYPE _dbgARGS); +_shAPI(unsigned long, MemPoolPreAllocateHandles)(MEM_POOL, + unsigned long _dbgARGS); +_shAPI(unsigned long, MemPoolShrink)(MEM_POOL _dbgARGS); +_shAPI(unsigned long, MemPoolSize)(MEM_POOL _dbgARGS); +_shAPI(unsigned long, MemPoolCount)(MEM_POOL _dbgARGS); +_shAPI(MEM_BOOL, MemPoolInfo)(MEM_POOL, void MEM_FAR *, + MEM_POOL_INFO MEM_FAR* _dbgARGS); +_shAPI(MEM_POOL_STATUS, MemPoolFirst)(MEM_POOL_INFO MEM_FAR *, + MEM_BOOL _dbgARGS); +_shAPI(MEM_POOL_STATUS,MemPoolNext)(MEM_POOL_INFO MEM_FAR*,MEM_BOOL _dbgARGS); +_shAPI(MEM_POOL_STATUS,MemPoolWalk)(MEM_POOL,MEM_POOL_ENTRY MEM_FAR*_dbgARGS); +_shAPI(MEM_BOOL, MemPoolCheck)(MEM_POOL _dbgARGS); +_shAPI(MEM_BOOL, MemPoolLock)(MEM_POOL _dbgARGS); +_shAPI(MEM_BOOL, MemPoolUnlock)(MEM_POOL _dbgARGS); + +/* Handle-based API for moveable memory within heap. */ +_shAPI(MEM_HANDLE, MemAlloc)(MEM_POOL, unsigned, unsigned long _dbgARGS); +_shAPI(MEM_HANDLE, MemReAlloc)(MEM_HANDLE,unsigned long,unsigned _dbgARGS); +_shAPI(MEM_BOOL, MemFree)(MEM_HANDLE _dbgARGS); +_shAPI(void MEM_FAR *, MemLock)(MEM_HANDLE _dbgARGS); +_shAPI(unsigned, MemUnlock)(MEM_HANDLE _dbgARGS); +_shAPI(void MEM_FAR *, MemFix)(MEM_HANDLE _dbgARGS); +_shAPI(unsigned, MemUnfix)(MEM_HANDLE _dbgARGS); +_shAPI(unsigned, MemLockCount)(MEM_HANDLE _dbgARGS); +#ifndef MemFlags +#define MemFlags(mem) MemLockCount(mem) +#endif +_shAPI(MEM_BOOL, MemIsMoveable)(MEM_HANDLE _dbgARGS); +_shAPI(unsigned long, MemSize)(MEM_HANDLE _dbgARGS); +_shAPI(unsigned long, MemSizeRequested)(MEM_HANDLE _dbgARGS); +_shAPI(MEM_HANDLE, MemHandle)(void MEM_FAR * _dbgARGS); +#ifndef MEM_REFERENCE + #ifdef MEM_DEBUG + MEM_ENTRY1 void MEM_FAR * MEM_ENTRY _dbgMemReference(MEM_HANDLE, + const char MEM_FAR *, int); + #define MEM_REFERENCE(handle) \ + _dbgMemReference(handle, __FILE__, __LINE__) + #else + #define MEM_REFERENCE(handle) (*(void MEM_FAR * MEM_FAR *)handle) + #endif +#endif + +/* General Heap Allocator (returns direct pointer to memory) */ +_shAPI(void MEM_FAR*,MemAllocPtr)(MEM_POOL,unsigned long,unsigned _dbgARGS); +_shAPI(void MEM_FAR *, MemReAllocPtr)(void MEM_FAR *, unsigned long, + unsigned _dbgARGS); +_shAPI(MEM_BOOL, MemFreePtr)(void MEM_FAR * _dbgARGS); +_shAPI(unsigned long, MemSizePtr)(void MEM_FAR * _dbgARGS); +_shAPI(MEM_POINTER_STATUS, MemCheckPtr)(MEM_POOL, void MEM_FAR * _dbgARGS); + +/* Fixed-Size Allocator */ +_shAPI(void MEM_FAR *, MemAllocFS)(MEM_POOL _dbgARGS); +_shAPI(MEM_BOOL, MemFreeFS)(void MEM_FAR * _dbgARGS); + +/* Error Handling Functions */ +MEM_ENTRY1 MEM_ERROR_FN MEM_ENTRY MemSetErrorHandler(MEM_ERROR_FN); +MEM_ENTRY1 MEM_BOOL MEM_ENTRY MemDefaultErrorHandler(MEM_ERROR_INFO MEM_FAR*); +MEM_ENTRY1 void MEM_ENTRY MemErrorUnwind(void); + +#ifdef MEM_WIN32 +/* patching control */ + +#ifndef MEM_PATCHING_DEFINED +#define MEM_PATCHING_DEFINED +typedef enum +{ + MEM_PATCH_ALL = 0, + MEM_SKIP_PATCHING_THIS_DLL = 1, + MEM_DISABLE_SYSTEM_HEAP_PATCHING = 2, + MEM_DISABLE_ALL_PATCHING = 4|2|1, + MEM_PATCHING_INT_MAX = INT_MAX /* to ensure enum is full int in size */ +} MEM_PATCHING; +#endif /* MEM_PATCHING_DEFINED */ + +#ifdef _MSC_VER +__declspec(dllexport) +#endif +MEM_PATCHING MEM_ENTRY MemSetPatching(const char ***skipDLLs); + +#endif /* MEM_WIN32 */ + +/* internal routines */ +MEM_ENTRY1 MEM_BOOL MEM_ENTRY _shi_enterCriticalSection(void); +MEM_ENTRY1 void MEM_ENTRY _shi_leaveCriticalSection(void); +MEM_BOOL shi_call_new_handler_msc(size_t, MEM_BOOL); + + +/* Wrapper macros for debugging API */ +#ifndef _SHI_dbgMacros +#ifdef MEM_DEBUG +#define MemRegisterTask() _dbgMemRegisterTask(__FILE__, __LINE__) +#define MemUnregisterTask() _dbgMemUnregisterTask(__FILE__, __LINE__) +#define MemPoolInit(flags) _dbgMemPoolInit(flags, __FILE__, __LINE__) +#define MemPoolInitFS(bs, bc, f) _dbgMemPoolInitFS(bs,bc,f,__FILE__,__LINE__) +#define MemPoolInitRegion(addr, sz, f) \ + _dbgMemPoolInitRegion(addr, sz, f, __FILE__, __LINE__) +#define MemPoolInitNamedShared(nm, sz, f) \ + _dbgMemPoolInitNamedShared(nm, sz, f, __FILE__, __LINE__) +#define MemPoolInitNamedSharedEx(a, c, p, sec, nm, sz, f) \ + _dbgMemPoolInitNamedSharedEx(a, c, p, sec, nm, sz, f, __FILE__, __LINE__) +#define MemPoolAttachShared(p, n) \ + _dbgMemPoolAttachShared(p, n, __FILE__, __LINE__) +#define MemPoolFree(pool) _dbgMemPoolFree(pool, __FILE__, __LINE__) +#define MemPoolSetPageSize(p, s) _dbgMemPoolSetPageSize(p,s,__FILE__,__LINE__) +#define MemPoolSetBlockSizeFS(p, s) \ + _dbgMemPoolSetBlockSizeFS(p, s, __FILE__, __LINE__) +#define MemPoolSetSmallBlockSize(p, s) \ + _dbgMemPoolSetSmallBlockSize(p, s, __FILE__, __LINE__) +#define MemPoolSetFloor(p, f) _dbgMemPoolSetFloor(p, f, __FILE__, __LINE__) +#define MemPoolSetCeiling(p, c) _dbgMemPoolSetCeiling(p,c,__FILE__, __LINE__) +#define MemPoolPreAllocate(p,s,t) \ + _dbgMemPoolPreAllocate(p,s,t,__FILE__, __LINE__) +#define MemPoolPreAllocateHandles(p,h) \ + _dbgMemPoolPreAllocateHandles(p,h,__FILE__, __LINE__) +#define MemPoolShrink(p) _dbgMemPoolShrink(p, __FILE__, __LINE__) +#define MemPoolCheck(p) _dbgMemPoolCheck(p, __FILE__, __LINE__) +#define MemPoolWalk(p, e) _dbgMemPoolWalk(p, e, __FILE__, __LINE__) +#define MemPoolSize(p) _dbgMemPoolSize(p, __FILE__, __LINE__) +#define MemPoolCount(p) _dbgMemPoolCount(p, __FILE__, __LINE__) +#define MemPoolInfo(p,x,i) _dbgMemPoolInfo(p,x,i, __FILE__, __LINE__) +#define MemPoolFirst(i, b) _dbgMemPoolFirst(i, b, __FILE__, __LINE__) +#define MemPoolNext(i, b) _dbgMemPoolNext(i, b, __FILE__, __LINE__) +#define MemPoolLock(p) _dbgMemPoolLock(p, __FILE__, __LINE__) +#define MemPoolUnlock(p) _dbgMemPoolUnlock(p, __FILE__, __LINE__) +#define MemAlloc(p, f, s) _dbgMemAlloc(p, f, s, __FILE__, __LINE__) +#define MemReAlloc(h, s, f) _dbgMemReAlloc(h, s, f, __FILE__, __LINE__) +#define MemFree(h) _dbgMemFree(h, __FILE__, __LINE__) +#define MemLock(h) _dbgMemLock(h, __FILE__, __LINE__) +#define MemUnlock(h) _dbgMemUnlock(h, __FILE__, __LINE__) +#define MemFix(h) _dbgMemFix(h, __FILE__, __LINE__) +#define MemUnfix(h) _dbgMemUnfix(h, __FILE__, __LINE__) +#define MemSize(h) _dbgMemSize(h, __FILE__, __LINE__) +#define MemSizeRequested(h) _dbgMemSizeRequested(h, __FILE__, __LINE__) +#define MemLockCount(h) _dbgMemLockCount(h, __FILE__, __LINE__) +#define MemIsMoveable(h) _dbgMemIsMoveable(h, __FILE__, __LINE__) +#define MemHandle(p) _dbgMemHandle(p, __FILE__, __LINE__) +#define MemAllocPtr(p, s, f) _dbgMemAllocPtr(p, s, f, __FILE__, __LINE__) +#define MemReAllocPtr(p, s, f) _dbgMemReAllocPtr(p, s, f, __FILE__,__LINE__) +#define MemFreePtr(p) _dbgMemFreePtr(p, __FILE__, __LINE__) +#define MemSizePtr(p) _dbgMemSizePtr(p, __FILE__, __LINE__) +#define MemCheckPtr(p, x) _dbgMemCheckPtr(p, x, __FILE__, __LINE__) +#define MemAllocFS(p) _dbgMemAllocFS(p, __FILE__, __LINE__) +#define MemFreeFS(p) _dbgMemFreeFS(p, __FILE__, __LINE__) + +#else /* MEM_DEBUG */ + +/* MEM_DEBUG not defined: define dbgMemXXX as no-op macros + * each macro returns "success" value when MEM_DEBUG not defined + */ +#ifndef dbgMemBreakpoint +#define dbgMemBreakpoint() ((void)0) +#define dbgMemCheckAll() 1 +#define dbgMemCheckPtr(p, f, s) 1 +#define dbgMemDeferFreeing(b) 1 +#define dbgMemFormatCall(i, b, s) 0 +#define dbgMemFormatErrorInfo(i, b, s) 0 +#define dbgMemPoolDeferFreeing(p, b) 1 +#define dbgMemFreeDeferred() 1 +#define dbgMemPoolFreeDeferred(p) 1 +#define dbgMemPoolInfo(p, b) 1 +#define dbgMemPoolSetCheckFrequency(p, f) 1 +#define dbgMemPoolSetDeferQueueLen(p, b) 1 +#define dbgMemPoolSetName(p, n) 1 +#define dbgMemProtectPtr(p, f) 1 +#define dbgMemPtrInfo(p, b) 1 +#define dbgMemReallocMoves(b) 1 +#define dbgMemReportLeakage(p, c1, c2) 1 +#define dbgMemReportWrongTaskRef(b) 1 +#define dbgMemScheduleChecking(b, p, i) 1 +#define dbgMemSetCheckFrequency(f) 1 +#define dbgMemSetCheckpoint(c) 1 +#define dbgMemSetDefaultErrorOutput(x, f) 1 +#define dbgMemSetDeferQueueLen(l) 1 +#define dbgMemSetDeferSizeThreshold(s) 1 +#define dbgMemSetEntryHandler(f) 0 +#define dbgMemSetExitHandler(f) 0 +#define dbgMemSetFreeFill(c) 1 +#define dbgMemSetGuardFill(c) 1 +#define dbgMemSetGuardSize(s) 1 +#define dbgMemSetInUseFill(c) 1 +#define dbgMemSetCallstackChains(s) 1 +#define dbgMemSetStackChecking(s) 1 +#define dbgMemSetSafetyLevel(s) 1 +#define dbgMemSettingsInfo(b) 1 +#define dbgMemSuppressFreeFill(b) 1 +#define dbgMemTotalCount() 1 +#define dbgMemTotalSize() 1 +#define dbgMemWalkHeap(b) MEM_POOL_OK +#endif /* dbgMemBreakpoint */ + +#endif /* MEM_DEBUG */ +#endif /* _SHI_dbgMacros */ + +#if defined(__WATCOMC__) && defined(__SW_3S) +/* Watcom stack calling convention */ + #pragma aux MemDefaultPool "_*"; + #pragma aux MemDefaultPoolBlockSizeFS "_*"; + #pragma aux MemDefaultPoolPageSize "_*"; + #pragma aux MemDefaultPoolFlags "_*"; + #pragma aux SmartHeap_malloc "_*"; + #pragma aux SmartHeap_far_malloc "_*"; + #pragma aux SmartHeap_new "_*"; +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !defined(_SMARTHEAP_PROT) */ diff --git a/3rdparty/smartheap/SMRTHEAP.HPP b/3rdparty/smartheap/SMRTHEAP.HPP new file mode 100644 index 00000000..663b6c90 --- /dev/null +++ b/3rdparty/smartheap/SMRTHEAP.HPP @@ -0,0 +1,159 @@ +// smrtheap.hpp -- SmartHeap public C++ header file +// Professional Memory Management Library +// +// Copyright (C) 1991-1996 by Arthur D. Applegate +// All Rights Reserved. +// +// No part of this source code may be copied, modified or reproduced +// in any form without retaining the above copyright notice. +// This source code, or source code derived from it, may not be redistributed +// without express written permission of the author. +// +// COMMENTS: +// - Include this header file to call the SmartHeap-specific versions of +// operators new (i.e. with placement syntax), to: +// o allocate from a specific memory pool; +// o specify allocation flags, such as zero-initialization; +// o resize an allocation. +// +// - If you include this header file, you must compile and link shnew.cpp, or +// link with one of the SmartHeap static operator new libraries: +// sh[l|d]XXXX.lib +// +// - Can be used in both EXEs and DLLs. +// +// - For 16-bit x86 platforms, use only in large or compact memory model. +// +// - If you do not want to use SmartHeap's global operator new but you do +// want to use SmartHeap's other facilities in a C++ application, then +// include the smrtheap.h header file but do not include this header file, +// and do not link with shnew.cpp. The two ".Xpp" files are present +// ONLY for the purpose of defining operator new and operator delete. +// +// - Use the MemDefaultPool global variable to refer to a memory pool to pass +// to SmartHeap functions that accept a pool as a parameter, +// e.g. MemPoolCount, MemPoolSize, MemPoolWalk, etc. +// + +#if !defined(_SMARTHEAP_HPP) +#define _SMARTHEAP_HPP + +#if defined(_MSC_VER) \ + && (defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM)) \ + && !defined(MEM_HUGE) +#define MEM_HUGE 0x8000u +#endif + +#ifndef __BORLANDC__ +/* Borland C++ does not treat extern "C++" correctly */ +extern "C++" +{ +#endif /* __BORLANDC__ */ + +#if defined(_MSC_VER) && _MSC_VER >= 900 +#pragma warning(disable : 4507) +#endif + +#if defined(new) +#if defined(MEM_DEBUG) +#undef new +#endif +#endif + +#include + +#include "smrtheap.h" + +#if defined(new) +#if defined(MEM_DEBUG) +#undef new +#endif +#endif + +#if ((defined(__BORLANDC__) && (__BORLANDC__ >= 0x450)) \ + || (defined(__WATCOMC__) && __WATCOMC__ >= 1000) \ + || (defined(__IBMCPP__) && __IBMCPP__ >= 250)) +#define SHI_ARRAY_NEW 1 +#endif + +void MEM_FAR * MEM_ENTRY_ANSI shi_New(unsigned long sz, unsigned flags=0, MEM_POOL pool=0); + +// operator new variants: + + +// version of new that passes memory allocation flags +// (e.g. MEM_ZEROINIT to zero-initialize memory) +// call with syntax 'ptr = new (flags) ' +inline void MEM_FAR *operator new(size_t sz, unsigned flags) + { return shi_New(sz, flags); } + +// version of new that allocates from a specified memory pool with alloc flags +// call with the syntax 'ptr = new (pool, [flags=0]) ' +inline void MEM_FAR *operator new(size_t sz, MEM_POOL pool, unsigned flags=0) + { return shi_New(sz, flags, pool); } +#ifdef SHI_ARRAY_NEW +inline void MEM_FAR *operator new[](size_t sz, MEM_POOL pool, unsigned flags=0) + { return shi_New(sz, flags, pool); } +#endif + +// version of new that changes the size of a memory block previously allocated +// from an SmartHeap memory pool +// call with the syntax 'ptr = new (ptr, flags) ' +#if !defined(MEM_DEBUG) || !defined(__HIGHC__) +/* bug in MetaWare High C++ parser confuses this with new(file,line) */ +inline void MEM_FAR *operator new(size_t new_sz, void MEM_FAR *lpMem, + unsigned flags) + { return MemReAllocPtr(lpMem, new_sz, flags); } +#ifdef SHI_ARRAY_NEW +inline void MEM_FAR *operator new[](size_t new_sz, void MEM_FAR *lpMem, + unsigned flags) + { return MemReAllocPtr(lpMem, new_sz, flags); } +#endif // SHI_ARRAY_NEW +#endif + + +// new_handler prototypes: note that MSC/C++ prototype differs from the +// protosed ANSI standard prototype for set_new_handler +#ifdef __MWERKS__ +#define MEM_CPP_THROW throw() +#else +#define MEM_CPP_THROW +#endif // __MWERKS__ +#ifndef _CRTIMP +#define _CRTIMP +#endif // _CRTIMP +#ifdef _MSC_VER +_CRTIMP _PNH MEM_ENTRY_ANSI _set_new_handler(_PNH); +#if UINT_MAX == 0xFFFFu +_PNH MEM_ENTRY_ANSI _set_fnew_handler(_PNH); +_PNHH MEM_ENTRY_ANSI _set_hnew_handler(_PNHH); +#endif // UINT_MAX +#endif // _MSC_VER +typedef void (MEM_ENTRY_ANSI * pnh)(); +_CRTIMP pnh MEM_ENTRY_ANSI set_new_handler(pnh) MEM_CPP_THROW; + +#ifndef DBG_FORMAL +#define DBG_FORMAL +#define DBG_ACTUAL +#ifndef DEBUG_NEW +#define DEBUG_NEW new +#endif // DEBUG_NEW +#define DEBUG_NEW1(x_) new(x_) +#define DEBUG_NEW2(x_, y_) new(x_, y_) +#define DEBUG_NEW3(x_, y_, z_) new(x_, y_, z_) +#define DEBUG_DELETE delete +#endif + +#ifdef DEFINE_NEW_MACRO +#define new DEBUG_NEW +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 900 +#pragma warning(default : 4507) +#endif + +#ifndef __BORLANDC__ +} +#endif /* __BORLANDC__ */ + +#endif /* !defined(_SMARTHEAP_HPP) */ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6067d1f9..eafee9ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,9 @@ -cmake_minimum_required(VERSION 3.0...3.5 FATAL_ERROR) +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) project(isle CXX) option(ISLE_BUILD_APP "Build ISLE.EXE application" ON) +option(ISLE_USE_SMARTHEAP "Build with SmartHeap" ${MSVC}) add_library(lego1 SHARED LEGO1/act1state.cpp @@ -177,6 +178,16 @@ add_library(lego1 SHARED LEGO1/viewmanager.cpp ) +if (ISLE_USE_SMARTHEAP) + add_library(SmartHeap::SmartHeap STATIC IMPORTED) + set_target_properties(SmartHeap::SmartHeap PROPERTIES + IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/3rdparty/smartheap/SHLW32MT.LIB" + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/3rdparty/smartheap" + INTERFACE_COMPILE_OPTIONS "/FI${CMAKE_SOURCE_DIR}/3rdparty/smartheap/SMRTHEAP.HPP") + + target_link_libraries(lego1 PRIVATE SmartHeap::SmartHeap) +endif() + # Link libraries target_link_libraries(lego1 PRIVATE ddraw dsound winmm) @@ -194,6 +205,10 @@ if (ISLE_BUILD_APP) # Include LEGO1 headers in ISLE target_include_directories(isle PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1") + if (ISLE_USE_SMARTHEAP) + target_link_libraries(isle PRIVATE SmartHeap::SmartHeap) + endif() + # Link DSOUND, WINMM, and LEGO1 target_link_libraries(isle PRIVATE dsound winmm lego1)