Files
snmalloc/src/mem/external_alloc.h
Robert Norton 86aa28644c Errno fix (#463)
Correctly set errno on failure and improve the related test.

Previously the malloc test would emit an error message but not
abort if the errno was not as expected on failure. This
was because the return in the null == true case prevented the
check for failed == true at the end of check_result from
being reached. To resolve this just abort immediately as in the 
null case.

Also add tests of allocations that are expected to fail for
calloc and malloc.

To make the tests pass we need to set errno in several places,
making sure to keep this off the fast path.

We must also take care not to attempt to zero nullptr in case
of calloc failure.

See microsoft/snmalloc#461 and microsoft/snmalloc#463.
2022-02-24 10:09:29 +00:00

82 lines
1.8 KiB
C++

#pragma once
#ifdef SNMALLOC_PASS_THROUGH
# if defined(__HAIKU__)
# define _GNU_SOURCE
# endif
# include <stdlib.h>
# if defined(_WIN32) //|| defined(__APPLE__)
# error "Pass through not supported on this platform"
// The Windows aligned allocation API is not capable of supporting the
// snmalloc API Apple was not providing aligned memory in some tests.
# else
// Defines malloc_size for the platform.
# if defined(_WIN32)
namespace snmalloc::external_alloc
{
inline size_t malloc_usable_size(void* ptr)
{
return _msize(ptr);
}
}
# elif defined(__APPLE__)
# include <malloc/malloc.h>
namespace snmalloc::external_alloc
{
inline size_t malloc_usable_size(void* ptr)
{
return malloc_size(ptr);
}
}
# elif defined(__linux__) || defined(__HAIKU__)
# include <malloc.h>
namespace snmalloc::external_alloc
{
using ::malloc_usable_size;
}
# elif defined(__sun) || defined(__NetBSD__) || defined(__OpenBSD__)
namespace snmalloc::external_alloc
{
using ::malloc_usable_size;
}
# elif defined(__FreeBSD__)
# include <malloc_np.h>
namespace snmalloc::external_alloc
{
using ::malloc_usable_size;
}
# else
# error Define malloc size macro for this platform.
# endif
namespace snmalloc::external_alloc
{
inline void* aligned_alloc(size_t alignment, size_t size)
{
// TSAN complains if allocation is large than this.
if constexpr (bits::BITS == 64)
{
if (size >= 0x10000000000)
{
errno = ENOMEM;
return nullptr;
}
}
if (alignment < sizeof(void*))
alignment = sizeof(void*);
void* result;
int err = posix_memalign(&result, alignment, size);
if (err != 0)
{
errno = err;
result = nullptr;
}
return result;
}
using ::free;
}
# endif
#endif