feat: update Filament to v1.56.4
This commit is contained in:
@@ -278,18 +278,23 @@ public:
|
||||
void* pop() noexcept {
|
||||
Node* const pStorage = mStorage;
|
||||
|
||||
HeadPtr currentHead = mHead.load();
|
||||
HeadPtr currentHead = mHead.load(std::memory_order_relaxed);
|
||||
while (currentHead.offset >= 0) {
|
||||
// The value of "pNext" we load here might already contain application data if another
|
||||
// thread raced ahead of us. But in that case, the computed "newHead" will be discarded
|
||||
// since compare_exchange_weak fails. Then this thread will loop with the updated
|
||||
// since compare_exchange_weak() fails. Then this thread will loop with the updated
|
||||
// value of currentHead, and try again.
|
||||
Node* const pNext = pStorage[currentHead.offset].next.load(std::memory_order_relaxed);
|
||||
// TSAN complains if we don't use a local variable here.
|
||||
Node const node = pStorage[currentHead.offset];
|
||||
Node const* const pNext = node.next;
|
||||
const HeadPtr newHead{ pNext ? int32_t(pNext - pStorage) : -1, currentHead.tag + 1 };
|
||||
// In the rare case that the other thread that raced ahead of us already returned the
|
||||
// same mHead we just loaded, but it now has a different "next" value, the tag field will not
|
||||
// match, and compare_exchange_weak will fail and prevent that particular race condition.
|
||||
if (mHead.compare_exchange_weak(currentHead, newHead)) {
|
||||
// In the rare case that the other thread that raced ahead of us already returned the
|
||||
// same mHead we just loaded, but it now has a different "next" value, the tag field
|
||||
// will not match, and compare_exchange_weak() will fail and prevent that particular
|
||||
// race condition.
|
||||
// acquire: no read/write can be reordered before this
|
||||
if (mHead.compare_exchange_weak(currentHead, newHead,
|
||||
std::memory_order_acquire, std::memory_order_relaxed)) {
|
||||
// This assert needs to occur after we have validated that there was no race condition
|
||||
// Otherwise, next might already contain application data, if another thread
|
||||
// raced ahead of us after we loaded mHead, but before we loaded mHead->next.
|
||||
@@ -306,13 +311,15 @@ public:
|
||||
Node* const storage = mStorage;
|
||||
assert_invariant(p && p >= storage);
|
||||
Node* const node = static_cast<Node*>(p);
|
||||
HeadPtr currentHead = mHead.load();
|
||||
HeadPtr currentHead = mHead.load(std::memory_order_relaxed);
|
||||
HeadPtr newHead = { int32_t(node - storage), currentHead.tag + 1 };
|
||||
do {
|
||||
newHead.tag = currentHead.tag + 1;
|
||||
Node* const n = (currentHead.offset >= 0) ? (storage + currentHead.offset) : nullptr;
|
||||
node->next.store(n, std::memory_order_relaxed);
|
||||
} while(!mHead.compare_exchange_weak(currentHead, newHead));
|
||||
Node* const pNext = (currentHead.offset >= 0) ? (storage + currentHead.offset) : nullptr;
|
||||
node->next = pNext; // could be a race with pop, corrected by CAS
|
||||
} while(!mHead.compare_exchange_weak(currentHead, newHead,
|
||||
std::memory_order_release, std::memory_order_relaxed));
|
||||
// release: no read/write can be reordered after this
|
||||
}
|
||||
|
||||
void* getFirst() noexcept {
|
||||
@@ -320,10 +327,7 @@ public:
|
||||
}
|
||||
|
||||
struct Node {
|
||||
// This should be a regular (non-atomic) pointer, but this causes TSAN to complain
|
||||
// about a data-race that exists but is benin. We always use this atomic<> in
|
||||
// relaxed mode.
|
||||
// The data race TSAN complains about is when a pop() is interrupted by a
|
||||
// There is a benign data race when a pop() is interrupted by a
|
||||
// pop() + push() just after mHead->next is read -- it appears as though it is written
|
||||
// without synchronization (by the push), however in that case, the pop's CAS will fail
|
||||
// and things will auto-correct.
|
||||
@@ -346,7 +350,7 @@ public:
|
||||
// |
|
||||
// CAS, tag++
|
||||
//
|
||||
std::atomic<Node*> next;
|
||||
Node* next = nullptr;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
FixedCapacityVector() = default;
|
||||
|
||||
explicit FixedCapacityVector(const allocator_type& allocator) noexcept
|
||||
: mCapacityAllocator({}, allocator) {
|
||||
: mCapacityAllocator(0, allocator) {
|
||||
}
|
||||
|
||||
explicit FixedCapacityVector(size_type size, const allocator_type& allocator = allocator_type())
|
||||
@@ -299,6 +299,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
void shrink_to_fit() {
|
||||
if (size() < capacity()) {
|
||||
FixedCapacityVector t(construct_with_capacity, size(), allocator());
|
||||
t.mSize = size();
|
||||
std::uninitialized_move(begin(), end(), t.begin());
|
||||
this->swap(t);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
enum construct_with_capacity_tag{ construct_with_capacity };
|
||||
|
||||
@@ -318,9 +328,9 @@ private:
|
||||
|
||||
iterator assertCapacityForSize(size_type s) {
|
||||
if constexpr(CapacityCheck || FILAMENT_FORCE_CAPACITY_CHECK) {
|
||||
ASSERT_PRECONDITION(capacity() >= s,
|
||||
"capacity exceeded: requested size %lu, available capacity %lu.",
|
||||
(unsigned long)s, (unsigned long)capacity());
|
||||
FILAMENT_CHECK_PRECONDITION(capacity() >= s)
|
||||
<< "capacity exceeded: requested size " << (unsigned long)s
|
||||
<< "u, available capacity " << (unsigned long)capacity() << "u.";
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
@@ -17,14 +17,28 @@
|
||||
#ifndef TNT_UTILS_PANIC_H
|
||||
#define TNT_UTILS_PANIC_H
|
||||
|
||||
#ifdef FILAMENT_PANIC_USES_ABSL
|
||||
# if FILAMENT_PANIC_USES_ABSL
|
||||
# include "absl/log/log.h"
|
||||
# define FILAMENT_CHECK_PRECONDITION CHECK
|
||||
# define FILAMENT_CHECK_POSTCONDITION CHECK
|
||||
# define FILAMENT_CHECK_ARITHMETIC CHECK
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <utils/CallStack.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/sstream.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#ifdef __EXCEPTIONS
|
||||
# define UTILS_EXCEPTIONS 1
|
||||
#else
|
||||
# ifdef UTILS_EXCEPTIONS
|
||||
# error UTILS_EXCEPTIONS is already defined!
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -250,42 +264,83 @@ namespace utils {
|
||||
*/
|
||||
class UTILS_PUBLIC Panic {
|
||||
public:
|
||||
|
||||
using PanicHandlerCallback = void(*)(void* user, Panic const& panic);
|
||||
|
||||
/**
|
||||
* Sets a user-defined handler for the Panic. If exceptions are enabled, the concrete Panic
|
||||
* object will be thrown upon return; moreover it is acceptable to throw from the provided
|
||||
* callback, but it is unsafe to throw the Panic object itself, since it's just an interface.
|
||||
* It is also acceptable to abort from the callback. If exceptions are not enabled, std::abort()
|
||||
* will be automatically called upon return.
|
||||
*
|
||||
* The PanicHandlerCallback can be called from any thread.
|
||||
*
|
||||
* Caveat: this API can misbehave if is used as a static library in multiple translation units,
|
||||
* some of these translation units might not see the callback.
|
||||
*
|
||||
* @param handler pointer to the user defined handler for the Panic
|
||||
* @param user user pointer given back to the callback
|
||||
*/
|
||||
static void setPanicHandler(PanicHandlerCallback handler, void* user) noexcept;
|
||||
|
||||
|
||||
virtual ~Panic() noexcept;
|
||||
|
||||
/**
|
||||
* @return a detailed description of the error
|
||||
* @return a formatted and detailed description of the error including all available
|
||||
* information.
|
||||
* @see std::exception
|
||||
*/
|
||||
virtual const char* what() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the function name where the panic was detected
|
||||
* Get the type of the panic (e.g. "Precondition")
|
||||
* @return a C string containing the type of panic
|
||||
*/
|
||||
virtual const char* getType() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the reason string for the panic
|
||||
* @return a C string containing the reason for the panic
|
||||
*/
|
||||
virtual const char* getReason() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get a version of the reason string that is guaranteed to be constructed from literal
|
||||
* strings only; it will contain no runtime information.
|
||||
*/
|
||||
virtual const char* getReasonLiteral() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the function name where the panic was detected. On debug build the fully qualified
|
||||
* function name is returned; on release builds only the function name is.
|
||||
* @return a C string containing the function name where the panic was detected
|
||||
*/
|
||||
virtual const char* getFunction() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the file name where the panic was detected
|
||||
* Get the file name where the panic was detected. Only available on debug builds.
|
||||
* @return a C string containing the file name where the panic was detected
|
||||
*/
|
||||
virtual const char* getFile() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the line number in the file where the panic was detected
|
||||
* Get the line number in the file where the panic was detected. Only available on debug builds.
|
||||
* @return an integer containing the line number in the file where the panic was detected
|
||||
*/
|
||||
virtual int getLine() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Logs this exception to the system-log
|
||||
*/
|
||||
virtual void log() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the CallStack when the panic was detected
|
||||
* Get the CallStack when the panic was detected if available.
|
||||
* @return the CallStack when the panic was detected
|
||||
*/
|
||||
virtual const CallStack& getCallStack() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Logs this exception to the system-log
|
||||
*/
|
||||
virtual void log() const noexcept = 0;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
@@ -305,6 +360,9 @@ public:
|
||||
const char* what() const noexcept override;
|
||||
|
||||
// Panic interface
|
||||
const char* getType() const noexcept override;
|
||||
const char* getReason() const noexcept override;
|
||||
const char* getReasonLiteral() const noexcept override;
|
||||
const char* getFunction() const noexcept override;
|
||||
const char* getFile() const noexcept override;
|
||||
int getLine() const noexcept override;
|
||||
@@ -318,13 +376,14 @@ public:
|
||||
* @param function the name of the function where the error was detected
|
||||
* @param file the file where the above function in implemented
|
||||
* @param line the line in the above file where the error was detected
|
||||
* @param literal a literal version of the error message
|
||||
* @param format printf style string describing the error
|
||||
* @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC
|
||||
* @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC
|
||||
* @see setMode()
|
||||
*/
|
||||
static void panic(char const* function, char const* file, int line, const char* format, ...)
|
||||
UTILS_NORETURN;
|
||||
static void panic(char const* function, char const* file, int line, char const* literal,
|
||||
const char* format, ...) UTILS_NORETURN;
|
||||
|
||||
/**
|
||||
* Depending on the mode set, either throws an exception of type T with the given reason plus
|
||||
@@ -333,43 +392,41 @@ public:
|
||||
* @param function the name of the function where the error was detected
|
||||
* @param file the file where the above function in implemented
|
||||
* @param line the line in the above file where the error was detected
|
||||
* @param s std::string describing the error
|
||||
* @param literal a literal version of the error message
|
||||
* @param reason std::string describing the error
|
||||
* @see ASSERT_PRECONDITION, ASSERT_POSTCONDITION, ASSERT_ARITHMETIC
|
||||
* @see PANIC_PRECONDITION, PANIC_POSTCONDITION, PANIC_ARITHMETIC
|
||||
* @see setMode()
|
||||
*/
|
||||
static inline void panic(char const* function, char const* file, int line, const std::string& s)
|
||||
UTILS_NORETURN {
|
||||
panic(function, file, line, s.c_str());
|
||||
}
|
||||
static inline void panic(
|
||||
char const* function, char const* file, int line, char const* literal,
|
||||
std::string reason) UTILS_NORETURN;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates a Panic.
|
||||
* @param reason a description of the cause of the error
|
||||
*/
|
||||
explicit TPanic(std::string reason);
|
||||
|
||||
/**
|
||||
* Creates a Panic with extra information about the error-site.
|
||||
* @param function the name of the function where the error was detected
|
||||
* @param file the file where the above function in implemented
|
||||
* @param line the line in the above file where the error was detected
|
||||
* @param literal a literal version of the error message
|
||||
* @param reason a description of the cause of the error
|
||||
*/
|
||||
TPanic(char const* function, char const* file, int line, std::string reason);
|
||||
TPanic(char const* function, char const* file, int line, char const* literal,
|
||||
std::string reason);
|
||||
|
||||
~TPanic() override;
|
||||
|
||||
private:
|
||||
void buildMessage();
|
||||
|
||||
CallStack m_callstack;
|
||||
std::string m_reason;
|
||||
char const* const m_function = nullptr;
|
||||
char const* const m_file = nullptr;
|
||||
const int m_line = -1;
|
||||
mutable std::string m_msg;
|
||||
char const* const mFile = nullptr; // file where the panic happened
|
||||
char const* const mFunction = nullptr; // function where the panic happened
|
||||
int const mLine = -1; // line where the panic happened
|
||||
std::string mLiteral; // reason for the panic, built only from literals
|
||||
std::string mReason; // reason for the panic
|
||||
mutable std::string mWhat; // fully formatted reason
|
||||
CallStack mCallstack;
|
||||
};
|
||||
|
||||
namespace details {
|
||||
@@ -391,6 +448,7 @@ class UTILS_PUBLIC PreconditionPanic : public TPanic<PreconditionPanic> {
|
||||
// e.g.: invalid arguments
|
||||
using TPanic<PreconditionPanic>::TPanic;
|
||||
friend class TPanic<PreconditionPanic>;
|
||||
constexpr static auto type = "Precondition";
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -404,6 +462,7 @@ class UTILS_PUBLIC PostconditionPanic : public TPanic<PostconditionPanic> {
|
||||
// e.g.: dead-lock would occur, arithmetic errors
|
||||
using TPanic<PostconditionPanic>::TPanic;
|
||||
friend class TPanic<PostconditionPanic>;
|
||||
constexpr static auto type = "Postcondition";
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -417,8 +476,74 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
|
||||
// e.g.: underflow, overflow, internal computations errors
|
||||
using TPanic<ArithmeticPanic>::TPanic;
|
||||
friend class TPanic<ArithmeticPanic>;
|
||||
constexpr static auto type = "Arithmetic";
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
struct Voidify final {
|
||||
template<typename T>
|
||||
void operator&&(const T&) const&& {}
|
||||
};
|
||||
|
||||
class UTILS_PUBLIC PanicStream {
|
||||
public:
|
||||
PanicStream(
|
||||
char const* function,
|
||||
char const* file,
|
||||
int line,
|
||||
char const* message) noexcept;
|
||||
|
||||
~PanicStream();
|
||||
|
||||
PanicStream& operator<<(short value) noexcept;
|
||||
PanicStream& operator<<(unsigned short value) noexcept;
|
||||
|
||||
PanicStream& operator<<(char value) noexcept;
|
||||
PanicStream& operator<<(unsigned char value) noexcept;
|
||||
|
||||
PanicStream& operator<<(int value) noexcept;
|
||||
PanicStream& operator<<(unsigned int value) noexcept;
|
||||
|
||||
PanicStream& operator<<(long value) noexcept;
|
||||
PanicStream& operator<<(unsigned long value) noexcept;
|
||||
|
||||
PanicStream& operator<<(long long value) noexcept;
|
||||
PanicStream& operator<<(unsigned long long value) noexcept;
|
||||
|
||||
PanicStream& operator<<(float value) noexcept;
|
||||
PanicStream& operator<<(double value) noexcept;
|
||||
PanicStream& operator<<(long double value) noexcept;
|
||||
|
||||
PanicStream& operator<<(bool value) noexcept;
|
||||
|
||||
PanicStream& operator<<(const void* value) noexcept;
|
||||
|
||||
PanicStream& operator<<(const char* string) noexcept;
|
||||
PanicStream& operator<<(const unsigned char* string) noexcept;
|
||||
|
||||
PanicStream& operator<<(std::string const& s) noexcept;
|
||||
PanicStream& operator<<(std::string_view const& s) noexcept;
|
||||
|
||||
protected:
|
||||
io::sstream mStream;
|
||||
char const* mFunction;
|
||||
char const* mFile;
|
||||
int mLine;
|
||||
char const* mLiteral;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class TPanicStream : public PanicStream {
|
||||
public:
|
||||
using PanicStream::PanicStream;
|
||||
~TPanicStream() noexcept(false) UTILS_NORETURN {
|
||||
T::panic(mFunction, mFile, mLine, mLiteral, mStream.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
} // namespace utils
|
||||
|
||||
@@ -430,37 +555,70 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
|
||||
# define PANIC_FUNCTION __func__
|
||||
#endif
|
||||
|
||||
|
||||
#define FILAMENT_CHECK_CONDITION_IMPL(cond) \
|
||||
switch (0) \
|
||||
case 0: \
|
||||
default: \
|
||||
UTILS_LIKELY(cond) ? (void)0 : ::utils::details::Voidify()&&
|
||||
|
||||
#define FILAMENT_PANIC_IMPL(message, TYPE) \
|
||||
::utils::details::TPanicStream<::utils::TYPE>(PANIC_FUNCTION, PANIC_FILE(__FILE__), __LINE__, message)
|
||||
|
||||
#ifndef FILAMENT_CHECK_PRECONDITION
|
||||
#define FILAMENT_CHECK_PRECONDITION(condition) \
|
||||
FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PreconditionPanic)
|
||||
#endif
|
||||
|
||||
#ifndef FILAMENT_CHECK_POSTCONDITION
|
||||
#define FILAMENT_CHECK_POSTCONDITION(condition) \
|
||||
FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, PostconditionPanic)
|
||||
#endif
|
||||
|
||||
#ifndef FILAMENT_CHECK_ARITHMETIC
|
||||
#define FILAMENT_CHECK_ARITHMETIC(condition) \
|
||||
FILAMENT_CHECK_CONDITION_IMPL(condition) FILAMENT_PANIC_IMPL(#condition, ArithmeticPanic)
|
||||
#endif
|
||||
|
||||
#define PANIC_PRECONDITION_IMPL(cond, format, ...) \
|
||||
::utils::PreconditionPanic::panic(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__)
|
||||
|
||||
#define PANIC_POSTCONDITION_IMPL(cond, format, ...) \
|
||||
::utils::PostconditionPanic::panic(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__)
|
||||
|
||||
#define PANIC_ARITHMETIC_IMPL(cond, format, ...) \
|
||||
::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, #cond, format, ##__VA_ARGS__)
|
||||
|
||||
#define PANIC_LOG_IMPL(cond, format, ...) \
|
||||
::utils::details::panicLog(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* PANIC_PRECONDITION is a macro that reports a PreconditionPanic
|
||||
* @param format printf-style string describing the error in more details
|
||||
*/
|
||||
#define PANIC_PRECONDITION(format, ...) \
|
||||
::utils::PreconditionPanic::panic(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
|
||||
#define PANIC_PRECONDITION(format, ...) PANIC_PRECONDITION_IMPL(format, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* PANIC_POSTCONDITION is a macro that reports a PostconditionPanic
|
||||
* @param format printf-style string describing the error in more details
|
||||
*/
|
||||
#define PANIC_POSTCONDITION(format, ...) \
|
||||
::utils::PostconditionPanic::panic(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
|
||||
#define PANIC_POSTCONDITION(format, ...) PANIC_POSTCONDITION_IMPL(format, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* PANIC_ARITHMETIC is a macro that reports a ArithmeticPanic
|
||||
* @param format printf-style string describing the error in more details
|
||||
*/
|
||||
#define PANIC_ARITHMETIC(format, ...) \
|
||||
::utils::ArithmeticPanic::panic(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
|
||||
#define PANIC_ARITHMETIC(format, ...) PANIC_ARITHMETIC_IMPL(format, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* PANIC_LOG is a macro that logs a Panic, and continues as usual.
|
||||
* @param format printf-style string describing the error in more details
|
||||
*/
|
||||
#define PANIC_LOG(format, ...) \
|
||||
::utils::details::panicLog(PANIC_FUNCTION, \
|
||||
PANIC_FILE(__FILE__), __LINE__, format, ##__VA_ARGS__)
|
||||
#define PANIC_LOG(format, ...) PANIC_LOG_IMPL(format, format, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @ingroup errors
|
||||
@@ -471,14 +629,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
|
||||
* @param format printf-style string describing the error in more details
|
||||
*/
|
||||
#define ASSERT_PRECONDITION(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__) : (void)0)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
|
||||
|
||||
#if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG)
|
||||
#define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION(format, ##__VA_ARGS__), false : true)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_PRECONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true)
|
||||
#else
|
||||
#define ASSERT_PRECONDITION_NON_FATAL(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -499,14 +657,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
|
||||
* @endcode
|
||||
*/
|
||||
#define ASSERT_POSTCONDITION(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__) : (void)0)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
|
||||
|
||||
#if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG)
|
||||
#define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION(format, ##__VA_ARGS__), false : true)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_POSTCONDITION_IMPL(cond, format, ##__VA_ARGS__), false : true)
|
||||
#else
|
||||
#define ASSERT_POSTCONDITION_NON_FATAL(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -527,14 +685,14 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
|
||||
* @endcode
|
||||
*/
|
||||
#define ASSERT_ARITHMETIC(cond, format, ...) \
|
||||
(!(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__) : (void)0)
|
||||
(!(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
|
||||
|
||||
#if defined(UTILS_EXCEPTIONS) || !defined(NDEBUG)
|
||||
#define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC(format, ##__VA_ARGS__), false : true)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_ARITHMETIC_IMPL(cond, format, ##__VA_ARGS__), false : true)
|
||||
#else
|
||||
#define ASSERT_ARITHMETIC_NON_FATAL(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG(format, ##__VA_ARGS__), false : true)
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__), false : true)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -558,6 +716,7 @@ class UTILS_PUBLIC ArithmeticPanic : public TPanic<ArithmeticPanic> {
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#define ASSERT_DESTRUCTOR(cond, format, ...) (!(cond) ? PANIC_LOG(format, ##__VA_ARGS__) : (void)0)
|
||||
#define ASSERT_DESTRUCTOR(cond, format, ...) \
|
||||
(!UTILS_LIKELY(cond) ? PANIC_LOG_IMPL(cond, format, ##__VA_ARGS__) : (void)0)
|
||||
|
||||
#endif // TNT_UTILS_PANIC_H
|
||||
|
||||
@@ -368,7 +368,7 @@ public:
|
||||
size_t last = mSize++;
|
||||
// Fold expression on the comma operator
|
||||
([&]{
|
||||
new(std::get<Indices>(mArrays) + last) Elements{std::get<Indices>(args)};
|
||||
new(std::get<Indices>(mArrays) + last) Elements{std::get<Indices>(std::forward<Structure>(args))};
|
||||
}() , ...);
|
||||
}
|
||||
|
||||
@@ -513,7 +513,7 @@ public:
|
||||
return (soa.elementAt<E>(i) = other);
|
||||
}
|
||||
UTILS_ALWAYS_INLINE Type const& operator = (Type&& other) noexcept {
|
||||
return (soa.elementAt<E>(i) = other);
|
||||
return (soa.elementAt<E>(i) = std::forward<Type>(other));
|
||||
}
|
||||
// comparisons
|
||||
UTILS_ALWAYS_INLINE bool operator==(Type const& other) const {
|
||||
|
||||
61
thermion_dart/native/include/filament/utils/Systrace.h
Normal file
61
thermion_dart/native/include/filament/utils/Systrace.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_UTILS_SYSTRACE_H
|
||||
#define TNT_UTILS_SYSTRACE_H
|
||||
|
||||
|
||||
#define SYSTRACE_TAG_NEVER (0)
|
||||
#define SYSTRACE_TAG_ALWAYS (1<<0)
|
||||
#define SYSTRACE_TAG_FILAMENT (1<<1) // don't change, used in makefiles
|
||||
#define SYSTRACE_TAG_JOBSYSTEM (1<<2)
|
||||
|
||||
/*
|
||||
* The SYSTRACE_ macros use SYSTRACE_TAG as a the TAG, which should be defined
|
||||
* before this file is included. If not, the SYSTRACE_TAG_ALWAYS tag will be used.
|
||||
*/
|
||||
|
||||
#ifndef SYSTRACE_TAG
|
||||
#define SYSTRACE_TAG (SYSTRACE_TAG_ALWAYS)
|
||||
#endif
|
||||
|
||||
// Systrace on Apple platforms is fragile and adds overhead, should only be enabled in dev builds.
|
||||
#ifndef FILAMENT_APPLE_SYSTRACE
|
||||
#define FILAMENT_APPLE_SYSTRACE 0
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <utils/android/Systrace.h>
|
||||
#elif defined(__APPLE__) && FILAMENT_APPLE_SYSTRACE
|
||||
#include <utils/darwin/Systrace.h>
|
||||
#else
|
||||
|
||||
#define SYSTRACE_ENABLE()
|
||||
#define SYSTRACE_DISABLE()
|
||||
#define SYSTRACE_CONTEXT()
|
||||
#define SYSTRACE_NAME(name)
|
||||
#define SYSTRACE_FRAME_ID(frame)
|
||||
#define SYSTRACE_NAME_BEGIN(name)
|
||||
#define SYSTRACE_NAME_END()
|
||||
#define SYSTRACE_CALL()
|
||||
#define SYSTRACE_ASYNC_BEGIN(name, cookie)
|
||||
#define SYSTRACE_ASYNC_END(name, cookie)
|
||||
#define SYSTRACE_VALUE32(name, val)
|
||||
#define SYSTRACE_VALUE64(name, val)
|
||||
|
||||
#endif // ANDROID
|
||||
|
||||
#endif // TNT_UTILS_SYSTRACE_H
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <type_traits> // for std::enable_if
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils {
|
||||
@@ -43,9 +44,15 @@ constexpr inline T clz(T x) noexcept {
|
||||
static_assert(sizeof(T) * CHAR_BIT <= 128, "details::clz() only support up to 128 bits");
|
||||
x |= (x >> 1u);
|
||||
x |= (x >> 2u);
|
||||
x |= (x >> 4u);
|
||||
x |= (x >> 8u);
|
||||
x |= (x >> 16u);
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 8) { // just to silence compiler warning
|
||||
x |= (x >> 4u);
|
||||
}
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 16) { // just to silence compiler warning
|
||||
x |= (x >> 8u);
|
||||
}
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 32) { // just to silence compiler warning
|
||||
x |= (x >> 16u);
|
||||
}
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 64) { // just to silence compiler warning
|
||||
x |= (x >> 32u);
|
||||
}
|
||||
@@ -67,11 +74,15 @@ constexpr inline T ctz(T x) noexcept {
|
||||
x &= -x;
|
||||
#endif
|
||||
if (x) c--;
|
||||
if (sizeof(T) * CHAR_BIT >= 64) {
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 64) {
|
||||
if (x & T(0x00000000FFFFFFFF)) c -= 32;
|
||||
}
|
||||
if (x & T(0x0000FFFF0000FFFF)) c -= 16;
|
||||
if (x & T(0x00FF00FF00FF00FF)) c -= 8;
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 32) {
|
||||
if (x & T(0x0000FFFF0000FFFF)) c -= 16;
|
||||
}
|
||||
if constexpr (sizeof(T) * CHAR_BIT >= 16) {
|
||||
if (x & T(0x00FF00FF00FF00FF)) c -= 8;
|
||||
}
|
||||
if (x & T(0x0F0F0F0F0F0F0F0F)) c -= 4;
|
||||
if (x & T(0x3333333333333333)) c -= 2;
|
||||
if (x & T(0x5555555555555555)) c -= 1;
|
||||
@@ -80,6 +91,24 @@ constexpr inline T ctz(T x) noexcept {
|
||||
|
||||
} // namespace details
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE clz(unsigned char x) noexcept {
|
||||
#if __has_builtin(__builtin_clz)
|
||||
return __builtin_clz((unsigned int)x) - 24;
|
||||
#else
|
||||
return details::clz(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE clz(unsigned short x) noexcept {
|
||||
#if __has_builtin(__builtin_clz)
|
||||
return __builtin_clz((unsigned int)x) - 16;
|
||||
#else
|
||||
return details::clz(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE clz(unsigned int x) noexcept {
|
||||
#if __has_builtin(__builtin_clz)
|
||||
@@ -107,6 +136,24 @@ unsigned long long UTILS_ALWAYS_INLINE clz(unsigned long long x) noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE ctz(unsigned char x) noexcept {
|
||||
#if __has_builtin(__builtin_ctz)
|
||||
return __builtin_ctz(x);
|
||||
#else
|
||||
return details::ctz(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE ctz(unsigned short x) noexcept {
|
||||
#if __has_builtin(__builtin_ctz)
|
||||
return __builtin_ctz(x);
|
||||
#else
|
||||
return details::ctz(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE ctz(unsigned int x) noexcept {
|
||||
#if __has_builtin(__builtin_ctz)
|
||||
@@ -134,6 +181,24 @@ unsigned long long UTILS_ALWAYS_INLINE ctz(unsigned long long x) noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE popcount(unsigned char x) noexcept {
|
||||
#if __has_builtin(__builtin_popcount)
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
return details::popcount(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE popcount(unsigned short x) noexcept {
|
||||
#if __has_builtin(__builtin_popcount)
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
return details::popcount(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
unsigned int UTILS_ALWAYS_INLINE popcount(unsigned int x) noexcept {
|
||||
#if __has_builtin(__builtin_popcount)
|
||||
@@ -161,11 +226,6 @@ unsigned long long UTILS_ALWAYS_INLINE popcount(unsigned long long x) noexcept {
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
uint8_t UTILS_ALWAYS_INLINE popcount(uint8_t x) noexcept {
|
||||
return (uint8_t)popcount((unsigned int)x);
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename = std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value>>
|
||||
constexpr inline UTILS_PUBLIC UTILS_PURE
|
||||
|
||||
@@ -60,6 +60,11 @@ public:
|
||||
std::fill(std::begin(storage), std::end(storage), 0);
|
||||
}
|
||||
|
||||
template<typename U, typename = typename std::enable_if_t<N == 1, U>>
|
||||
explicit bitset(U value) noexcept {
|
||||
storage[0] = value;
|
||||
}
|
||||
|
||||
T getBitsAt(size_t n) const noexcept {
|
||||
assert_invariant(n<N);
|
||||
return storage[n];
|
||||
@@ -94,6 +99,8 @@ public:
|
||||
|
||||
size_t size() const noexcept { return N * BITS_PER_WORD; }
|
||||
|
||||
bool empty() const noexcept { return none(); }
|
||||
|
||||
bool test(size_t bit) const noexcept { return operator[](bit); }
|
||||
|
||||
void set(size_t b) noexcept {
|
||||
@@ -117,11 +124,14 @@ public:
|
||||
storage[b / BITS_PER_WORD] ^= T(1) << (b % BITS_PER_WORD);
|
||||
}
|
||||
|
||||
|
||||
void reset() noexcept {
|
||||
std::fill(std::begin(storage), std::end(storage), 0);
|
||||
}
|
||||
|
||||
void clear() noexcept {
|
||||
reset();
|
||||
}
|
||||
|
||||
bool operator[](size_t b) const noexcept {
|
||||
assert_invariant(b / BITS_PER_WORD < N);
|
||||
return bool(storage[b / BITS_PER_WORD] & (T(1) << (b % BITS_PER_WORD)));
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <utils/compiler.h>
|
||||
|
||||
namespace utils {
|
||||
UTILS_PUBLIC
|
||||
void panic(const char *func, const char * file, int line, const char *assertion) noexcept;
|
||||
} // namespace filament
|
||||
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_UTILS_LINUX_CONDITION_H
|
||||
#define TNT_UTILS_LINUX_CONDITION_H
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <condition_variable> // for cv_status
|
||||
#include <limits>
|
||||
#include <mutex> // for unique_lock
|
||||
|
||||
#include <utils/linux/Mutex.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
namespace utils {
|
||||
|
||||
/*
|
||||
* A very simple condition variable class that can be used as an (almost) drop-in replacement
|
||||
* for std::condition_variable (doesn't have the timed wait() though).
|
||||
* It is very low overhead as most of it is inlined.
|
||||
*/
|
||||
|
||||
class Condition {
|
||||
public:
|
||||
Condition() noexcept = default;
|
||||
Condition(const Condition&) = delete;
|
||||
Condition& operator=(const Condition&) = delete;
|
||||
|
||||
void notify_all() noexcept {
|
||||
pulse(std::numeric_limits<int>::max());
|
||||
}
|
||||
|
||||
void notify_one() noexcept {
|
||||
pulse(1);
|
||||
}
|
||||
|
||||
void notify_n(size_t n) noexcept {
|
||||
if (n > 0) pulse(n);
|
||||
}
|
||||
|
||||
void wait(std::unique_lock<Mutex>& lock) noexcept {
|
||||
wait_until(lock.mutex(), false, nullptr);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
void wait(std::unique_lock<Mutex>& lock, P predicate) {
|
||||
while (!predicate()) {
|
||||
wait(lock);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
std::cv_status wait_until(std::unique_lock<Mutex>& lock,
|
||||
const std::chrono::time_point<std::chrono::steady_clock, D>& timeout_time) noexcept {
|
||||
// convert to nanoseconds
|
||||
uint64_t ns = std::chrono::duration<uint64_t, std::nano>(timeout_time.time_since_epoch()).count();
|
||||
using sec_t = decltype(timespec::tv_sec);
|
||||
using nsec_t = decltype(timespec::tv_nsec);
|
||||
timespec ts{ sec_t(ns / 1000000000), nsec_t(ns % 1000000000) };
|
||||
return wait_until(lock.mutex(), false, &ts);
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
std::cv_status wait_until(std::unique_lock<Mutex>& lock,
|
||||
const std::chrono::time_point<std::chrono::system_clock, D>& timeout_time) noexcept {
|
||||
// convert to nanoseconds
|
||||
uint64_t ns = std::chrono::duration<uint64_t, std::nano>(timeout_time.time_since_epoch()).count();
|
||||
using sec_t = decltype(timespec::tv_sec);
|
||||
using nsec_t = decltype(timespec::tv_nsec);
|
||||
timespec ts{ sec_t(ns / 1000000000), nsec_t(ns % 1000000000) };
|
||||
return wait_until(lock.mutex(), true, &ts);
|
||||
}
|
||||
|
||||
template<typename C, typename D, typename P>
|
||||
bool wait_until(std::unique_lock<Mutex>& lock,
|
||||
const std::chrono::time_point<C, D>& timeout_time, P predicate) noexcept {
|
||||
while (!predicate()) {
|
||||
if (wait_until(lock, timeout_time) == std::cv_status::timeout) {
|
||||
return predicate();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename R, typename Period>
|
||||
std::cv_status wait_for(std::unique_lock<Mutex>& lock,
|
||||
const std::chrono::duration<R, Period>& rel_time) noexcept {
|
||||
return wait_until(lock, std::chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
|
||||
template<typename R, typename Period, typename P>
|
||||
bool wait_for(std::unique_lock<Mutex>& lock,
|
||||
const std::chrono::duration<R, Period>& rel_time, P pred) noexcept {
|
||||
return wait_until(lock, std::chrono::steady_clock::now() + rel_time, std::move(pred));
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<uint32_t> mState = { 0 };
|
||||
|
||||
void pulse(int threadCount) noexcept;
|
||||
|
||||
std::cv_status wait_until(Mutex* lock,
|
||||
bool realtimeClock, timespec* ts) noexcept;
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // TNT_UTILS_LINUX_CONDITION_H
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_UTILS_LINUX_MUTEX_H
|
||||
#define TNT_UTILS_LINUX_MUTEX_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils {
|
||||
|
||||
/*
|
||||
* A very simple mutex class that can be used as an (almost) drop-in replacement
|
||||
* for std::mutex.
|
||||
* It is very low overhead as most of it is inlined.
|
||||
*/
|
||||
|
||||
class Mutex {
|
||||
public:
|
||||
constexpr Mutex() noexcept = default;
|
||||
Mutex(const Mutex&) = delete;
|
||||
Mutex& operator=(const Mutex&) = delete;
|
||||
|
||||
void lock() noexcept {
|
||||
uint32_t old_state = UNLOCKED;
|
||||
if (UTILS_UNLIKELY(!mState.compare_exchange_strong(old_state,
|
||||
LOCKED, std::memory_order_acquire, std::memory_order_relaxed))) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
void unlock() noexcept {
|
||||
if (UTILS_UNLIKELY(mState.exchange(UNLOCKED, std::memory_order_release) == LOCKED_CONTENDED)) {
|
||||
wake();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
UNLOCKED = 0, LOCKED = 1, LOCKED_CONTENDED = 2
|
||||
};
|
||||
std::atomic<uint32_t> mState = { UNLOCKED };
|
||||
|
||||
void wait() noexcept;
|
||||
void wake() noexcept;
|
||||
};
|
||||
|
||||
} // namespace utils
|
||||
|
||||
#endif // TNT_UTILS_LINUX_MUTEX_H
|
||||
@@ -40,7 +40,7 @@ inline void* aligned_alloc(size_t size, size_t align) noexcept {
|
||||
#if defined(WIN32)
|
||||
p = ::_aligned_malloc(size, align);
|
||||
#else
|
||||
::posix_memalign(&p, align, size);
|
||||
(void) ::posix_memalign(&p, align, size);
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
@@ -73,8 +73,8 @@ public:
|
||||
using const_pointer = const TYPE*;
|
||||
using reference = TYPE&;
|
||||
using const_reference = const TYPE&;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using size_type = ::size_t;
|
||||
using difference_type = ::ptrdiff_t;
|
||||
using propagate_on_container_move_assignment = std::true_type;
|
||||
using is_always_equal = std::true_type;
|
||||
|
||||
|
||||
@@ -95,11 +95,11 @@ protected:
|
||||
size_t length() const noexcept;
|
||||
|
||||
private:
|
||||
void reserve(size_t newSize) noexcept;
|
||||
void reserve(size_t newCapacity) noexcept;
|
||||
|
||||
char* buffer = nullptr; // buffer address
|
||||
char* curr = nullptr; // current pointer
|
||||
size_t size = 0; // size remaining
|
||||
size_t sizeRemaining = 0; // size remaining
|
||||
size_t capacity = 0; // total capacity of the buffer
|
||||
};
|
||||
|
||||
|
||||
36
thermion_dart/native/include/filament/utils/sstream.h
Normal file
36
thermion_dart/native/include/filament/utils/sstream.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_UTILS_SSTREAM_H
|
||||
#define TNT_UTILS_SSTREAM_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace utils::io {
|
||||
|
||||
class UTILS_PUBLIC sstream : public ostream {
|
||||
public:
|
||||
ostream& flush() noexcept override;
|
||||
const char* c_str() const noexcept;
|
||||
size_t length() const noexcept;
|
||||
};
|
||||
|
||||
} // namespace utils::io
|
||||
|
||||
#endif // TNT_UTILS_SSTREAM_H
|
||||
Reference in New Issue
Block a user