diff options
Diffstat (limited to '3rdparty/bx/src')
-rw-r--r-- | 3rdparty/bx/src/amalgamated.cpp | 19 | ||||
-rw-r--r-- | 3rdparty/bx/src/bx.cpp | 146 | ||||
-rw-r--r-- | 3rdparty/bx/src/commandline.cpp | 4 | ||||
-rw-r--r-- | 3rdparty/bx/src/crt.cpp | 362 | ||||
-rw-r--r-- | 3rdparty/bx/src/crtimpl.cpp | 1 | ||||
-rw-r--r-- | 3rdparty/bx/src/crtnone.cpp | 590 | ||||
-rw-r--r-- | 3rdparty/bx/src/debug.cpp | 4 | ||||
-rw-r--r-- | 3rdparty/bx/src/dtoa.cpp | 82 | ||||
-rw-r--r-- | 3rdparty/bx/src/fpumath.cpp | 70 | ||||
-rw-r--r-- | 3rdparty/bx/src/mutex.cpp | 42 | ||||
-rw-r--r-- | 3rdparty/bx/src/os.cpp | 11 | ||||
-rw-r--r-- | 3rdparty/bx/src/semaphore.cpp (renamed from 3rdparty/bx/src/sem.cpp) | 141 | ||||
-rw-r--r-- | 3rdparty/bx/src/sort.cpp | 55 | ||||
-rw-r--r-- | 3rdparty/bx/src/string.cpp | 584 | ||||
-rw-r--r-- | 3rdparty/bx/src/thread.cpp | 226 | ||||
-rw-r--r-- | 3rdparty/bx/src/timer.cpp | 60 |
16 files changed, 1809 insertions, 588 deletions
diff --git a/3rdparty/bx/src/amalgamated.cpp b/3rdparty/bx/src/amalgamated.cpp new file mode 100644 index 00000000000..1aeb2bb906d --- /dev/null +++ b/3rdparty/bx/src/amalgamated.cpp @@ -0,0 +1,19 @@ +/* + * Copyright 2011-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + */ + +#include "bx.cpp" +#include "commandline.cpp" +#include "crtimpl.cpp" +#include "crtnone.cpp" +#include "debug.cpp" +#include "dtoa.cpp" +#include "fpumath.cpp" +#include "mutex.cpp" +#include "os.cpp" +#include "semaphore.cpp" +#include "sort.cpp" +#include "string.cpp" +#include "thread.cpp" +#include "timer.cpp" diff --git a/3rdparty/bx/src/bx.cpp b/3rdparty/bx/src/bx.cpp new file mode 100644 index 00000000000..8a063c56de9 --- /dev/null +++ b/3rdparty/bx/src/bx.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include <bx/debug.h> +#include <bx/readerwriter.h> + +#if !BX_CRT_NONE +# include <string.h> // memcpy, memmove, memset +#endif // !BX_CRT_NONE + +namespace bx +{ + void xchg(void* _a, void* _b, size_t _numBytes) + { + uint8_t* lhs = (uint8_t*)_a; + uint8_t* rhs = (uint8_t*)_b; + const uint8_t* end = rhs + _numBytes; + while (rhs != end) + { + xchg(*lhs++, *rhs++); + } + } + + void memCopyRef(void* _dst, const void* _src, size_t _numBytes) + { + uint8_t* dst = (uint8_t*)_dst; + const uint8_t* end = dst + _numBytes; + const uint8_t* src = (const uint8_t*)_src; + while (dst != end) + { + *dst++ = *src++; + } + } + + void memCopy(void* _dst, const void* _src, size_t _numBytes) + { +#if BX_CRT_NONE + memCopyRef(_dst, _src, _numBytes); +#else + ::memcpy(_dst, _src, _numBytes); +#endif // BX_CRT_NONE + } + + void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch) + { + const uint8_t* src = (const uint8_t*)_src; + uint8_t* dst = (uint8_t*)_dst; + + for (uint32_t ii = 0; ii < _num; ++ii) + { + memCopy(dst, src, _size); + src += _srcPitch; + dst += _dstPitch; + } + } + + /// + void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch) + { + memCopy(_dst, _src, _size, _num, _srcPitch, _size); + } + + /// + void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch) + { + memCopy(_dst, _src, _size, _num, _size, _dstPitch); + } + + void memMoveRef(void* _dst, const void* _src, size_t _numBytes) + { + uint8_t* dst = (uint8_t*)_dst; + const uint8_t* src = (const uint8_t*)_src; + + if (_numBytes == 0 + || dst == src) + { + return; + } + + // if (src+_numBytes <= dst || end <= src) + if (dst < src) + { + memCopy(_dst, _src, _numBytes); + return; + } + + for (intptr_t ii = _numBytes-1; ii >= 0; --ii) + { + dst[ii] = src[ii]; + } + } + + void memMove(void* _dst, const void* _src, size_t _numBytes) + { +#if BX_CRT_NONE + memMoveRef(_dst, _src, _numBytes); +#else + ::memmove(_dst, _src, _numBytes); +#endif // BX_CRT_NONE + } + + void memSetRef(void* _dst, uint8_t _ch, size_t _numBytes) + { + uint8_t* dst = (uint8_t*)_dst; + const uint8_t* end = dst + _numBytes; + while (dst != end) + { + *dst++ = char(_ch); + } + } + + void memSet(void* _dst, uint8_t _ch, size_t _numBytes) + { +#if BX_CRT_NONE + memSetRef(_dst, _ch, _numBytes); +#else + ::memset(_dst, _ch, _numBytes); +#endif // BX_CRT_NONE + } + + int32_t memCmpRef(const void* _lhs, const void* _rhs, size_t _numBytes) + { + const char* lhs = (const char*)_lhs; + const char* rhs = (const char*)_rhs; + for ( + ; 0 < _numBytes && *lhs == *rhs + ; ++lhs, ++rhs, --_numBytes + ) + { + } + + return 0 == _numBytes ? 0 : *lhs - *rhs; + } + + int32_t memCmp(const void* _lhs, const void* _rhs, size_t _numBytes) + { +#if BX_CRT_NONE + return memCmpRef(_lhs, _rhs, _numBytes); +#else + return ::memcmp(_lhs, _rhs, _numBytes); +#endif // BX_CRT_NONE + } + +} // namespace bx diff --git a/3rdparty/bx/src/commandline.cpp b/3rdparty/bx/src/commandline.cpp index 400e4965a0e..6ec2aadaaaf 100644 --- a/3rdparty/bx/src/commandline.cpp +++ b/3rdparty/bx/src/commandline.cpp @@ -175,13 +175,13 @@ namespace bx bool CommandLine::hasArg(const char _short, const char* _long) const { - const char* arg = findOption(_short, _long, 0); + const char* arg = findOption(_short, _long, int32_t(0) ); return NULL != arg; } bool CommandLine::hasArg(const char* _long) const { - const char* arg = findOption('\0', _long, 0); + const char* arg = findOption('\0', _long, int32_t(0) ); return NULL != arg; } diff --git a/3rdparty/bx/src/crt.cpp b/3rdparty/bx/src/crt.cpp deleted file mode 100644 index 8686f03d267..00000000000 --- a/3rdparty/bx/src/crt.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright 2010-2017 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause - */ - -#include <bx/bx.h> -#include <bx/readerwriter.h> -#include <bx/debug.h> - -namespace bx -{ - void* memCopyRef(void* _dst, const void* _src, size_t _numBytes) - { - uint8_t* dst = (uint8_t*)_dst; - const uint8_t* end = dst + _numBytes; - const uint8_t* src = (const uint8_t*)_src; - while (dst != end) - { - *dst++ = *src++; - } - - return _dst; - } - - void* memCopy(void* _dst, const void* _src, size_t _numBytes) - { -#if BX_CRT_NONE - return memCopyRef(_dst, _src, _numBytes); -#else - return ::memcpy(_dst, _src, _numBytes); -#endif // BX_CRT_NONE - } - - void memCopy(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch, uint32_t _dstPitch) - { - const uint8_t* src = (const uint8_t*)_src; - uint8_t* dst = (uint8_t*)_dst; - - for (uint32_t ii = 0; ii < _num; ++ii) - { - memCopy(dst, src, _size); - src += _srcPitch; - dst += _dstPitch; - } - } - - /// - void gather(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _srcPitch) - { - memCopy(_dst, _src, _size, _num, _srcPitch, _size); - } - - /// - void scatter(void* _dst, const void* _src, uint32_t _size, uint32_t _num, uint32_t _dstPitch) - { - memCopy(_dst, _src, _size, _num, _size, _dstPitch); - } - - void* memMoveRef(void* _dst, const void* _src, size_t _numBytes) - { - uint8_t* dst = (uint8_t*)_dst; - const uint8_t* src = (const uint8_t*)_src; - - if (_numBytes == 0 - || dst == src) - { - return dst; - } - - // if (src+_numBytes <= dst || end <= src) - if (dst < src) - { - return memcpy(_dst, _src, _numBytes); - } - - for (intptr_t ii = _numBytes-1; ii >= 0; --ii) - { - dst[ii] = src[ii]; - } - - return _dst; - } - - void* memMove(void* _dst, const void* _src, size_t _numBytes) - { -#if BX_CRT_NONE - return memMoveRef(_dst, _src, _numBytes); -#else - return ::memmove(_dst, _src, _numBytes); -#endif // BX_CRT_NONE - } - - void* memSetRef(void* _dst, uint8_t _ch, size_t _numBytes) - { - uint8_t* dst = (uint8_t*)_dst; - const uint8_t* end = dst + _numBytes; - while (dst != end) - { - *dst++ = char(_ch); - } - - return _dst; - } - - void* memSet(void* _dst, uint8_t _ch, size_t _numBytes) - { -#if BX_CRT_NONE - return memSetRef(_dst, _ch, _numBytes); -#else - return ::memset(_dst, _ch, _numBytes); -#endif // BX_CRT_NONE - } - - namespace - { - struct Param - { - int32_t width; - uint32_t base; - uint32_t prec; - char fill; - bool left; - }; - - static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err) - { - int32_t size = 0; - int32_t len = (int32_t)strnlen(_str, _len); - int32_t padding = _param.width > len ? _param.width - len : 0; - - if (!_param.left) - { - size += writeRep(_writer, _param.fill, padding, _err); - } - - size += write(_writer, _str, len, _err); - - if (_param.left) - { - size += writeRep(_writer, _param.fill, padding, _err); - } - - return size; - } - - static int32_t write(WriterI* _writer, const char* _str, const Param& _param, Error* _err) - { - return write(_writer, _str, INT32_MAX, _param, _err); - } - - static int32_t write(WriterI* _writer, int32_t _i, const Param& _param, Error* _err) - { - char str[33]; - int32_t len = toString(str, sizeof(str), _i, _param.base); - - if (len == 0) - { - return 0; - } - - return write(_writer, str, len, _param, _err); - } - - static int32_t write(WriterI* _writer, uint32_t _i, const Param& _param, Error* _err) - { - char str[33]; - int32_t len = toString(str, sizeof(str), _i, _param.base); - - if (len == 0) - { - return 0; - } - - return write(_writer, str, len, _param, _err); - } - - static int32_t write(WriterI* _writer, double _d, const Param& _param, Error* _err) - { - char str[1024]; - int32_t len = toString(str, sizeof(str), _d); - - if (len == 0) - { - return 0; - } - - const char* dot = strnchr(str, '.'); - const int32_t precLen = int32_t(dot + 1 + _param.prec - str); - if (precLen > len) - { - for (int32_t ii = len; ii < precLen; ++ii) - { - str[ii] = '0'; - } - str[precLen] = '\0'; - } - len = precLen; - - return write(_writer, str, len, _param, _err); - } - - static int32_t write(WriterI* _writer, const void* _ptr, const Param& _param, Error* _err) - { - char str[35] = "0x"; - int32_t len = toString(str + 2, sizeof(str) - 2, uint32_t(uintptr_t(_ptr) ), 16); - - if (len == 0) - { - return 0; - } - - len += 2; - return write(_writer, str, len, _param, _err); - } - } // anonymous namespace - - int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err) - { - MemoryReader reader(_format, strnlen(_format) ); - - int32_t size = 0; - - while (_err->isOk() ) - { - char ch = '\0'; - read(&reader, ch, _err); - - if (!_err->isOk() ) - { - break; - } - else if ('%' == ch) - { - // %[ -0][<width>][.<precision>] - read(&reader, ch); - - Param param; - param.base = 10; - param.prec = 6; - param.left = false; - param.fill = ' '; - param.width = 0; - - while (' ' == ch - || '-' == ch - || '0' == ch) - { - switch (ch) - { - case '-': param.left = true; break; - case ' ': param.fill = ' '; break; - case '0': param.fill = '0'; break; - } - - if (param.left) - { - param.fill = ' '; - } - - read(&reader, ch); - } - - if ('*' == ch) - { - read(&reader, ch); - param.width = va_arg(_argList, int32_t); - - if (0 > param.width) - { - param.left = true; - param.width = -param.width; - } - - } - else - { - while (isNumeric(ch) ) - { - param.width = param.width * 10 + ch - '0'; - read(&reader, ch); - } - } - - if ('.' == ch) - { - read(&reader, ch); - - if ('*' == ch) - { - read(&reader, ch); - param.prec = va_arg(_argList, int32_t); - } - else - { - param.prec = 0; - while (isNumeric(ch) ) - { - param.prec = param.prec * 10 + ch - '0'; - read(&reader, ch); - } - } - } - - switch (toLower(ch) ) - { - case 'c': - size += write(_writer, char(va_arg(_argList, int32_t) ), _err); - break; - - case 's': - size += write(_writer, va_arg(_argList, const char*), param, _err); - break; - - case 'd': - param.base = 10; - size += write(_writer, va_arg(_argList, int32_t), param, _err); - break; - - case 'f': - size += write(_writer, va_arg(_argList, double), param, _err); - break; - - case 'p': - size += write(_writer, va_arg(_argList, void*), param, _err); - break; - - case 'x': - param.base = 16; - size += write(_writer, va_arg(_argList, uint32_t), param, _err); - break; - - case 'u': - param.base = 10; - size += write(_writer, va_arg(_argList, uint32_t), param, _err); - break; - - default: - size += write(_writer, ch, _err); - break; - } - } - else - { - size += write(_writer, ch, _err); - } - } - - size += write(_writer, '\0', _err); - - return size; - } - - int32_t write(WriterI* _writer, Error* _err, const char* _format, ...) - { - va_list argList; - va_start(argList, _format); - int32_t size = write(_writer, _format, argList, _err); - va_end(argList); - return size; - } - -} // namespace bx diff --git a/3rdparty/bx/src/crtimpl.cpp b/3rdparty/bx/src/crtimpl.cpp index 7adb74bb8ee..064b9f6e3ad 100644 --- a/3rdparty/bx/src/crtimpl.cpp +++ b/3rdparty/bx/src/crtimpl.cpp @@ -4,6 +4,7 @@ */ #include <bx/crtimpl.h> +#include <stdio.h> #if BX_CONFIG_ALLOCATOR_CRT # include <malloc.h> diff --git a/3rdparty/bx/src/crtnone.cpp b/3rdparty/bx/src/crtnone.cpp new file mode 100644 index 00000000000..0e88551b6f3 --- /dev/null +++ b/3rdparty/bx/src/crtnone.cpp @@ -0,0 +1,590 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include <bx/debug.h> +#include <bx/sort.h> +#include <bx/readerwriter.h> + +#if BX_CRT_NONE + +extern "C" void* memcpy(void* _dst, const void* _src, size_t _numBytes) +{ + bx::memCopy(_dst, _src, _numBytes); + return _dst; +} + +extern "C" void* memmove(void* _dst, const void* _src, size_t _numBytes) +{ + bx::memMove(_dst, _src, _numBytes); + return _dst; +} + +extern "C" void* memset(void* _dst, int _ch, size_t _numBytes) +{ + bx::memSet(_dst, uint8_t(_ch), _numBytes); + return _dst; +} + +#if !BX_PLATFORM_NONE + +typedef int64_t off64_t; +typedef int32_t pid_t; + +extern "C" int32_t memcmp(const void* _lhs, const void* _rhs, size_t _numBytes) +{ + return bx::memCmp(_lhs, _rhs, _numBytes); +} + +extern "C" size_t strlen(const char* _str) +{ + return bx::strnlen(_str); +} + +extern "C" size_t strnlen(const char* _str, size_t _max) +{ + return bx::strnlen(_str, _max); +} + +extern "C" void* strcpy(char* _dst, const char* _src) +{ + bx::strlncpy(_dst, INT32_MAX, _src, INT32_MAX); + return _dst; +} + +extern "C" void* strncpy(char* _dst, const char* _src, size_t _num) +{ + bx::strlncpy(_dst, INT32_MAX, _src, _num); + return _dst; +} + +extern "C" char* strcat(char* _dst, const char* _src) +{ + bx::strlncat(_dst, INT32_MAX, _src, INT32_MAX); + return _dst; +} + +extern "C" const char* strchr(const char* _str, int _ch) +{ + return bx::strnchr(_str, _ch); +} + +extern "C" int32_t strcmp(const char* _lhs, const char* _rhs) +{ + return bx::strncmp(_lhs, _rhs); +} + +extern "C" int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max) +{ + return bx::strncmp(_lhs, _rhs, _max); +} + +extern "C" const char* strstr(const char* _str, const char* _find) +{ + return bx::strnstr(_str, _find); +} + +extern "C" void qsort(void* _base, size_t _num, size_t _size, bx::ComparisonFn _fn) +{ + BX_CHECK(_num <= UINT32_MAX && _size <= UINT32_MAX, ""); + return bx::quickSort(_base, _num, _size, _fn); +} + +extern "C" int isprint(int _ch) +{ + return bx::isPrint(_ch); +} + +extern "C" int toupper (int _ch) +{ + return bx::toUpper(_ch); +} + +extern "C" size_t mbstowcs(wchar_t* _dst, const char* _src, size_t _max) +{ + BX_UNUSED(_dst, _src, _max); + return 0; +} + +extern "C" char* strdup(const char* _src) +{ + BX_UNUSED(_src); + return NULL; +} + +extern "C" long int strtol(const char* _str, char** _end, int _base) +{ + BX_UNUSED(_str, _end, _base); + return -1; +} + +extern "C" int abs(int _value) +{ + return _value >= 0 ? _value : -_value; +} + +extern "C" float fabsf(float _value) +{ + return _value >= 0.0f ? _value : -_value; +} + +extern "C" double fabs(double _value) +{ + return _value >= 0.0 ? _value : -_value; +} + +extern "C" double ldexp(double _x, int _exp) +{ + BX_UNUSED(_x, _exp); + return 0.0; +} + +extern "C" float expf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float logf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float log10f(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float powf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" double pow(double _x) +{ + BX_UNUSED(_x); + return 0.0; +} + +extern "C" float sinf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float cosf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float tanf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float atan2f(float _y, float _x) +{ + BX_UNUSED(_y, _x); + return 0.0f; +} + +extern "C" float sqrtf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" double sqrt(double _x) +{ + BX_UNUSED(_x); + return 0.0; +} + +extern "C" float ceilf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" double ceil(double _x) +{ + BX_UNUSED(_x); + return 0.0; +} + +extern "C" float floorf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" double floor(double _x) +{ + BX_UNUSED(_x); + return 0.0; +} + +extern "C" float acosf(float _x) +{ + BX_UNUSED(_x); + return 0.0f; +} + +extern "C" float fmodf(float _numer, float _denom) +{ + BX_UNUSED(_numer, _denom); + return 0.0f; +} + +extern "C" int atoi(const char* _str) +{ + BX_UNUSED(_str); + return 0; +} + +extern "C" double atof(const char* _str) +{ + BX_UNUSED(_str); + return 0.0; +} + +extern "C" struct DIR* opendir(const char* dirname) +{ + BX_UNUSED(dirname); + return NULL; +} + +extern "C" struct dirent* readdir(struct DIR* dirp) +{ + BX_UNUSED(dirp); + return NULL; +} + +extern "C" int closedir (struct DIR* dirp) +{ + BX_UNUSED(dirp); + return 0; +} + +extern "C" int vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList) +{ + return bx::vsnprintf(_out, _max, _format, _argList); +} + +extern "C" int sprintf(char* _out, const char* _format, ...) +{ + va_list argList; + va_start(argList, _format); + int32_t len = bx::vsnprintf(_out, INT32_MAX, _format, argList); + va_end(argList); + return len; +} + +extern "C" int snprintf(char* _out, size_t _max, const char* _format, ...) +{ + va_list argList; + va_start(argList, _format); + int32_t len = bx::vsnprintf(_out, _max, _format, argList); + va_end(argList); + return len; +} + +extern "C" int printf(const char* _format, ...) +{ + BX_UNUSED(_format); + return -1; +} + +extern "C" int fprintf(FILE* _stream, const char* _format, ...) +{ + BX_UNUSED(_stream, _format); + return -1; +} + +extern "C" int vfprintf(FILE* _stream, const char* _format, va_list _argList) +{ + BX_UNUSED(_stream, _format, _argList); + return -1; +} + +extern "C" int sscanf(const char* _str, const char* _format, ...) +{ + BX_UNUSED(_str, _format); + return -1; +} + +extern "C" int fscanf(FILE* _stream, const char* _format, ...) +{ + BX_UNUSED(_stream, _format); + return -1; +} + +FILE * stdout; + +extern "C" FILE* fopen(const char* _filename, const char* _mode) +{ + BX_UNUSED(_filename, _mode); + return NULL; +} + +extern "C" int fclose(FILE* _stream) +{ + BX_UNUSED(_stream); + return -1; +} + +extern "C" size_t fread(void* _ptr, size_t _size, size_t _count, FILE* _stream) +{ + BX_UNUSED(_ptr, _size, _count, _stream); + return -1; +} + +extern "C" size_t fwrite(const void* _ptr, size_t _size, size_t _count, FILE* _stream) +{ + BX_UNUSED(_ptr, _size, _count, _stream); + return -1; +} + +extern "C" int fseek(FILE* _stream, long int _offset, int _origin) +{ + BX_UNUSED(_stream, _offset, _origin); + return -1; +} + +extern "C" int fseeko64(FILE* _stream, off64_t _offset, int _whence) +{ + BX_UNUSED(_stream, _offset, _whence); + return -1; +} + +extern "C" long int ftell(FILE* _stream) +{ + BX_UNUSED(_stream); + return -1; +} + +extern "C" off64_t ftello64(FILE* _stream) +{ + BX_UNUSED(_stream); + return -1; +} + +extern "C" int feof(FILE* _stream) +{ + BX_UNUSED(_stream); + return -1; +} + +extern "C" int ferror(FILE* _stream) +{ + BX_UNUSED(_stream); + return -1; +} + +extern "C" FILE* popen(const char* _command, const char* _type) +{ + BX_UNUSED(_command, _type); + return NULL; +} + +extern "C" int pclose(FILE* _stream) +{ + BX_UNUSED(_stream); + return -1; +} + +extern "C" int execvp(const char* _file, char* const _argv[]) +{ + BX_UNUSED(_file, _argv); + return -1; +} + +extern "C" long syscall(long _num, ...) +{ + BX_UNUSED(_num); + return -1; +} + +extern "C" long sysconf(int name) +{ + BX_UNUSED(name); + return -1; +} + +extern "C" pid_t fork() +{ + return -1; +} + +extern "C" int sched_yield() +{ + return -1; +} + +extern "C" int prctl(int _option, unsigned long _arg2, unsigned long _arg3, unsigned long _arg4, unsigned long _arg5) +{ + BX_UNUSED(_option, _arg2, _arg3, _arg4, _arg5); + return -1; +} + +extern "C" int chdir(const char* _path) +{ + BX_UNUSED(_path); + return -1; +} + +extern "C" char* getcwd(char* _buf, size_t _size) +{ + BX_UNUSED(_buf, _size); + return NULL; +} + +extern "C" char* getenv(const char* _name) +{ + BX_UNUSED(_name); + return NULL; +} + +extern "C" int setenv(const char* _name, const char* _value, int _overwrite) +{ + BX_UNUSED(_name, _value, _overwrite); + return -1; +} + +extern "C" int unsetenv(const char* _name) +{ + BX_UNUSED(_name); + return -1; +} + +extern "C" time_t time(time_t* _arg) +{ + BX_UNUSED(_arg); + return -1; +} + +extern "C" int gettimeofday(struct timeval* _tv, struct timezone* _tz) +{ + BX_UNUSED(_tv, _tz); + return -1; +} + +extern "C" void* realloc(void* _ptr, size_t _size) +{ + BX_UNUSED(_ptr, _size); + return NULL; +} + +extern "C" void* malloc(size_t _size) +{ + return ::realloc(NULL, _size); +} + +extern "C" void free(void* _ptr) +{ + BX_UNUSED(_ptr); +} + +#endif // BX_PLATFORM_* + +extern "C" void abort() +{ + while (true) {}; +} + +extern "C" void __assert_fail(const char* _assertion, const char* _file, uint32_t _line, const char* _function) +{ + BX_UNUSED(_assertion, _file, _line, _function); + abort(); +} + +void* __dso_handle = (void*)&__dso_handle; + +void operator delete(void*) +{ +} + +extern "C" void __cxa_pure_virtual() +{ +} + +extern "C" int __cxa_atexit(void (*_dtorFn)(void*), void* _arg, void* _dsoHandle) +{ + BX_UNUSED(_dtorFn, _arg, _dsoHandle); + return 0; +} + +extern "C" void __gxx_personality_v0() +{ +} + +extern "C" void _Unwind_Resume(void*) +{ +} + +extern "C" int __gcc_personality_v0(int _version, ...) +{ + BX_UNUSED(_version); + return 0; +} + +namespace __cxxabiv1 +{ + class __class_type_info + { + public: + virtual ~__class_type_info(); + + const char* m_name; + }; + + __class_type_info::~__class_type_info() + { + } + + class __si_class_type_info : public __class_type_info + { + public: + virtual ~__si_class_type_info(); + }; + + __si_class_type_info::~__si_class_type_info() + { + } + + class __vmi_class_type_info : public __class_type_info + { + public: + virtual ~__vmi_class_type_info(); + }; + + __vmi_class_type_info::~__vmi_class_type_info() + { + } + + __extension__ typedef int __guard __attribute__( (mode(__DI__) ) ); + + extern "C" int __cxa_guard_acquire (__guard* _g) + { + return !*(char*)(_g); + } + + extern "C" void __cxa_guard_release (__guard* _g) + { + *(char*)_g = 1; + } + + extern "C" void __cxa_guard_abort (__guard* _g) + { + BX_UNUSED(_g); + } + +} // namespace __cxxabiv1 + +#endif // BX_CRT_NONE diff --git a/3rdparty/bx/src/debug.cpp b/3rdparty/bx/src/debug.cpp index 550eef6e5f6..5e52be86e88 100644 --- a/3rdparty/bx/src/debug.cpp +++ b/3rdparty/bx/src/debug.cpp @@ -60,9 +60,11 @@ namespace bx # endif // defined(__OBJC__) #elif 0 // BX_PLATFORM_EMSCRIPTEN emscripten_log(EM_LOG_CONSOLE, "%s", _out); -#else +#elif !BX_CRT_NONE fputs(_out, stdout); fflush(stdout); +#else + BX_UNUSED(_out); #endif // BX_PLATFORM_ } diff --git a/3rdparty/bx/src/dtoa.cpp b/3rdparty/bx/src/dtoa.cpp index 05ac387fec2..98640ede20b 100644 --- a/3rdparty/bx/src/dtoa.cpp +++ b/3rdparty/bx/src/dtoa.cpp @@ -8,6 +8,8 @@ #include <bx/string.h> #include <bx/uint32_t.h> +#include <type_traits> + namespace bx { // https://github.com/miloyip/dtoa-benchmark @@ -384,7 +386,7 @@ namespace bx if (0 < kk && kk <= 21) { // 1234e-2 -> 12.34 - memmove(&buffer[kk + 1], &buffer[kk], length - kk); + memMove(&buffer[kk + 1], &buffer[kk], length - kk); buffer[kk] = '.'; buffer[length + 1] = '\0'; return length + 1; @@ -394,7 +396,7 @@ namespace bx { // 1234e-6 -> 0.001234 const int32_t offset = 2 - kk; - memmove(&buffer[offset], &buffer[0], length); + memMove(&buffer[offset], &buffer[0], length); buffer[0] = '0'; buffer[1] = '.'; for (int32_t i = 2; i < offset; i++) @@ -415,56 +417,57 @@ namespace bx } // 1234e30 -> 1.234e33 - memmove(&buffer[2], &buffer[1], length - 1); + memMove(&buffer[2], &buffer[1], length - 1); buffer[1] = '.'; buffer[length + 1] = 'e'; int32_t exp = WriteExponent(kk - 1, &buffer[length + 2]); return length + 2 + exp; } - int32_t toString(char* _dst, size_t _max, double value) + int32_t toString(char* _dst, int32_t _max, double _value) { - if (isNan(value) ) + int32_t sign = 0 != (doubleToBits(_value) & (UINT64_C(1)<<63) ) ? 1 : 0; + if (1 == sign) { - return (int32_t)strlncpy(_dst, _max, "NaN"); + *_dst++ = '-'; + --_max; + _value = -_value; } - else if (isInfinite(value) ) + + if (isNan(_value) ) { - return (int32_t)strlncpy(_dst, _max, "Inf"); + return (int32_t)strlncpy(_dst, _max, "nan") + sign; } - - int32_t sign = 0.0 > value ? 1 : 0; - if (1 == sign) + else if (isInfinite(_value) ) { - *_dst++ = '-'; - --_max; - value = -value; + return (int32_t)strlncpy(_dst, _max, "inf") + sign; } int32_t len; - if (0.0 == value) + if (0.0 == _value) { len = (int32_t)strlncpy(_dst, _max, "0.0"); } else { int32_t kk; - Grisu2(value, _dst, &len, &kk); + Grisu2(_value, _dst, &len, &kk); len = Prettify(_dst, len, kk); } return len + sign; } - static void reverse(char* _dst, size_t _len) + static void reverse(char* _dst, int32_t _len) { - for (size_t ii = 0, jj = _len - 1; ii < jj; ++ii, --jj) + for (int32_t ii = 0, jj = _len - 1; ii < jj; ++ii, --jj) { xchg(_dst[ii], _dst[jj]); } } - int32_t toString(char* _dst, size_t _max, int32_t _value, uint32_t _base) + template<typename Ty> + int32_t toStringSigned(char* _dst, int32_t _max, Ty _value, uint32_t _base) { if (_base == 10 && _value < 0) @@ -474,7 +477,11 @@ namespace bx return 0; } - _max = toString(_dst + 1, _max - 1, uint32_t(-_value), _base); + _max = toString(_dst + 1 + , _max - 1 + , typename std::make_unsigned<Ty>::type(-_value) + , _base + ); if (_max == 0) { return 0; @@ -484,13 +491,28 @@ namespace bx return int32_t(_max + 1); } - return toString(_dst, _max, uint32_t(_value), _base); + return toString(_dst + , _max + , typename std::make_unsigned<Ty>::type(_value) + , _base + ); } - int32_t toString(char* _dst, size_t _max, uint32_t _value, uint32_t _base) + int32_t toString(char* _dst, int32_t _max, int32_t _value, uint32_t _base) + { + return toStringSigned(_dst, _max, _value, _base); + } + + int32_t toString(char* _dst, int32_t _max, int64_t _value, uint32_t _base) + { + return toStringSigned(_dst, _max, _value, _base); + } + + template<typename Ty> + int32_t toStringUnsigned(char* _dst, int32_t _max, Ty _value, uint32_t _base) { char data[32]; - size_t len = 0; + int32_t len = 0; if (_base > 16 || _base < 2) @@ -500,7 +522,7 @@ namespace bx do { - const uint32_t rem = _value % _base; + const Ty rem = _value % _base; _value /= _base; if (rem < 10) { @@ -520,9 +542,19 @@ namespace bx reverse(data, len); - memcpy(_dst, data, len); + memCopy(_dst, data, len); _dst[len] = '\0'; return int32_t(len); } + int32_t toString(char* _dst, int32_t _max, uint32_t _value, uint32_t _base) + { + return toStringUnsigned(_dst, _max, _value, _base); + } + + int32_t toString(char* _dst, int32_t _max, uint64_t _value, uint32_t _base) + { + return toStringUnsigned(_dst, _max, _value, _base); + } + } // namespace bx diff --git a/3rdparty/bx/src/fpumath.cpp b/3rdparty/bx/src/fpumath.cpp index da463e08767..e957ef9e960 100644 --- a/3rdparty/bx/src/fpumath.cpp +++ b/3rdparty/bx/src/fpumath.cpp @@ -4,6 +4,7 @@ */ #include <bx/fpumath.h> +#include <math.h> namespace bx { @@ -17,7 +18,72 @@ namespace bx const float huge = HUGE_VALF; #endif // BX_COMPILER_MSVC - void mtx3Inverse(float* __restrict _result, const float* __restrict _a) + float fabsolute(float _a) + { + return ::fabsf(_a); + } + + float fsin(float _a) + { + return ::sinf(_a); + } + + float fasin(float _a) + { + return ::asinf(_a); + } + + float fcos(float _a) + { + return ::cosf(_a); + } + + float ftan(float _a) + { + return ::tanf(_a); + } + + float facos(float _a) + { + return ::acosf(_a); + } + + float fatan2(float _y, float _x) + { + return ::atan2f(_y, _x); + } + + float fpow(float _a, float _b) + { + return ::powf(_a, _b); + } + + float flog(float _a) + { + return ::logf(_a); + } + + float fsqrt(float _a) + { + return ::sqrtf(_a); + } + + float ffloor(float _f) + { + return ::floorf(_f); + } + + float fceil(float _f) + { + return ::ceilf(_f); + } + + float fmod(float _a, float _b) + { + return ::fmodf(_a, _b); + } + + void mtx3Inverse(float* _result, const float* _a) { float xx = _a[0]; float xy = _a[1]; @@ -49,7 +115,7 @@ namespace bx _result[8] = +(xx*yy - xy*yx) * invDet; } - void mtxInverse(float* __restrict _result, const float* __restrict _a) + void mtxInverse(float* _result, const float* _a) { float xx = _a[ 0]; float xy = _a[ 1]; diff --git a/3rdparty/bx/src/mutex.cpp b/3rdparty/bx/src/mutex.cpp index 00e517684e2..988084bbf0b 100644 --- a/3rdparty/bx/src/mutex.cpp +++ b/3rdparty/bx/src/mutex.cpp @@ -7,17 +7,19 @@ #if BX_CONFIG_SUPPORTS_THREADING -#if 0 \ - || BX_PLATFORM_ANDROID \ - || BX_PLATFORM_LINUX \ - || BX_PLATFORM_NACL \ - || BX_PLATFORM_IOS \ - || BX_PLATFORM_OSX +#if BX_PLATFORM_ANDROID \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_RPI # include <pthread.h> -#elif 0 \ - || BX_PLATFORM_WINDOWS \ - || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOX360 +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE +# include <windows.h> # include <errno.h> #endif // BX_PLATFORM_ @@ -50,7 +52,7 @@ namespace bx InitializeCriticalSectionEx(_mutex, 4000, 0); // docs recommend 4000 spincount as sane default #else InitializeCriticalSection(_mutex); -#endif +#endif // BX_PLATFORM_ return 0; } @@ -63,28 +65,36 @@ namespace bx Mutex::Mutex() { + BX_STATIC_ASSERT(sizeof(pthread_mutex_t) <= sizeof(m_internal) ); + pthread_mutexattr_t attr; + #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT #else pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_WINRT - pthread_mutex_init(&m_handle, &attr); +#endif // BX_PLATFORM_ + + pthread_mutex_t* handle = (pthread_mutex_t*)m_internal; + pthread_mutex_init(handle, &attr); } Mutex::~Mutex() { - pthread_mutex_destroy(&m_handle); + pthread_mutex_t* handle = (pthread_mutex_t*)m_internal; + pthread_mutex_destroy(handle); } void Mutex::lock() { - pthread_mutex_lock(&m_handle); + pthread_mutex_t* handle = (pthread_mutex_t*)m_internal; + pthread_mutex_lock(handle); } void Mutex::unlock() { - pthread_mutex_unlock(&m_handle); + pthread_mutex_t* handle = (pthread_mutex_t*)m_internal; + pthread_mutex_unlock(handle); } } // namespace bx diff --git a/3rdparty/bx/src/os.cpp b/3rdparty/bx/src/os.cpp index 5f1d45945b7..0c7e9dc9a8e 100644 --- a/3rdparty/bx/src/os.cpp +++ b/3rdparty/bx/src/os.cpp @@ -7,7 +7,10 @@ #include <bx/uint32_t.h> #include <bx/string.h> +#if !BX_PLATFORM_NONE + #include <stdio.h> +#include <sys/stat.h> #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT # include <windows.h> @@ -237,7 +240,7 @@ namespace bx result = len != 0 && len < *_inOutSize; if (len < *_inOutSize) { - strcpy(_out, ptr); + strlncpy(_out, len, ptr); } } @@ -406,11 +409,11 @@ namespace bx return (void*)uintptr_t(pid); #elif BX_PLATFORM_WINDOWS STARTUPINFO si; - memset(&si, 0, sizeof(STARTUPINFO) ); + memSet(&si, 0, sizeof(STARTUPINFO) ); si.cb = sizeof(STARTUPINFO); PROCESS_INFORMATION pi; - memset(&pi, 0, sizeof(PROCESS_INFORMATION) ); + memSet(&pi, 0, sizeof(PROCESS_INFORMATION) ); int32_t total = 0; for (uint32_t ii = 0; NULL != _argv[ii]; ++ii) @@ -452,3 +455,5 @@ namespace bx } } // namespace bx + +#endif // !BX_PLATFORM_NONE diff --git a/3rdparty/bx/src/sem.cpp b/3rdparty/bx/src/semaphore.cpp index 2d3ca1574f8..b4369ff0ce6 100644 --- a/3rdparty/bx/src/sem.cpp +++ b/3rdparty/bx/src/semaphore.cpp @@ -3,35 +3,69 @@ * License: https://github.com/bkaradzic/bx#license-bsd-2-clause */ -#include <bx/sem.h> +#include <bx/semaphore.h> #if BX_CONFIG_SUPPORTS_THREADING #if BX_PLATFORM_POSIX # include <errno.h> +# include <pthread.h> # include <semaphore.h> # include <time.h> -# include <pthread.h> -#elif BX_PLATFORM_XBOXONE -# include <synchapi.h> -#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE # include <windows.h> # include <limits.h> +# if BX_PLATFORM_XBOXONE +# include <synchapi.h> +# endif // BX_PLATFORM_XBOXONE #endif // BX_PLATFORM_ +#ifndef BX_CONFIG_SEMAPHORE_PTHREAD +# define BX_CONFIG_SEMAPHORE_PTHREAD (0 \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_IOS \ + ) +#endif // BX_CONFIG_SEMAPHORE_PTHREAD + namespace bx { + struct SemaphoreInternal + { +#if BX_PLATFORM_POSIX +# if BX_CONFIG_SEMAPHORE_PTHREAD + pthread_mutex_t m_mutex; + pthread_cond_t m_cond; + int32_t m_count; +# else + sem_t m_handle; +# endif // BX_CONFIG_SEMAPHORE_PTHREAD +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE + HANDLE m_handle; +#endif // BX_PLATFORM_ + }; + #if BX_PLATFORM_POSIX # if BX_CONFIG_SEMAPHORE_PTHREAD Semaphore::Semaphore() - : m_count(0) { + BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); + + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + si->m_count = 0; + int result; - result = pthread_mutex_init(&m_mutex, NULL); + + result = pthread_mutex_init(&si->m_mutex, NULL); BX_CHECK(0 == result, "pthread_mutex_init %d", result); - result = pthread_cond_init(&m_cond, NULL); + result = pthread_cond_init(&si->m_cond, NULL); BX_CHECK(0 == result, "pthread_cond_init %d", result); BX_UNUSED(result); @@ -39,11 +73,13 @@ namespace bx Semaphore::~Semaphore() { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + int result; - result = pthread_cond_destroy(&m_cond); + result = pthread_cond_destroy(&si->m_cond); BX_CHECK(0 == result, "pthread_cond_destroy %d", result); - result = pthread_mutex_destroy(&m_mutex); + result = pthread_mutex_destroy(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_destroy %d", result); BX_UNUSED(result); @@ -51,18 +87,20 @@ namespace bx void Semaphore::post(uint32_t _count) { - int result = pthread_mutex_lock(&m_mutex); + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + int result = pthread_mutex_lock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_lock %d", result); for (uint32_t ii = 0; ii < _count; ++ii) { - result = pthread_cond_signal(&m_cond); + result = pthread_cond_signal(&si->m_cond); BX_CHECK(0 == result, "pthread_cond_signal %d", result); } - m_count += _count; + si->m_count += _count; - result = pthread_mutex_unlock(&m_mutex); + result = pthread_mutex_unlock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_unlock %d", result); BX_UNUSED(result); @@ -70,24 +108,26 @@ namespace bx bool Semaphore::wait(int32_t _msecs) { - int result = pthread_mutex_lock(&m_mutex); + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + int result = pthread_mutex_lock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_lock %d", result); # if BX_PLATFORM_NACL || BX_PLATFORM_OSX BX_UNUSED(_msecs); BX_CHECK(-1 == _msecs, "NaCl and OSX don't support pthread_cond_timedwait at this moment."); while (0 == result - && 0 >= m_count) + && 0 >= si->m_count) { - result = pthread_cond_wait(&m_cond, &m_mutex); + result = pthread_cond_wait(&si->m_cond, &si->m_mutex); } # elif BX_PLATFORM_IOS if (-1 == _msecs) { while (0 == result - && 0 >= m_count) + && 0 >= si->m_count) { - result = pthread_cond_wait(&m_cond, &m_mutex); + result = pthread_cond_wait(&si->m_cond, &si->m_mutex); } } else @@ -97,9 +137,9 @@ namespace bx ts.tv_nsec = (_msecs%1000)*1000; while (0 == result - && 0 >= m_count) + && 0 >= si->m_count) { - result = pthread_cond_timedwait_relative_np(&m_cond, &m_mutex, &ts); + result = pthread_cond_timedwait_relative_np(&si->m_cond, &si->m_mutex, &ts); } } # else @@ -109,19 +149,19 @@ namespace bx ts.tv_nsec += (_msecs%1000)*1000; while (0 == result - && 0 >= m_count) + && 0 >= si->m_count) { - result = pthread_cond_timedwait(&m_cond, &m_mutex, &ts); + result = pthread_cond_timedwait(&si->m_cond, &si->m_mutex, &ts); } -# endif // BX_PLATFORM_NACL || BX_PLATFORM_OSX +# endif // BX_PLATFORM_ bool ok = 0 == result; if (ok) { - --m_count; + --si->m_count; } - result = pthread_mutex_unlock(&m_mutex); + result = pthread_mutex_unlock(&si->m_mutex); BX_CHECK(0 == result, "pthread_mutex_unlock %d", result); BX_UNUSED(result); @@ -133,24 +173,32 @@ namespace bx Semaphore::Semaphore() { - int32_t result = sem_init(&m_handle, 0, 0); + BX_STATIC_ASSERT(sizeof(SemaphoreInternal) <= sizeof(m_internal) ); + + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + int32_t result = sem_init(&si->m_handle, 0, 0); BX_CHECK(0 == result, "sem_init failed. errno %d", errno); BX_UNUSED(result); } Semaphore::~Semaphore() { - int32_t result = sem_destroy(&m_handle); + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + int32_t result = sem_destroy(&si->m_handle); BX_CHECK(0 == result, "sem_destroy failed. errno %d", errno); BX_UNUSED(result); } void Semaphore::post(uint32_t _count) { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + int32_t result; for (uint32_t ii = 0; ii < _count; ++ii) { - result = sem_post(&m_handle); + result = sem_post(&si->m_handle); BX_CHECK(0 == result, "sem_post failed. errno %d", errno); } BX_UNUSED(result); @@ -158,16 +206,18 @@ namespace bx bool Semaphore::wait(int32_t _msecs) { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + # if BX_PLATFORM_NACL || BX_PLATFORM_OSX BX_CHECK(-1 == _msecs, "NaCl and OSX don't support sem_timedwait at this moment."); BX_UNUSED(_msecs); - return 0 == sem_wait(&m_handle); + return 0 == sem_wait(&si->m_handle); # else if (0 > _msecs) { int32_t result; do { - result = sem_wait(&m_handle); + result = sem_wait(&si->m_handle); } // keep waiting when interrupted by a signal handler... while (-1 == result && EINTR == errno); BX_CHECK(0 == result, "sem_wait failed. errno %d", errno); @@ -178,40 +228,51 @@ namespace bx clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += _msecs/1000; ts.tv_nsec += (_msecs%1000)*1000; - return 0 == sem_timedwait(&m_handle, &ts); + return 0 == sem_timedwait(&si->m_handle, &ts); # endif // BX_PLATFORM_ } # endif // BX_CONFIG_SEMAPHORE_PTHREAD -#elif BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE Semaphore::Semaphore() { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + #if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT - m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); + si->m_handle = CreateSemaphoreExW(NULL, 0, LONG_MAX, NULL, 0, SEMAPHORE_ALL_ACCESS); #else - m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL); + si->m_handle = CreateSemaphoreA(NULL, 0, LONG_MAX, NULL); #endif - BX_CHECK(NULL != m_handle, "Failed to create Semaphore!"); + BX_CHECK(NULL != si->m_handle, "Failed to create Semaphore!"); } Semaphore::~Semaphore() { - CloseHandle(m_handle); + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + CloseHandle(si->m_handle); } void Semaphore::post(uint32_t _count) { - ReleaseSemaphore(m_handle, _count, NULL); + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + + ReleaseSemaphore(si->m_handle, _count, NULL); } bool Semaphore::wait(int32_t _msecs) { + SemaphoreInternal* si = (SemaphoreInternal*)m_internal; + DWORD milliseconds = (0 > _msecs) ? INFINITE : _msecs; #if BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT - return WAIT_OBJECT_0 == WaitForSingleObjectEx(m_handle, milliseconds, FALSE); + return WAIT_OBJECT_0 == WaitForSingleObjectEx(si->m_handle, milliseconds, FALSE); #else - return WAIT_OBJECT_0 == WaitForSingleObject(m_handle, milliseconds); + return WAIT_OBJECT_0 == WaitForSingleObject(si->m_handle, milliseconds); #endif } #endif // BX_PLATFORM_ diff --git a/3rdparty/bx/src/sort.cpp b/3rdparty/bx/src/sort.cpp new file mode 100644 index 00000000000..3b7485fe7fe --- /dev/null +++ b/3rdparty/bx/src/sort.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include <bx/sort.h> + +namespace bx +{ + static void quickSortR(void* _pivot, void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn) + { + if (2 > _num) + { + return; + } + + memCopy(_pivot, _data, _stride); + + uint8_t* data = (uint8_t*)_data; + + uint32_t ll = 0; + uint32_t gg = 1; + + for (uint32_t ii = 1; ii < _num;) + { + int32_t result = _fn(&data[ii*_stride], _pivot); + if (0 > result) + { + xchg(&data[ll*_stride], &data[ii*_stride], _stride); + ++ll; + } + else if (0 == result) + { + xchg(&data[gg*_stride], &data[ii*_stride], _stride); + ++gg; + ++ii; + } + else + { + ++ii; + } + } + + quickSortR(_pivot, &data[0 ], ll, _stride, _fn); + quickSortR(_pivot, &data[gg*_stride], _num-gg, _stride, _fn); + } + + void quickSort(void* _data, uint32_t _num, uint32_t _stride, const ComparisonFn _fn) + { + uint8_t* pivot = (uint8_t*)alloca(_stride); + quickSortR(pivot, _data, _num, _stride, _fn); + } + +} // namespace bx + diff --git a/3rdparty/bx/src/string.cpp b/3rdparty/bx/src/string.cpp index c53a9de1155..dbb59e5090a 100644 --- a/3rdparty/bx/src/string.cpp +++ b/3rdparty/bx/src/string.cpp @@ -60,21 +60,57 @@ namespace bx return _ch + (isUpper(_ch) ? 0x20 : 0); } + void toLowerUnsafe(char* _inOutStr, int32_t _len) + { + for (int32_t ii = 0; ii < _len; ++ii) + { + *_inOutStr = toLower(*_inOutStr); + } + } + + void toLower(char* _inOutStr, int32_t _max) + { + const int32_t len = strnlen(_inOutStr, _max); + toLowerUnsafe(_inOutStr, len); + } + char toUpper(char _ch) { return _ch - (isLower(_ch) ? 0x20 : 0); } + void toUpperUnsafe(char* _inOutStr, int32_t _len) + { + for (int32_t ii = 0; ii < _len; ++ii) + { + *_inOutStr = toUpper(*_inOutStr); + } + } + + void toUpper(char* _inOutStr, int32_t _max) + { + const int32_t len = strnlen(_inOutStr, _max); + toUpperUnsafe(_inOutStr, len); + } + bool toBool(const char* _str) { char ch = toLower(_str[0]); return ch == 't' || ch == '1'; } - int32_t strncmp(const char* _lhs, const char* _rhs, size_t _max) + typedef char (*CharFn)(char _ch); + + inline char toNoop(char _ch) + { + return _ch; + } + + template<CharFn fn> + int32_t strCmp(const char* _lhs, const char* _rhs, int32_t _max) { for ( - ; 0 < _max && *_lhs == *_rhs + ; 0 < _max && fn(*_lhs) == fn(*_rhs) ; ++_lhs, ++_rhs, --_max ) { @@ -85,62 +121,60 @@ namespace bx } } - return 0 == _max ? 0 : *_lhs - *_rhs; + return 0 == _max ? 0 : fn(*_lhs) - fn(*_rhs); } - int32_t strincmp(const char* _lhs, const char* _rhs, size_t _max) + int32_t strncmp(const char* _lhs, const char* _rhs, int32_t _max) { - for ( - ; 0 < _max && toLower(*_lhs) == toLower(*_rhs) - ; ++_lhs, ++_rhs, --_max - ) - { - if (*_lhs == '\0' - || *_rhs == '\0') - { - break; - } - } + return strCmp<toNoop>(_lhs, _rhs, _max); + } - return 0 == _max ? 0 : *_lhs - *_rhs; + int32_t strincmp(const char* _lhs, const char* _rhs, int32_t _max) + { + return strCmp<toLower>(_lhs, _rhs, _max); } - size_t strnlen(const char* _str, size_t _max) + int32_t strnlen(const char* _str, int32_t _max) { - const char* ptr; - for (ptr = _str; 0 < _max && *ptr != '\0'; ++ptr, --_max) {}; - return ptr - _str; + if (NULL == _str) + { + return 0; + } + + const char* ptr = _str; + for (; 0 < _max && *ptr != '\0'; ++ptr, --_max) {}; + return int32_t(ptr - _str); } - size_t strlncpy(char* _dst, size_t _dstSize, const char* _src, size_t _num) + int32_t strlncpy(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) { BX_CHECK(NULL != _dst, "_dst can't be NULL!"); BX_CHECK(NULL != _src, "_src can't be NULL!"); BX_CHECK(0 < _dstSize, "_dstSize can't be 0!"); - const size_t len = strnlen(_src, _num); - const size_t max = _dstSize-1; - const size_t num = (len < max ? len : max); - memcpy(_dst, _src, num); + const int32_t len = strnlen(_src, _num); + const int32_t max = _dstSize-1; + const int32_t num = (len < max ? len : max); + memCopy(_dst, _src, num); _dst[num] = '\0'; return num; } - size_t strlncat(char* _dst, size_t _dstSize, const char* _src, size_t _num) + int32_t strlncat(char* _dst, int32_t _dstSize, const char* _src, int32_t _num) { BX_CHECK(NULL != _dst, "_dst can't be NULL!"); BX_CHECK(NULL != _src, "_src can't be NULL!"); BX_CHECK(0 < _dstSize, "_dstSize can't be 0!"); - const size_t max = _dstSize; - const size_t len = strnlen(_dst, max); + const int32_t max = _dstSize; + const int32_t len = strnlen(_dst, max); return strlncpy(&_dst[len], max-len, _src, _num); } - const char* strnchr(const char* _str, char _ch, size_t _max) + const char* strnchr(const char* _str, char _ch, int32_t _max) { - for (size_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii) + for (int32_t ii = 0, len = strnlen(_str, _max); ii < len; ++ii) { if (_str[ii] == _ch) { @@ -151,9 +185,9 @@ namespace bx return NULL; } - const char* strnrchr(const char* _str, char _ch, size_t _max) + const char* strnrchr(const char* _str, char _ch, int32_t _max) { - for (size_t ii = strnlen(_str, _max); 0 < ii; --ii) + for (int32_t ii = strnlen(_str, _max); 0 < ii; --ii) { if (_str[ii] == _ch) { @@ -164,17 +198,18 @@ namespace bx return NULL; } - const char* strnstr(const char* _str, const char* _find, size_t _max) + template<CharFn fn> + static const char* strStr(const char* _str, int32_t _strMax, const char* _find, int32_t _findMax) { const char* ptr = _str; - size_t stringLen = strnlen(_str, _max); - const size_t findLen = strnlen(_find); + int32_t stringLen = strnlen(_str, _strMax); + const int32_t findLen = strnlen(_find, _findMax); for (; stringLen >= findLen; ++ptr, --stringLen) { // Find start of the string. - while (*ptr != *_find) + while (fn(*ptr) != fn(*_find) ) { ++ptr; --stringLen; @@ -191,7 +226,7 @@ namespace bx const char* search = _find; // Start comparing. - while (*string++ == *search++) + while (fn(*string++) == fn(*search++) ) { // If end of the 'search' string is reached, all characters match. if ('\0' == *search) @@ -204,44 +239,14 @@ namespace bx return NULL; } - const char* stristr(const char* _str, const char* _find, size_t _max) + const char* strnstr(const char* _str, const char* _find, int32_t _max) { - const char* ptr = _str; - - size_t stringLen = strnlen(_str, _max); - const size_t findLen = strnlen(_find); - - for (; stringLen >= findLen; ++ptr, --stringLen) - { - // Find start of the string. - while (toLower(*ptr) != toLower(*_find) ) - { - ++ptr; - --stringLen; - - // Search pattern lenght can't be longer than the string. - if (findLen > stringLen) - { - return NULL; - } - } - - // Set pointers. - const char* string = ptr; - const char* search = _find; - - // Start comparing. - while (toLower(*string++) == toLower(*search++) ) - { - // If end of the 'search' string is reached, all characters match. - if ('\0' == *search) - { - return ptr; - } - } - } + return strStr<toNoop>(_str, _max, _find, INT32_MAX); + } - return NULL; + const char* stristr(const char* _str, const char* _find, int32_t _max) + { + return strStr<toLower>(_str, _max, _find, INT32_MAX); } const char* strnl(const char* _str) @@ -324,7 +329,7 @@ namespace bx return NULL; } - void eolLF(char* _out, size_t _size, const char* _str) + void eolLF(char* _out, int32_t _size, const char* _str) { if (0 < _size) { @@ -343,7 +348,7 @@ namespace bx const char* findIdentifierMatch(const char* _str, const char* _word) { - size_t len = strnlen(_word); + int32_t len = strnlen(_word); const char* ptr = strnstr(_str, _word); for (; NULL != ptr; ptr = strnstr(ptr + len, _word) ) { @@ -382,13 +387,422 @@ namespace bx return NULL; } - int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err); + namespace + { + struct Param + { + Param() + : width(0) + , base(10) + , prec(6) + , fill(' ') + , bits(0) + , left(false) + , upper(false) + , spec(false) + , sign(false) + { + } + + int32_t width; + uint32_t base; + uint32_t prec; + char fill; + uint8_t bits; + bool left; + bool upper; + bool spec; + bool sign; + }; + + static int32_t write(WriterI* _writer, const char* _str, int32_t _len, const Param& _param, Error* _err) + { + int32_t size = 0; + int32_t len = (int32_t)strnlen(_str, _len); + int32_t padding = _param.width > len ? _param.width - len : 0; + bool sign = _param.sign && len > 1 && _str[0] != '-'; + padding = padding > 0 ? padding - sign : 0; + + if (!_param.left) + { + size += writeRep(_writer, _param.fill, padding, _err); + } + + if (NULL == _str) + { + size += write(_writer, "(null)", 6, _err); + } + else if (_param.upper) + { + for (int32_t ii = 0; ii < len; ++ii) + { + size += write(_writer, toUpper(_str[ii]), _err); + } + } + else if (sign) + { + size += write(_writer, '+', _err); + size += write(_writer, _str, len, _err); + } + else + { + size += write(_writer, _str, len, _err); + } + + if (_param.left) + { + size += writeRep(_writer, _param.fill, padding, _err); + } + + return size; + } + + static int32_t write(WriterI* _writer, char _ch, const Param& _param, Error* _err) + { + return write(_writer, &_ch, 1, _param, _err); + } + + static int32_t write(WriterI* _writer, const char* _str, const Param& _param, Error* _err) + { + return write(_writer, _str, INT32_MAX, _param, _err); + } + + static int32_t write(WriterI* _writer, int32_t _i, const Param& _param, Error* _err) + { + char str[33]; + int32_t len = toString(str, sizeof(str), _i, _param.base); + + if (len == 0) + { + return 0; + } + + return write(_writer, str, len, _param, _err); + } + + static int32_t write(WriterI* _writer, int64_t _i, const Param& _param, Error* _err) + { + char str[33]; + int32_t len = toString(str, sizeof(str), _i, _param.base); + + if (len == 0) + { + return 0; + } + + return write(_writer, str, len, _param, _err); + } + + static int32_t write(WriterI* _writer, uint32_t _u, const Param& _param, Error* _err) + { + char str[33]; + int32_t len = toString(str, sizeof(str), _u, _param.base); + + if (len == 0) + { + return 0; + } + + return write(_writer, str, len, _param, _err); + } + + static int32_t write(WriterI* _writer, uint64_t _u, const Param& _param, Error* _err) + { + char str[33]; + int32_t len = toString(str, sizeof(str), _u, _param.base); + + if (len == 0) + { + return 0; + } + + return write(_writer, str, len, _param, _err); + } + + static int32_t write(WriterI* _writer, double _d, const Param& _param, Error* _err) + { + char str[1024]; + int32_t len = toString(str, sizeof(str), _d); + + if (len == 0) + { + return 0; + } + + if (_param.upper) + { + toUpperUnsafe(str, len); + } + + const char* dot = strnchr(str, '.'); + if (NULL != dot) + { + const int32_t precLen = int32_t( + dot + + uint32_min(_param.prec + _param.spec, 1) + + _param.prec + - str + ); + if (precLen > len) + { + for (int32_t ii = len; ii < precLen; ++ii) + { + str[ii] = '0'; + } + str[precLen] = '\0'; + } + len = precLen; + } + + return write(_writer, str, len, _param, _err); + } + + static int32_t write(WriterI* _writer, const void* _ptr, const Param& _param, Error* _err) + { + char str[35] = "0x"; + int32_t len = toString(str + 2, sizeof(str) - 2, uint32_t(uintptr_t(_ptr) ), 16); + + if (len == 0) + { + return 0; + } + + len += 2; + return write(_writer, str, len, _param, _err); + } + } // anonymous namespace + + int32_t write(WriterI* _writer, const char* _format, va_list _argList, Error* _err) + { + MemoryReader reader(_format, uint32_t(strnlen(_format) ) ); + + int32_t size = 0; + + while (_err->isOk() ) + { + char ch = '\0'; + + Error err; + read(&reader, ch, &err); + + if (!_err->isOk() + || !err.isOk() ) + { + break; + } + else if ('%' == ch) + { + // %[flags][width][.precision][length sub-specifier]specifier + read(&reader, ch); + + Param param; + + // flags + while (' ' == ch + || '-' == ch + || '+' == ch + || '0' == ch + || '#' == ch) + { + switch (ch) + { + default: + case ' ': param.fill = ' '; break; + case '-': param.left = true; break; + case '+': param.sign = true; break; + case '0': param.fill = '0'; break; + case '#': param.spec = true; break; + } + + read(&reader, ch); + } + + if (param.left) + { + param.fill = ' '; + } + + // width + if ('*' == ch) + { + read(&reader, ch); + param.width = va_arg(_argList, int32_t); + + if (0 > param.width) + { + param.left = true; + param.width = -param.width; + } + + } + else + { + while (isNumeric(ch) ) + { + param.width = param.width * 10 + ch - '0'; + read(&reader, ch); + } + } + + // .precision + if ('.' == ch) + { + read(&reader, ch); + + if ('*' == ch) + { + read(&reader, ch); + param.prec = va_arg(_argList, int32_t); + } + else + { + param.prec = 0; + while (isNumeric(ch) ) + { + param.prec = param.prec * 10 + ch - '0'; + read(&reader, ch); + } + } + } + + // length sub-specifier + while ('h' == ch + || 'I' == ch + || 'l' == ch + || 'j' == ch + || 't' == ch + || 'z' == ch) + { + switch (ch) + { + default: break; + + case 'j': param.bits = sizeof(intmax_t )*8; break; + case 't': param.bits = sizeof(size_t )*8; break; + case 'z': param.bits = sizeof(ptrdiff_t)*8; break; + + case 'h': case 'I': case 'l': + switch (ch) + { + case 'h': param.bits = sizeof(short int)*8; break; + case 'l': param.bits = sizeof(long int )*8; break; + default: break; + } + + read(&reader, ch); + switch (ch) + { + case 'h': param.bits = sizeof(signed char )*8; break; + case 'l': param.bits = sizeof(long long int)*8; break; + case '3': + case '6': + read(&reader, ch); + switch (ch) + { + case '2': param.bits = sizeof(int32_t)*8; break; + case '4': param.bits = sizeof(int64_t)*8; break; + default: break; + } + break; + + default: seek(&reader, -1); break; + } + break; + } + + read(&reader, ch); + } + + // specifier + switch (toLower(ch) ) + { + case 'c': + size += write(_writer, char(va_arg(_argList, int32_t) ), param, _err); + break; + + case 's': + size += write(_writer, va_arg(_argList, const char*), param, _err); + break; + + case 'o': + param.base = 8; + switch (param.bits) + { + default: size += write(_writer, va_arg(_argList, int32_t), param, _err); break; + case 64: size += write(_writer, va_arg(_argList, int64_t), param, _err); break; + } + break; + + case 'i': + case 'd': + param.base = 10; + switch (param.bits) + { + default: size += write(_writer, va_arg(_argList, int32_t), param, _err); break; + case 64: size += write(_writer, va_arg(_argList, int64_t), param, _err); break; + }; + break; + + case 'e': + case 'f': + case 'g': + param.upper = isUpper(ch); + size += write(_writer, va_arg(_argList, double), param, _err); + break; + + case 'p': + size += write(_writer, va_arg(_argList, void*), param, _err); + break; + + case 'x': + param.base = 16; + param.upper = isUpper(ch); + switch (param.bits) + { + default: size += write(_writer, va_arg(_argList, uint32_t), param, _err); break; + case 64: size += write(_writer, va_arg(_argList, uint64_t), param, _err); break; + } + break; + + case 'u': + param.base = 10; + switch (param.bits) + { + default: size += write(_writer, va_arg(_argList, uint32_t), param, _err); break; + case 64: size += write(_writer, va_arg(_argList, uint64_t), param, _err); break; + } + break; + + default: + size += write(_writer, ch, _err); + break; + } + } + else + { + size += write(_writer, ch, _err); + } + } + + size += write(_writer, '\0', _err); + + return size; + } + + int32_t write(WriterI* _writer, Error* _err, const char* _format, ...) + { + va_list argList; + va_start(argList, _format); + int32_t size = write(_writer, _format, argList, _err); + va_end(argList); + return size; + } - int32_t vsnprintfRef(char* _out, size_t _max, const char* _format, va_list _argList) + int32_t vsnprintfRef(char* _out, int32_t _max, const char* _format, va_list _argList) { if (1 < _max) { - StaticMemoryBlockWriter writer(_out, _max-1); + StaticMemoryBlockWriter writer(_out, uint32_t(_max-1) ); _out[_max-1] = '\0'; Error err; @@ -413,7 +827,7 @@ namespace bx return size - 1 /* size without '\0' terminator */; } - int32_t vsnprintf(char* _out, size_t _max, const char* _format, va_list _argList) + int32_t vsnprintf(char* _out, int32_t _max, const char* _format, va_list _argList) { #if BX_CRT_NONE return vsnprintfRef(_out, _max, _format, _argList); @@ -432,7 +846,7 @@ namespace bx #endif // BX_COMPILER_MSVC } - int32_t snprintf(char* _out, size_t _max, const char* _format, ...) + int32_t snprintf(char* _out, int32_t _max, const char* _format, ...) { va_list argList; va_start(argList, _format); @@ -441,7 +855,7 @@ namespace bx return len; } - int32_t vsnwprintf(wchar_t* _out, size_t _max, const wchar_t* _format, va_list _argList) + int32_t vsnwprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, va_list _argList) { #if BX_CRT_NONE BX_UNUSED(_out, _max, _format, _argList); @@ -463,7 +877,7 @@ namespace bx #endif // BX_COMPILER_MSVC } - int32_t swnprintf(wchar_t* _out, size_t _max, const wchar_t* _format, ...) + int32_t swnprintf(wchar_t* _out, int32_t _max, const wchar_t* _format, ...) { va_list argList; va_start(argList, _format); @@ -487,7 +901,7 @@ namespace bx return _filePath; } - void prettify(char* _out, size_t _count, uint64_t _size) + void prettify(char* _out, int32_t _count, uint64_t _size) { uint8_t idx = 0; double size = double(_size); @@ -502,12 +916,12 @@ namespace bx snprintf(_out, _count, "%0.2f %c%c", size, "BkMGTPEZY"[idx], idx > 0 ? 'B' : '\0'); } - size_t strlcpy(char* _dst, const char* _src, size_t _max) + int32_t strlcpy(char* _dst, const char* _src, int32_t _max) { return strlncpy(_dst, _max, _src); } - size_t strlcat(char* _dst, const char* _src, size_t _max) + int32_t strlcat(char* _dst, const char* _src, int32_t _max) { return strlncat(_dst, _max, _src); } diff --git a/3rdparty/bx/src/thread.cpp b/3rdparty/bx/src/thread.cpp index fea7e8b606c..70ea4a0ecbe 100644 --- a/3rdparty/bx/src/thread.cpp +++ b/3rdparty/bx/src/thread.cpp @@ -5,24 +5,94 @@ #include <bx/thread.h> +#if BX_PLATFORM_ANDROID \ + || BX_PLATFORM_LINUX \ + || BX_PLATFORM_NACL \ + || BX_PLATFORM_IOS \ + || BX_PLATFORM_OSX \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_RPI +# include <pthread.h> +# if defined(__FreeBSD__) +# include <pthread_np.h> +# endif +# if BX_PLATFORM_LINUX && (BX_CRT_GLIBC < 21200) +# include <sys/prctl.h> +# endif // BX_PLATFORM_ +#elif BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE +# include <windows.h> +# include <limits.h> +# include <errno.h> +# if BX_PLATFORM_WINRT +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::System::Threading; +# endif // BX_PLATFORM_WINRT +#endif // BX_PLATFORM_ + #if BX_CONFIG_SUPPORTS_THREADING namespace bx { - Thread::Thread() -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT - : m_handle(INVALID_HANDLE_VALUE) - , m_threadId(UINT32_MAX) + struct ThreadInternal + { +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE + static DWORD WINAPI threadFunc(LPVOID _arg); + HANDLE m_handle; + DWORD m_threadId; #elif BX_PLATFORM_POSIX - : m_handle(0) + static void* threadFunc(void* _arg); + pthread_t m_handle; +#endif // BX_PLATFORM_ + }; + +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT + DWORD WINAPI ThreadInternal::threadFunc(LPVOID _arg) + { + Thread* thread = (Thread*)_arg; + int32_t result = thread->entry(); + return result; + } +#else + void* ThreadInternal::threadFunc(void* _arg) + { + Thread* thread = (Thread*)_arg; + union + { + void* ptr; + int32_t i; + } cast; + cast.i = thread->entry(); + return cast.ptr; + } #endif // BX_PLATFORM_ - , m_fn(NULL) + + Thread::Thread() + : m_fn(NULL) , m_userData(NULL) , m_stackSize(0) , m_exitCode(0 /*EXIT_SUCCESS*/) , m_running(false) - { - } + { + BX_STATIC_ASSERT(sizeof(ThreadInternal) <= sizeof(m_internal) ); + + ThreadInternal* ti = (ThreadInternal*)m_internal; +#if BX_PLATFORM_WINDOWS \ + || BX_PLATFORM_WINRT \ + || BX_PLATFORM_XBOX360 \ + || BX_PLATFORM_XBOXONE + ti->m_handle = INVALID_HANDLE_VALUE; + ti->m_threadId = UINT32_MAX; +#elif BX_PLATFORM_POSIX + ti->m_handle = 0; +#endif // BX_PLATFORM_ + } Thread::~Thread() { @@ -41,21 +111,24 @@ namespace bx m_stackSize = _stackSize; m_running = true; + ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE - m_handle = ::CreateThread(NULL + ti->m_handle = ::CreateThread(NULL , m_stackSize - , (LPTHREAD_START_ROUTINE)threadFunc + , (LPTHREAD_START_ROUTINE)ti->threadFunc , this , 0 , NULL ); #elif BX_PLATFORM_WINRT - m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + ti->m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^) - { - m_exitCode = threadFunc(this); - SetEvent(m_handle); - }, CallbackContext::Any); + { + m_exitCode = ti->threadFunc(this); + SetEvent(ti->m_handle); + } + , CallbackContext::Any + ); ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced); #elif BX_PLATFORM_POSIX @@ -72,12 +145,7 @@ namespace bx BX_CHECK(0 == result, "pthread_attr_setstacksize failed! %d", result); } - // sched_param sched; - // sched.sched_priority = 0; - // result = pthread_attr_setschedparam(&attr, &sched); - // BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result); - - result = pthread_create(&m_handle, &attr, &threadFunc, this); + result = pthread_create(&ti->m_handle, &attr, &ti->threadFunc, this); BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result); #else # error "Not implemented!" @@ -94,25 +162,27 @@ namespace bx void Thread::shutdown() { BX_CHECK(m_running, "Not running!"); + ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 - WaitForSingleObject(m_handle, INFINITE); - GetExitCodeThread(m_handle, (DWORD*)&m_exitCode); - CloseHandle(m_handle); - m_handle = INVALID_HANDLE_VALUE; -#elif BX_PLATFORM_WINRT - WaitForSingleObjectEx(m_handle, INFINITE, FALSE); - CloseHandle(m_handle); - m_handle = INVALID_HANDLE_VALUE; + WaitForSingleObject(ti->m_handle, INFINITE); + GetExitCodeThread(ti->m_handle, (DWORD*)&m_exitCode); + CloseHandle(ti->m_handle); + ti->m_handle = INVALID_HANDLE_VALUE; +#elif BX_PLATFORM_WINRT || BX_PLATFORM_XBOXONE + WaitForSingleObjectEx(ti->m_handle, INFINITE, FALSE); + CloseHandle(ti->m_handle); + ti->m_handle = INVALID_HANDLE_VALUE; #elif BX_PLATFORM_POSIX union { void* ptr; int32_t i; } cast; - pthread_join(m_handle, &cast.ptr); + pthread_join(ti->m_handle, &cast.ptr); m_exitCode = cast.i; - m_handle = 0; + ti->m_handle = 0; #endif // BX_PLATFORM_ + m_running = false; } @@ -128,17 +198,19 @@ namespace bx void Thread::setThreadName(const char* _name) { + ThreadInternal* ti = (ThreadInternal*)m_internal; + BX_UNUSED(ti); #if BX_PLATFORM_OSX || BX_PLATFORM_IOS pthread_setname_np(_name); #elif (BX_CRT_GLIBC >= 21200) && ! BX_PLATFORM_HURD - pthread_setname_np(m_handle, _name); + pthread_setname_np(ti->m_handle, _name); #elif BX_PLATFORM_LINUX prctl(PR_SET_NAME,_name, 0, 0, 0); #elif BX_PLATFORM_BSD # ifdef __NetBSD__ - pthread_setname_np(m_handle, "%s", (void*)_name); + pthread_setname_np(ti->m_handle, "%s", (void*)_name); # else - pthread_set_name_np(m_handle, _name); + pthread_set_name_np(ti->m_handle, _name); # endif // __NetBSD__ #elif BX_PLATFORM_WINDOWS && BX_COMPILER_MSVC # pragma pack(push, 8) @@ -153,7 +225,7 @@ namespace bx ThreadName tn; tn.type = 0x1000; tn.name = _name; - tn.id = m_threadId; + tn.id = ti->m_threadId; tn.flags = 0; __try @@ -175,33 +247,83 @@ namespace bx int32_t Thread::entry() { #if BX_PLATFORM_WINDOWS - m_threadId = ::GetCurrentThreadId(); + ThreadInternal* ti = (ThreadInternal*)m_internal; + ti->m_threadId = ::GetCurrentThreadId(); #endif // BX_PLATFORM_WINDOWS m_sem.post(); return m_fn(m_userData); } -#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT - DWORD WINAPI Thread::threadFunc(LPVOID _arg) + struct TlsDataInternal { - Thread* thread = (Thread*)_arg; - int32_t result = thread->entry(); - return result; +#if BX_PLATFORM_WINDOWS + uint32_t m_id; +#elif !(BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT) + pthread_key_t m_id; +#endif // BX_PLATFORM_* + }; + +#if BX_PLATFORM_WINDOWS + TlsData::TlsData() + { + BX_STATIC_ASSERT(sizeof(TlsDataInternal) <= sizeof(m_internal) ); + + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + ti->m_id = TlsAlloc(); + BX_CHECK(TLS_OUT_OF_INDEXES != ti->m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() ); } -#else - void* Thread::threadFunc(void* _arg) + + TlsData::~TlsData() { - Thread* thread = (Thread*)_arg; - union - { - void* ptr; - int32_t i; - } cast; - cast.i = thread->entry(); - return cast.ptr; + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + BOOL result = TlsFree(ti->m_id); + BX_CHECK(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result); } -#endif // BX_PLATFORM_ + + void* TlsData::get() const + { + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + return TlsGetValue(ti->m_id); + } + + void TlsData::set(void* _ptr) + { + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + TlsSetValue(ti->m_id, _ptr); + } + +#elif !(BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT) + + TlsData::TlsData() + { + BX_STATIC_ASSERT(sizeof(TlsDataInternal) <= sizeof(m_internal) ); + + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + int result = pthread_key_create(&ti->m_id, NULL); + BX_CHECK(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result); + } + + TlsData::~TlsData() + { + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + int result = pthread_key_delete(ti->m_id); + BX_CHECK(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result); + } + + void* TlsData::get() const + { + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + return pthread_getspecific(ti->m_id); + } + + void TlsData::set(void* _ptr) + { + TlsDataInternal* ti = (TlsDataInternal*)m_internal; + int result = pthread_setspecific(ti->m_id, _ptr); + BX_CHECK(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result); + } +#endif // BX_PLATFORM_* } // namespace bx diff --git a/3rdparty/bx/src/timer.cpp b/3rdparty/bx/src/timer.cpp new file mode 100644 index 00000000000..7f5403749d9 --- /dev/null +++ b/3rdparty/bx/src/timer.cpp @@ -0,0 +1,60 @@ +/* + * Copyright 2010-2017 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + */ + +#include <bx/timer.h> + +#if BX_PLATFORM_ANDROID +# include <time.h> // clock, clock_gettime +#elif BX_PLATFORM_EMSCRIPTEN +# include <emscripten.h> +#elif BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT +# include <windows.h> +#else +# include <sys/time.h> // gettimeofday +#endif // BX_PLATFORM_ + +namespace bx +{ + int64_t getHPCounter() + { +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT + LARGE_INTEGER li; + // Performance counter value may unexpectedly leap forward + // http://support.microsoft.com/kb/274323 + QueryPerformanceCounter(&li); + int64_t i64 = li.QuadPart; +#elif BX_PLATFORM_ANDROID + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + int64_t i64 = now.tv_sec*INT64_C(1000000000) + now.tv_nsec; +#elif BX_PLATFORM_EMSCRIPTEN + int64_t i64 = int64_t(1000.0f * emscripten_get_now() ); +#elif !BX_PLATFORM_NONE + struct timeval now; + gettimeofday(&now, 0); + int64_t i64 = now.tv_sec*INT64_C(1000000) + now.tv_usec; +#else + BX_CHECK(false, "Not implemented!"); + int64_t i64 = UINT64_MAX; +#endif // BX_PLATFORM_ + return i64; + } + + int64_t getHPFrequency() + { +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360 || BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT + LARGE_INTEGER li; + QueryPerformanceFrequency(&li); + return li.QuadPart; +#elif BX_PLATFORM_ANDROID + return INT64_C(1000000000); +#elif BX_PLATFORM_EMSCRIPTEN + return INT64_C(1000000); +#else + return INT64_C(1000000); +#endif // BX_PLATFORM_ + } + +} // namespace bx |