Mac and Linux SDL2 binary snapshots
Edward Rudd
2020-05-02 03f8528315fa46c95991a34f3325d7b33ae5538c
source/src/stdlib/SDL_malloc.c
@@ -1,6 +1,6 @@
/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
@@ -18,42 +18,27 @@
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_config.h"
#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS)
#define SDL_DISABLE_ANALYZE_MACROS 1
#endif
#include "../SDL_internal.h"
/* This file contains portable memory management functions for SDL */
#include "SDL_stdinc.h"
#include "SDL_atomic.h"
#include "SDL_error.h"
#if defined(HAVE_MALLOC)
void *SDL_malloc(size_t size)
{
    return malloc(size);
}
void *SDL_calloc(size_t nmemb, size_t size)
{
    return calloc(nmemb, size);
}
void *SDL_realloc(void *ptr, size_t size)
{
    return realloc(ptr, size);
}
void SDL_free(void *ptr)
{
    free(ptr);
}
#else  /* the rest of this is a LOT of tapdancing to implement malloc. :) */
#ifndef HAVE_MALLOC
#define LACKS_SYS_TYPES_H
#define LACKS_STDIO_H
#define LACKS_STRINGS_H
#define LACKS_STRING_H
#define LACKS_STDLIB_H
#define ABORT
#define USE_LOCKS 1
#define USE_DL_PREFIX
/*
  This is a version (aka dlmalloc) of malloc/free/realloc written by
@@ -517,6 +502,14 @@
#define MMAP_CLEARS 0           /* WINCE and some others apparently don't clear */
#endif /* WIN32 */
#ifdef __OS2__
#define INCL_DOS
#include <os2.h>
#define HAVE_MMAP 1
#define HAVE_MORECORE 0
#define LACKS_SYS_MMAN_H
#endif  /* __OS2__ */
#if defined(DARWIN) || defined(_DARWIN)
/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
#ifndef HAVE_MORECORE
@@ -630,12 +623,12 @@
#define MALLINFO_FIELD_TYPE size_t
#endif /* MALLINFO_FIELD_TYPE */
#ifndef memset
#define memset  SDL_memset
#endif
#ifndef memcpy
#define memcpy  SDL_memcpy
#define malloc  SDL_malloc
#define calloc  SDL_calloc
#define realloc SDL_realloc
#define free    SDL_free
#endif
/*
  mallopt tuning options.  SVID/XPG defines four standard parameter
@@ -1357,7 +1350,7 @@
#define IS_MMAPPED_BIT       (SIZE_T_ONE)
#define USE_MMAP_BIT         (SIZE_T_ONE)
#ifndef WIN32
#if !defined(WIN32) && !defined (__OS2__)
#define CALL_MUNMAP(a, s)    munmap((a), (s))
#define MMAP_PROT            (PROT_READ|PROT_WRITE)
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
@@ -1380,6 +1373,42 @@
#endif /* MAP_ANONYMOUS */
#define DIRECT_MMAP(s)       CALL_MMAP(s)
#elif defined(__OS2__)
/* OS/2 MMAP via DosAllocMem */
static void* os2mmap(size_t size) {
  void* ptr;
  if (DosAllocMem(&ptr, size, OBJ_ANY|PAG_COMMIT|PAG_READ|PAG_WRITE) &&
      DosAllocMem(&ptr, size, PAG_COMMIT|PAG_READ|PAG_WRITE))
    return MFAIL;
  return ptr;
}
#define os2direct_mmap(n)     os2mmap(n)
/* This function supports releasing coalesed segments */
static int os2munmap(void* ptr, size_t size) {
  while (size) {
    ULONG ulSize = size;
    ULONG ulFlags = 0;
    if (DosQueryMem(ptr, &ulSize, &ulFlags) != 0)
      return -1;
    if ((ulFlags & PAG_BASE) == 0 ||(ulFlags & PAG_COMMIT) == 0 ||
        ulSize > size)
      return -1;
    if (DosFreeMem(ptr) != 0)
      return -1;
    ptr = ( void * ) ( ( char * ) ptr + ulSize );
    size -= ulSize;
  }
  return 0;
}
#define CALL_MMAP(s)         os2mmap(s)
#define CALL_MUNMAP(a, s)    os2munmap((a), (s))
#define DIRECT_MMAP(s)       os2direct_mmap(s)
#else /* WIN32 */
/* Win32 MMAP via VirtualAlloc */
@@ -1463,7 +1492,7 @@
    unique mparams values are initialized only once.
*/
#ifndef WIN32
#if !defined(WIN32) && !defined(__OS2__)
/* By default use posix locks */
#include <pthread.h>
#define MLOCK_T pthread_mutex_t
@@ -1476,6 +1505,16 @@
#endif /* HAVE_MORECORE */
static MLOCK_T magic_init_mutex = PTHREAD_MUTEX_INITIALIZER;
#elif defined(__OS2__)
#define MLOCK_T HMTX
#define INITIAL_LOCK(l)      DosCreateMutexSem(0, l, 0, FALSE)
#define ACQUIRE_LOCK(l)      DosRequestMutexSem(*l, SEM_INDEFINITE_WAIT)
#define RELEASE_LOCK(l)      DosReleaseMutexSem(*l)
#if HAVE_MORECORE
static MLOCK_T morecore_mutex;
#endif /* HAVE_MORECORE */
static MLOCK_T magic_init_mutex;
#else /* WIN32 */
/*
@@ -2547,10 +2586,15 @@
        }
        RELEASE_MAGIC_INIT_LOCK();
#ifndef WIN32
#if !defined(WIN32) && !defined(__OS2__)
        mparams.page_size = malloc_getpagesize;
        mparams.granularity = ((DEFAULT_GRANULARITY != 0) ?
                               DEFAULT_GRANULARITY : mparams.page_size);
#elif defined (__OS2__)
        /* if low-memory is used, os2munmap() would break
           if it were anything other than 64k */
        mparams.page_size = 4096u;
        mparams.granularity = 65536u;
#else /* WIN32 */
        {
            SYSTEM_INFO system_info;
@@ -2940,13 +2984,17 @@
internal_malloc_stats(mstate m)
{
    if (!PREACTION(m)) {
#ifndef LACKS_STDIO_H
        size_t maxfp = 0;
#endif
        size_t fp = 0;
        size_t used = 0;
        check_malloc_state(m);
        if (is_initialized(m)) {
            msegmentptr s = &m->seg;
#ifndef LACKS_STDIO_H
            maxfp = m->max_footprint;
#endif
            fp = m->footprint;
            used = fp - (m->topsize + TOP_FOOT_SIZE);
@@ -5255,4 +5303,133 @@
#endif /* !HAVE_MALLOC */
#ifdef HAVE_MALLOC
#define real_malloc malloc
#define real_calloc calloc
#define real_realloc realloc
#define real_free free
#else
#define real_malloc dlmalloc
#define real_calloc dlcalloc
#define real_realloc dlrealloc
#define real_free dlfree
#endif
/* Memory functions used by SDL that can be replaced by the application */
static struct
{
    SDL_malloc_func malloc_func;
    SDL_calloc_func calloc_func;
    SDL_realloc_func realloc_func;
    SDL_free_func free_func;
    SDL_atomic_t num_allocations;
} s_mem = {
    real_malloc, real_calloc, real_realloc, real_free, { 0 }
};
void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func,
                            SDL_calloc_func *calloc_func,
                            SDL_realloc_func *realloc_func,
                            SDL_free_func *free_func)
{
    if (malloc_func) {
        *malloc_func = s_mem.malloc_func;
    }
    if (calloc_func) {
        *calloc_func = s_mem.calloc_func;
    }
    if (realloc_func) {
        *realloc_func = s_mem.realloc_func;
    }
    if (free_func) {
        *free_func = s_mem.free_func;
    }
}
int SDL_SetMemoryFunctions(SDL_malloc_func malloc_func,
                           SDL_calloc_func calloc_func,
                           SDL_realloc_func realloc_func,
                           SDL_free_func free_func)
{
    if (!malloc_func) {
        return SDL_InvalidParamError("malloc_func");
    }
    if (!calloc_func) {
        return SDL_InvalidParamError("calloc_func");
    }
    if (!realloc_func) {
        return SDL_InvalidParamError("realloc_func");
    }
    if (!free_func) {
        return SDL_InvalidParamError("free_func");
    }
    s_mem.malloc_func = malloc_func;
    s_mem.calloc_func = calloc_func;
    s_mem.realloc_func = realloc_func;
    s_mem.free_func = free_func;
    return 0;
}
int SDL_GetNumAllocations(void)
{
    return SDL_AtomicGet(&s_mem.num_allocations);
}
void *SDL_malloc(size_t size)
{
    void *mem;
    if (!size) {
        size = 1;
    }
    mem = s_mem.malloc_func(size);
    if (mem) {
        SDL_AtomicIncRef(&s_mem.num_allocations);
    }
    return mem;
}
void *SDL_calloc(size_t nmemb, size_t size)
{
    void *mem;
    if (!nmemb || !size) {
        nmemb = 1;
        size = 1;
    }
    mem = s_mem.calloc_func(nmemb, size);
    if (mem) {
        SDL_AtomicIncRef(&s_mem.num_allocations);
    }
    return mem;
}
void *SDL_realloc(void *ptr, size_t size)
{
    void *mem;
    if (!ptr && !size) {
        size = 1;
    }
    mem = s_mem.realloc_func(ptr, size);
    if (mem && !ptr) {
        SDL_AtomicIncRef(&s_mem.num_allocations);
    }
    return mem;
}
void SDL_free(void *ptr)
{
    if (!ptr) {
        return;
    }
    s_mem.free_func(ptr);
    (void)SDL_AtomicDecRef(&s_mem.num_allocations);
}
/* vi: set ts=4 sw=4 expandtab: */