feat update tsa
This commit is contained in:
parent
a81eb0f8de
commit
03a62901f2
@ -56,7 +56,7 @@ target_sources(
|
|||||||
src/strings/utils.cc
|
src/strings/utils.cc
|
||||||
src/synchronization/event.cc
|
src/synchronization/event.cc
|
||||||
src/synchronization/mutex.cc
|
src/synchronization/mutex.cc
|
||||||
src/synchronization/sequence_checker_internal.cc
|
src/synchronization/sequence_checker.cc
|
||||||
src/synchronization/thread_local.cc
|
src/synchronization/thread_local.cc
|
||||||
src/system/location.cc
|
src/system/location.cc
|
||||||
src/system/pid.cc
|
src/system/pid.cc
|
||||||
@ -126,6 +126,7 @@ if(SLED_BUILD_TESTS)
|
|||||||
src/futures/future_test.cc
|
src/futures/future_test.cc
|
||||||
# src/profiling/profiling_test.cc
|
# src/profiling/profiling_test.cc
|
||||||
src/strings/base64_test.cc
|
src/strings/base64_test.cc
|
||||||
|
src/synchronization/sequence_checker_test.cc
|
||||||
src/cleanup_test.cc
|
src/cleanup_test.cc
|
||||||
src/status_or_test.cc
|
src/status_or_test.cc
|
||||||
src/system/fiber/fiber_test.cc
|
src/system/fiber/fiber_test.cc
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef SLED_FILESYSTEM_PATH_H
|
#ifndef SLED_FILESYSTEM_PATH_H
|
||||||
#define SLED_FILESYSTEM_PATH_H
|
#define SLED_FILESYSTEM_PATH_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef SLED_FILESYSTEM_TEMPORARY_FILE_H
|
#ifndef SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||||
#define SLED_FILESYSTEM_TEMPORARY_FILE_H
|
#define SLED_FILESYSTEM_TEMPORARY_FILE_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -1,39 +1,59 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef SLED_LANG_ATTRIBUTES_H
|
#ifndef SLED_LANG_ATTRIBUTES_H
|
||||||
#define SLED_LANG_ATTRIBUTES_H
|
#define SLED_LANG_ATTRIBUTES_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <marl/tsa.h>
|
#define SLED_DEPRECATED __attribute__((deprecated))
|
||||||
|
|
||||||
#define SLED_DEPRECATED() __attribute__((deprecated))
|
#if defined(__clang__) && (!defined(SWIG))
|
||||||
#ifndef THREAD_ANNOTATION_ATTRIBUTE__
|
#define SLED_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||||
#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) && !defined(SWIG)
|
|
||||||
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
|
|
||||||
#elif defined(__clang__)
|
|
||||||
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
|
||||||
#else
|
#else
|
||||||
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
|
#define SLED_THREAD_ANNOTATION_ATTRIBUTE__(x)// no-op
|
||||||
#endif
|
|
||||||
#endif// THREAD_ANNOTATION_ATTRIBUTE__
|
|
||||||
|
|
||||||
#ifndef GUARDED_BY
|
|
||||||
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__)
|
#define SLED_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
|
||||||
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
|
|
||||||
|
|
||||||
#define EXCLUSIVE_LOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
|
#define SLED_SCOPED_CAPABILITY SLED_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
|
||||||
|
#define SLED_LOCKABLE SLED_THREAD_ANNOTATION_ATTRIBUTE__(lockable)
|
||||||
|
|
||||||
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
|
#define SLED_GUARDED_BY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
|
||||||
|
|
||||||
// #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
|
#define SLED_PT_GUARDED_BY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
|
||||||
|
|
||||||
#else// defined(__clang__)
|
#define SLED_ACQUIRED_BEFORE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
|
||||||
|
|
||||||
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(__VA_ARGS__))
|
#define SLED_ACQUIRED_AFTER(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
|
||||||
#define EXCLUSIVE_LOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(__VA_ARGS__))
|
|
||||||
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock(__VA_ARGS__))
|
#define SLED_REQUIRES(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
|
||||||
// #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
|
|
||||||
#endif
|
#define SLED_REQUIRES_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_ACQUIRE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_ACQUIRE_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_RELEASE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_RELEASE_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_TRY_ACQUIRE(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_TRY_ACQUIRE_SHARED(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_EXCLUDES(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define SLED_ASSERT_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
|
||||||
|
|
||||||
|
#define SLED_ASSERT_SHARED_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
|
||||||
|
|
||||||
|
#define SLED_RETURN_CAPABILITY(x) SLED_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
|
||||||
|
|
||||||
|
#define SLED_NO_THREAD_SAFETY_ANALYSIS SLED_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
|
||||||
|
|
||||||
|
#define SLED_EXCLUSIVE_LOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
|
||||||
|
#define SLED_SHARED_LOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
|
||||||
|
#define SLED_EXCLUSIVE_TRYLOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
|
||||||
|
#define SLED_SHARED_TRYLOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
|
||||||
|
#define SLED_UNLOCK_FUNCTION(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
|
||||||
|
#define SLED_ASSERT_EXCLUSIVE_LOCK(...) SLED_THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
|
||||||
|
|
||||||
#endif// SLED_LANG_ATTRIBUTES_H
|
#endif// SLED_LANG_ATTRIBUTES_H
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_LOG_LOG_H
|
#ifndef SLED_LOG_LOG_H
|
||||||
#define SLED_LOG_LOG_H
|
#define SLED_LOG_LOG_H
|
||||||
|
#pragma once
|
||||||
#include "sled/system/location.h"
|
#include "sled/system/location.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
@ -69,6 +69,9 @@ void Log(LogLevel level, const char *tag, const char *fmt, const char *file_name
|
|||||||
#define LOGE_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
|
#define LOGE_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kError, tag, fmt, __VA_ARGS__)
|
||||||
#define LOGF_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
|
#define LOGF_IF(cond, tag, fmt, ...) SLOG_IF(cond, sled::LogLevel::kFatal, tag, fmt, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define CHECK(cond, fmt, ...) SLOG_ASSERT(cond, "DCHECK", fmt, ##__VA_ARGS__)
|
||||||
|
#define DCHECK(cond, fmt, ...) SLOG_ASSERT(cond, "DCHECK", fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define LOGV(tag, fmt, ...) SLOG(sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__)
|
#define LOGV(tag, fmt, ...) SLOG(sled::LogLevel::kTrace, tag, fmt, ##__VA_ARGS__)
|
||||||
#define LOGD(tag, fmt, ...) SLOG(sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
|
#define LOGD(tag, fmt, ...) SLOG(sled::LogLevel::kDebug, tag, fmt, ##__VA_ARGS__)
|
||||||
#define LOGI(tag, fmt, ...) SLOG(sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__)
|
#define LOGI(tag, fmt, ...) SLOG(sled::LogLevel::kInfo, tag, fmt, ##__VA_ARGS__)
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NETWORK_ASYNC_RESOLVER_H
|
#ifndef SLED_NETWORK_ASYNC_RESOLVER_H
|
||||||
#define SLED_NETWORK_ASYNC_RESOLVER_H
|
#define SLED_NETWORK_ASYNC_RESOLVER_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/async_resolver_interface.h"
|
#include "sled/network/async_resolver_interface.h"
|
||||||
#include "sled/scoped_refptr.h"
|
#include "sled/scoped_refptr.h"
|
||||||
@ -34,8 +34,7 @@ private:
|
|||||||
SocketAddress addr_;
|
SocketAddress addr_;
|
||||||
std::vector<IPAddress> addresses_;
|
std::vector<IPAddress> addresses_;
|
||||||
int error_;
|
int error_;
|
||||||
bool recursion_check_ =
|
bool recursion_check_ = false;// Protects against SignalDone calling into Destroy.
|
||||||
false;// Protects against SignalDone calling into Destroy.
|
|
||||||
bool destroy_called_ = false;
|
bool destroy_called_ = false;
|
||||||
scoped_refptr<State> state_;
|
scoped_refptr<State> state_;
|
||||||
};
|
};
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NETWORK_ASYNC_RESOLVER_INTERFACE_H
|
#ifndef SLED_NETWORK_ASYNC_RESOLVER_INTERFACE_H
|
||||||
#define SLED_NETWORK_ASYNC_RESOLVER_INTERFACE_H
|
#define SLED_NETWORK_ASYNC_RESOLVER_INTERFACE_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/socket_address.h"
|
#include "sled/network/socket_address.h"
|
||||||
#include "sled/sigslot.h"
|
#include "sled/sigslot.h"
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef SLED_NETWORK_IP_ADDRESS_H
|
#ifndef SLED_NETWORK_IP_ADDRESS_H
|
||||||
#define SLED_NETWORK_IP_ADDRESS_H
|
#define SLED_NETWORK_IP_ADDRESS_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/byte_order.h"
|
#include "sled/byte_order.h"
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -29,10 +28,7 @@ public:
|
|||||||
u_.ip4 = ip4;
|
u_.ip4 = ip4;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit IPAddress(const in6_addr &ip6) : family_(AF_INET6)
|
explicit IPAddress(const in6_addr &ip6) : family_(AF_INET6) { u_.ip6 = ip6; }
|
||||||
{
|
|
||||||
u_.ip6 = ip6;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit IPAddress(uint32_t ip_in_host_byte_order) : family_(AF_INET)
|
explicit IPAddress(uint32_t ip_in_host_byte_order) : family_(AF_INET)
|
||||||
{
|
{
|
||||||
@ -40,10 +36,7 @@ public:
|
|||||||
u_.ip4.s_addr = HostToNetwork32(ip_in_host_byte_order);
|
u_.ip4.s_addr = HostToNetwork32(ip_in_host_byte_order);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPAddress(const IPAddress &other) : family_(other.family_)
|
IPAddress(const IPAddress &other) : family_(other.family_) { ::memcpy(&u_, &other.u_, sizeof(u_)); }
|
||||||
{
|
|
||||||
::memcpy(&u_, &other.u_, sizeof(u_));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~IPAddress() = default;
|
virtual ~IPAddress() = default;
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NETWORK_NULL_SOCKET_SERVER_H
|
#ifndef SLED_NETWORK_NULL_SOCKET_SERVER_H
|
||||||
#define SLED_NETWORK_NULL_SOCKET_SERVER_H
|
#define SLED_NETWORK_NULL_SOCKET_SERVER_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/socket_server.h"
|
#include "sled/network/socket_server.h"
|
||||||
#include "sled/synchronization/event.h"
|
#include "sled/synchronization/event.h"
|
||||||
@ -21,6 +21,7 @@ public:
|
|||||||
void WakeUp() override;
|
void WakeUp() override;
|
||||||
|
|
||||||
Socket *CreateSocket(int family, int type) override;
|
Socket *CreateSocket(int family, int type) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Event event_;
|
Event event_;
|
||||||
};
|
};
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NETWORK_PHYSICAL_SOCKET_SERVER_H
|
#ifndef SLED_NETWORK_PHYSICAL_SOCKET_SERVER_H
|
||||||
#define SLED_NETWORK_PHYSICAL_SOCKET_SERVER_H
|
#define SLED_NETWORK_PHYSICAL_SOCKET_SERVER_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/async_resolver.h"
|
#include "sled/network/async_resolver.h"
|
||||||
#include "sled/sigslot.h"
|
#include "sled/sigslot.h"
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NETWORK_SOCKET_H
|
#ifndef SLED_NETWORK_SOCKET_H
|
||||||
#define SLED_NETWORK_SOCKET_H
|
#define SLED_NETWORK_SOCKET_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/socket_address.h"
|
#include "sled/network/socket_address.h"
|
||||||
#include "sled/sigslot.h"
|
#include "sled/sigslot.h"
|
||||||
@ -36,11 +36,9 @@ public:
|
|||||||
virtual int Bind(const SocketAddress &addr) = 0;
|
virtual int Bind(const SocketAddress &addr) = 0;
|
||||||
virtual int Connect(const SocketAddress &addr) = 0;
|
virtual int Connect(const SocketAddress &addr) = 0;
|
||||||
virtual int Send(const void *pv, size_t cb) = 0;
|
virtual int Send(const void *pv, size_t cb) = 0;
|
||||||
virtual int
|
virtual int SendTo(const void *pv, size_t cb, const SocketAddress &addr) = 0;
|
||||||
SendTo(const void *pv, size_t cb, const SocketAddress &addr) = 0;
|
|
||||||
virtual int Recv(void *pv, size_t cb, int64_t *timestamp) = 0;
|
virtual int Recv(void *pv, size_t cb, int64_t *timestamp) = 0;
|
||||||
virtual int
|
virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr, int64_t *timestamp) = 0;
|
||||||
RecvFrom(void *pv, size_t cb, SocketAddress *paddr, int64_t *timestamp) = 0;
|
|
||||||
virtual int Listen(int backlog) = 0;
|
virtual int Listen(int backlog) = 0;
|
||||||
virtual Socket *Accept(SocketAddress *paddr) = 0;
|
virtual Socket *Accept(SocketAddress *paddr) = 0;
|
||||||
virtual int Close() = 0;
|
virtual int Close() = 0;
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NETWORK_SOCKET_ADDRESS_H
|
#ifndef SLED_NETWORK_SOCKET_ADDRESS_H
|
||||||
#define SLED_NETWORK_SOCKET_ADDRESS_H
|
#define SLED_NETWORK_SOCKET_ADDRESS_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/ip_address.h"
|
#include "sled/network/ip_address.h"
|
||||||
|
|
||||||
@ -65,8 +65,7 @@ private:
|
|||||||
bool literal_;
|
bool literal_;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool SocketAddressFromSockAddrStorage(const sockaddr_storage &saddr,
|
bool SocketAddressFromSockAddrStorage(const sockaddr_storage &saddr, SocketAddress *out);
|
||||||
SocketAddress *out);
|
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
|
||||||
#endif// SLED_NETWORK_SOCKET_ADDRESS_H
|
#endif// SLED_NETWORK_SOCKET_ADDRESS_H
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef SLED_NETWORK_SOCKET_FACTORY_H
|
#ifndef SLED_NETWORK_SOCKET_FACTORY_H
|
||||||
#define SLED_NETWORK_SOCKET_FACTORY_H
|
#define SLED_NETWORK_SOCKET_FACTORY_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/socket.h"
|
#include "sled/network/socket.h"
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma
|
|
||||||
#ifndef SLED_NETWORK_SOCKET_SERVER_H
|
#ifndef SLED_NETWORK_SOCKET_SERVER_H
|
||||||
#define SLED_NETWORK_SOCKET_SERVER_H
|
#define SLED_NETWORK_SOCKET_SERVER_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/network/socket_factory.h"
|
#include "sled/network/socket_factory.h"
|
||||||
#include "sled/units/time_delta.h"
|
#include "sled/units/time_delta.h"
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_NUMERICS_DIVIDE_ROUND_H
|
#ifndef SLED_NUMERICS_DIVIDE_ROUND_H
|
||||||
#define SLED_NUMERICS_DIVIDE_ROUND_H
|
#define SLED_NUMERICS_DIVIDE_ROUND_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef FIXED_POINT_H_
|
#ifndef FIXED_POINT_H_
|
||||||
#define FIXED_POINT_H_
|
#define FIXED_POINT_H_
|
||||||
|
#pragma once
|
||||||
#include <Eigen/Eigen>
|
#include <Eigen/Eigen>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -186,8 +186,7 @@ template<int shift, typename T>
|
|||||||
constexpr T
|
constexpr T
|
||||||
signed_rsh(T x)
|
signed_rsh(T x)
|
||||||
{
|
{
|
||||||
return shifter<shift, (shift >= 0), (abs_helper(shift) >= sizeof(T) * 8),
|
return shifter<shift, (shift >= 0), (abs_helper(shift) >= sizeof(T) * 8), T>::op(x);
|
||||||
T>::op(x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Signed right shift, run time version.*/
|
/*Signed right shift, run time version.*/
|
||||||
@ -195,9 +194,7 @@ template<typename T>
|
|||||||
T
|
T
|
||||||
signed_rsh(T x, int shift)
|
signed_rsh(T x, int shift)
|
||||||
{
|
{
|
||||||
return std::abs(shift) < sizeof(T) * 8
|
return std::abs(shift) < sizeof(T) * 8 ? (shift < 0 ? x << -shift : x >> shift) : 0;
|
||||||
? (shift < 0 ? x << -shift : x >> shift)
|
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Signed left shift, compile-time version*/
|
/*Signed left shift, compile-time version*/
|
||||||
@ -213,9 +210,7 @@ template<typename T>
|
|||||||
T
|
T
|
||||||
signed_lsh(T x, int shift)
|
signed_lsh(T x, int shift)
|
||||||
{
|
{
|
||||||
return std::abs(shift) < sizeof(T) * 8
|
return std::abs(shift) < sizeof(T) * 8 ? (shift < 0 ? x >> -shift : x << shift) : 0;
|
||||||
? (shift < 0 ? x >> -shift : x << shift)
|
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Multiplies and simultaneously right-shifts the argument values,
|
/*Multiplies and simultaneously right-shifts the argument values,
|
||||||
@ -381,8 +376,7 @@ template<unsigned fb>
|
|||||||
fp::q<f, I>
|
fp::q<f, I>
|
||||||
fp::q<f, I>::operator/(q<fb, I> b) const
|
fp::q<f, I>::operator/(q<fb, I> b) const
|
||||||
{
|
{
|
||||||
static const I msb = (I) 1
|
static const I msb = (I) 1 << (sizeof(I) * 8 - 1);//Most significant bit for the type
|
||||||
<< (sizeof(I) * 8 - 1);//Most significant bit for the type
|
|
||||||
//Make b positive so that leading zeroes can be properly computed
|
//Make b positive so that leading zeroes can be properly computed
|
||||||
I abs_b = b.i < 0 ? -b.i : b.i;
|
I abs_b = b.i < 0 ? -b.i : b.i;
|
||||||
unsigned lz = fp_internal::clz(abs_b);//Amount of leading zeroes
|
unsigned lz = fp_internal::clz(abs_b);//Amount of leading zeroes
|
||||||
@ -398,9 +392,7 @@ fp::q<f, I>::operator/(q<fb, I> b) const
|
|||||||
}
|
}
|
||||||
q<f, I> t;
|
q<f, I> t;
|
||||||
t.i = (I) fp_internal::mul_rsh(//adjust the radix point of (this*r)
|
t.i = (I) fp_internal::mul_rsh(//adjust the radix point of (this*r)
|
||||||
r.i,
|
r.i, (typename std::make_unsigned<I>::type)(this->i < 0 ? -this->i : this->i),
|
||||||
(typename std::make_unsigned<I>::type)(this->i < 0 ? -this->i
|
|
||||||
: this->i),
|
|
||||||
sizeof(i) * 16 - fb - lz - (d == msb) - 1);
|
sizeof(i) * 16 - fb - lz - (d == msb) - 1);
|
||||||
t.i = (b.i < 0) ^ (this->i < 0) ? -t.i : t.i;//set correct sign
|
t.i = (b.i < 0) ^ (this->i < 0) ? -t.i : t.i;//set correct sign
|
||||||
return t;
|
return t;
|
||||||
@ -552,10 +544,8 @@ fp::q<f, I>::operator>=(q<fb, I> b) const
|
|||||||
I mb = fp_internal::signed_rsh<fb>(b.i);
|
I mb = fp_internal::signed_rsh<fb>(b.i);
|
||||||
return (ma > mb)
|
return (ma > mb)
|
||||||
|| ((ma == mb)
|
|| ((ma == mb)
|
||||||
&& ((typename std::make_unsigned<I>::type)
|
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
|
||||||
fp_internal::signed_lsh<bits - f>(i)
|
>= (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
|
||||||
>= (typename std::make_unsigned<I>::type)
|
|
||||||
fp_internal::signed_lsh<bits - fb>(b.i)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned f, typename I>
|
template<unsigned f, typename I>
|
||||||
@ -568,10 +558,8 @@ fp::q<f, I>::operator>(q<fb, I> b) const
|
|||||||
I mb = fp_internal::signed_rsh<fb>(b.i);
|
I mb = fp_internal::signed_rsh<fb>(b.i);
|
||||||
return (ma > mb)
|
return (ma > mb)
|
||||||
|| ((ma == mb)
|
|| ((ma == mb)
|
||||||
&& ((typename std::make_unsigned<I>::type)
|
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
|
||||||
fp_internal::signed_lsh<bits - f>(i)
|
> (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
|
||||||
> (typename std::make_unsigned<I>::type)
|
|
||||||
fp_internal::signed_lsh<bits - fb>(b.i)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned f, typename I>
|
template<unsigned f, typename I>
|
||||||
@ -584,10 +572,8 @@ fp::q<f, I>::operator<=(q<fb, I> b) const
|
|||||||
I mb = fp_internal::signed_rsh<fb>(b.i);
|
I mb = fp_internal::signed_rsh<fb>(b.i);
|
||||||
return (ma < mb)
|
return (ma < mb)
|
||||||
|| ((ma == mb)
|
|| ((ma == mb)
|
||||||
&& ((typename std::make_unsigned<I>::type)
|
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
|
||||||
fp_internal::signed_lsh<bits - f>(i)
|
<= (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
|
||||||
<= (typename std::make_unsigned<I>::type)
|
|
||||||
fp_internal::signed_lsh<bits - fb>(b.i)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned f, typename I>
|
template<unsigned f, typename I>
|
||||||
@ -600,10 +586,8 @@ fp::q<f, I>::operator<(q<fb, I> b) const
|
|||||||
I mb = fp_internal::signed_rsh<fb>(b.i);
|
I mb = fp_internal::signed_rsh<fb>(b.i);
|
||||||
return (ma < mb)
|
return (ma < mb)
|
||||||
|| ((ma == mb)
|
|| ((ma == mb)
|
||||||
&& ((typename std::make_unsigned<I>::type)
|
&& ((typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - f>(i)
|
||||||
fp_internal::signed_lsh<bits - f>(i)
|
< (typename std::make_unsigned<I>::type) fp_internal::signed_lsh<bits - fb>(b.i)));
|
||||||
< (typename std::make_unsigned<I>::type)
|
|
||||||
fp_internal::signed_lsh<bits - fb>(b.i)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned f, typename I>
|
template<unsigned f, typename I>
|
||||||
@ -611,8 +595,7 @@ template<unsigned fb>
|
|||||||
bool
|
bool
|
||||||
fp::q<f, I>::operator==(q<fb, I> b) const
|
fp::q<f, I>::operator==(q<fb, I> b) const
|
||||||
{
|
{
|
||||||
return fp_internal::signed_rsh<f - fb>(i) == b.i
|
return fp_internal::signed_rsh<f - fb>(i) == b.i && fp_internal::signed_rsh<fb - f>(b.i) == i;
|
||||||
&& fp_internal::signed_rsh<fb - f>(b.i) == i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned f, typename I>
|
template<unsigned f, typename I>
|
||||||
@ -620,8 +603,7 @@ template<unsigned fb>
|
|||||||
bool
|
bool
|
||||||
fp::q<f, I>::operator!=(q<fb, I> b) const
|
fp::q<f, I>::operator!=(q<fb, I> b) const
|
||||||
{
|
{
|
||||||
return fp_internal::signed_rsh<f - fb>(i) != b.i
|
return fp_internal::signed_rsh<f - fb>(i) != b.i || fp_internal::signed_rsh<fb - f>(b.i) != i;
|
||||||
|| fp_internal::signed_rsh<fb - f>(b.i) != i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<unsigned f, typename I>
|
template<unsigned f, typename I>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef SLED_PROFILING_PROFILING_H
|
#ifndef SLED_PROFILING_PROFILING_H
|
||||||
#define SLED_PROFILING_PROFILING_H
|
#define SLED_PROFILING_PROFILING_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/system/location.h"
|
#include "sled/system/location.h"
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#ifndef SLED_QUEUE_CIRCLE_QUEUE_H
|
#ifndef SLED_QUEUE_CIRCLE_QUEUE_H
|
||||||
#define SLED_QUEUE_CIRCLE_QUEUE_H
|
#define SLED_QUEUE_CIRCLE_QUEUE_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/log/log.h"
|
#include "sled/log/log.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
@ -49,10 +50,7 @@ public:
|
|||||||
head_ = (head_ + 1) % (LEN + 1);
|
head_ = (head_ + 1) % (LEN + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const
|
size_t size() const { return tail_ >= head_ ? tail_ - head_ : (LEN + 1) - (head_ - tail_); }
|
||||||
{
|
|
||||||
return tail_ >= head_ ? tail_ - head_ : (LEN + 1) - (head_ - tail_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty() const { return (tail_ + 1) % (LEN + 1) == head_; }
|
bool empty() const { return (tail_ + 1) % (LEN + 1) == head_; }
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_SYNCHRONIZATION_EVENT_H
|
#ifndef SLED_SYNCHRONIZATION_EVENT_H
|
||||||
#define SLED_SYNCHRONIZATION_EVENT_H
|
#define SLED_SYNCHRONIZATION_EVENT_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/synchronization/mutex.h"
|
#include "sled/synchronization/mutex.h"
|
||||||
#include "sled/units/time_delta.h"
|
#include "sled/units/time_delta.h"
|
||||||
@ -28,15 +28,13 @@ public:
|
|||||||
|
|
||||||
bool Wait(TimeDelta give_up_after)
|
bool Wait(TimeDelta give_up_after)
|
||||||
{
|
{
|
||||||
return Wait(give_up_after,
|
return Wait(give_up_after, give_up_after.IsPlusInfinity() ? TimeDelta::Seconds(3) : kForever);
|
||||||
give_up_after.IsPlusInfinity() ? TimeDelta::Seconds(3)
|
|
||||||
: kForever);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex mutex_;
|
Mutex mutex_;
|
||||||
ConditionVariable cv_;
|
ConditionVariable cv_;
|
||||||
const bool is_manual_reset_;
|
const bool is_manual_reset_;
|
||||||
bool event_status_ GUARDED_BY(mutex_);
|
bool event_status_ SLED_GUARDED_BY(mutex_);
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
@ -4,17 +4,17 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
|
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
|
||||||
#define SLED_SYNCHRONIZATION_MUTEX_H
|
#define SLED_SYNCHRONIZATION_MUTEX_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "marl/conditionvariable.h"
|
|
||||||
#include "sled/lang/attributes.h"
|
#include "sled/lang/attributes.h"
|
||||||
#include "sled/units/time_delta.h"
|
#include "sled/units/time_delta.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <marl/conditionvariable.h>
|
||||||
#include <marl/mutex.h>
|
#include <marl/mutex.h>
|
||||||
#include <mutex>
|
// #include <condition_variable>
|
||||||
|
// #include <mutex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace sled {
|
namespace sled {
|
||||||
@ -60,36 +60,52 @@ public:
|
|||||||
RecursiveMutex(const RecursiveMutex &) = delete;
|
RecursiveMutex(const RecursiveMutex &) = delete;
|
||||||
RecursiveMutex &operator=(const RecursiveMutex &) = delete;
|
RecursiveMutex &operator=(const RecursiveMutex &) = delete;
|
||||||
|
|
||||||
inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { impl_.lock(); }
|
inline void Lock() SLED_SHARED_LOCK_FUNCTION() { impl_.lock(); }
|
||||||
|
|
||||||
inline bool TryLock() { return impl_.try_lock(); }
|
inline bool TryLock() SLED_SHARED_TRYLOCK_FUNCTION(true) { return impl_.try_lock(); }
|
||||||
|
|
||||||
inline void AssertHeld() {}
|
inline void AssertHeld() {}
|
||||||
|
|
||||||
inline void Unlock() UNLOCK_FUNCTION() { impl_.unlock(); }
|
inline void Unlock() SLED_UNLOCK_FUNCTION() { impl_.unlock(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex impl_;
|
std::recursive_mutex impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TLock, typename std::enable_if<internal::HasLockAndUnlock<TLock>::value, TLock>::type * = nullptr>
|
class RecursiveMutexLock final {
|
||||||
class LockGuard final {
|
|
||||||
public:
|
public:
|
||||||
LockGuard(const LockGuard &) = delete;
|
RecursiveMutexLock(const RecursiveMutexLock &) = delete;
|
||||||
LockGuard &operator=(const LockGuard &) = delete;
|
RecursiveMutexLock &operator=(const RecursiveMutexLock &) = delete;
|
||||||
|
|
||||||
explicit LockGuard(TLock *lock) EXCLUSIVE_LOCK_FUNCTION() : mutex_(lock) { mutex_->Lock(); };
|
explicit RecursiveMutexLock(RecursiveMutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : mutex_(mutex)
|
||||||
|
{
|
||||||
|
mutex->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
~LockGuard() UNLOCK_FUNCTION() { mutex_->Unlock(); };
|
~RecursiveMutexLock() SLED_UNLOCK_FUNCTION() { mutex_->Unlock(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TLock *mutex_;
|
RecursiveMutex *mutex_;
|
||||||
friend class ConditionVariable;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// LockGuard(const LockGuard &) = delete;
|
||||||
|
// LockGuard &operator=(const LockGuard &) = delete;
|
||||||
|
//
|
||||||
|
// explicit LockGuard(TLock *lock) SLED_EXCLUSIVE_LOCK_FUNCTION(lock) : mutex_(lock) { mutex_->Lock(); };
|
||||||
|
//
|
||||||
|
// ~LockGuard() SLED_UNLOCK_FUNCTION() { mutex_->Unlock(); };
|
||||||
|
//
|
||||||
|
// private:
|
||||||
|
// TLock *mutex_;
|
||||||
|
// friend class ConditionVariable;
|
||||||
|
// };
|
||||||
|
//
|
||||||
class MutexLock final {
|
class MutexLock final {
|
||||||
public:
|
public:
|
||||||
MutexLock(Mutex *mutex) : lock_(*mutex) {}
|
MutexLock(Mutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : lock_(*mutex) {}
|
||||||
|
|
||||||
|
~MutexLock() SLED_UNLOCK_FUNCTION() = default;
|
||||||
|
|
||||||
MutexLock(const MutexLock &) = delete;
|
MutexLock(const MutexLock &) = delete;
|
||||||
MutexLock &operator=(const MutexLock &) = delete;
|
MutexLock &operator=(const MutexLock &) = delete;
|
||||||
@ -99,41 +115,6 @@ private:
|
|||||||
marl::lock lock_;
|
marl::lock lock_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using MutexGuard SLED_DEPRECATED() = MutexLock;
|
|
||||||
// using MutexGuard = marl::lock;
|
|
||||||
// using MutexLock = LockGuard<Mutex>;
|
|
||||||
// using MutexGuard = LockGuard<Mutex>;
|
|
||||||
using RecursiveMutexLock SLED_DEPRECATED() = LockGuard<RecursiveMutex>;
|
|
||||||
|
|
||||||
// class MutexLock final {
|
|
||||||
// public:
|
|
||||||
// MutexLock(const MutexLock &) = delete;
|
|
||||||
// MutexLock &operator=(const MutexLock &) = delete;
|
|
||||||
//
|
|
||||||
// explicit MutexLock(Mutex *mutex) : mutex_(mutex) { mutex->Lock(); }
|
|
||||||
//
|
|
||||||
// ~MutexLock() { mutex_->Unlock(); }
|
|
||||||
//
|
|
||||||
// private:
|
|
||||||
// Mutex *mutex_;
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// class RecursiveMutexLock final {
|
|
||||||
// public:
|
|
||||||
// RecursiveMutexLock(const RecursiveMutexLock &) = delete;
|
|
||||||
// RecursiveMutexLock &operator=(const RecursiveMutexLock &) = delete;
|
|
||||||
//
|
|
||||||
// explicit RecursiveMutexLock(RecursiveMutex *mutex) : mutex_(mutex)
|
|
||||||
// {
|
|
||||||
// mutex->Lock();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ~RecursiveMutexLock() { mutex_->Unlock(); }
|
|
||||||
//
|
|
||||||
// private:
|
|
||||||
// RecursiveMutex *mutex_;
|
|
||||||
// };
|
|
||||||
|
|
||||||
class ConditionVariable final {
|
class ConditionVariable final {
|
||||||
public:
|
public:
|
||||||
static constexpr TimeDelta kForever = TimeDelta::PlusInfinity();
|
static constexpr TimeDelta kForever = TimeDelta::PlusInfinity();
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_SYNCHRONIZATION_ONE_TIME_EVENT_H
|
#ifndef SLED_SYNCHRONIZATION_ONE_TIME_EVENT_H
|
||||||
#define SLED_SYNCHRONIZATION_ONE_TIME_EVENT_H
|
#define SLED_SYNCHRONIZATION_ONE_TIME_EVENT_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "sled/synchronization/mutex.h"
|
#include "sled/synchronization/mutex.h"
|
||||||
|
|
||||||
|
52
include/sled/synchronization/sequence_checker.h
Normal file
52
include/sled/synchronization/sequence_checker.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* @file : sequence_checker_internal
|
||||||
|
* @created : Saturday Feb 03, 2024 13:34:40 CST
|
||||||
|
* @license : MIT
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
|
||||||
|
#define SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "sled/log/log.h"
|
||||||
|
#include "sled/synchronization/mutex.h"
|
||||||
|
#include "sled/task_queue/task_queue_base.h"
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
|
||||||
|
class SLED_LOCKABLE SequenceChecker {
|
||||||
|
public:
|
||||||
|
enum InitialState { kDetached = false, kAttached = true };
|
||||||
|
|
||||||
|
explicit SequenceChecker(InitialState initial_state = kAttached);
|
||||||
|
~SequenceChecker() = default;
|
||||||
|
|
||||||
|
bool IsCurrent() const;
|
||||||
|
|
||||||
|
void Detach();
|
||||||
|
|
||||||
|
// only use by macro RUN_ON
|
||||||
|
std::string ExpectationToString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable Mutex mutex_;
|
||||||
|
mutable bool attached_ GUARDED_BY(mutex_);
|
||||||
|
mutable pthread_t valid_thread_ GUARDED_BY(mutex_);
|
||||||
|
mutable const TaskQueueBase *valid_queue_ GUARDED_BY(mutex_);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SequenceCheckerDoNothing {
|
||||||
|
public:
|
||||||
|
explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {}
|
||||||
|
|
||||||
|
bool IsCurrent() const { return true; }
|
||||||
|
|
||||||
|
void Detach() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SLED_RUN_ON(x) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
|
||||||
|
#define SLED_DCHECK_RUN_ON(x) DCHECK((x)->IsCurrent(), (x)->ExpectationToString())
|
||||||
|
|
||||||
|
}// namespace sled
|
||||||
|
|
||||||
|
#endif// SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
|
@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file : sequence_checker_internal
|
|
||||||
* @created : Saturday Feb 03, 2024 13:34:40 CST
|
|
||||||
* @license : MIT
|
|
||||||
**/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
|
|
||||||
#define SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
|
|
||||||
|
|
||||||
#include "sled/synchronization/mutex.h"
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace sled {
|
|
||||||
|
|
||||||
class SequenceCheckerImpl {
|
|
||||||
public:
|
|
||||||
explicit SequenceCheckerImpl(bool attach_to_current_thread);
|
|
||||||
~SequenceCheckerImpl() = default;
|
|
||||||
|
|
||||||
bool IsCurrent() const;
|
|
||||||
void Detach();
|
|
||||||
std::string ExpectationToString() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
mutable Mutex lock_;
|
|
||||||
mutable bool attached_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SequenceCheckerDoNothing {
|
|
||||||
public:
|
|
||||||
explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {}
|
|
||||||
|
|
||||||
bool IsCurrent() const { return true; }
|
|
||||||
|
|
||||||
void Detach() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ThreadLikeObject>
|
|
||||||
typename std::enable_if<std::is_base_of<SequenceCheckerImpl, ThreadLikeObject>::value,
|
|
||||||
std::string>::type
|
|
||||||
ExpectationToString(const ThreadLikeObject *checker)
|
|
||||||
{
|
|
||||||
return checker->ExpectationToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ThreadLikeObject>
|
|
||||||
typename std::enable_if<!std::is_base_of<SequenceCheckerImpl, ThreadLikeObject>::value,
|
|
||||||
std::string>::type
|
|
||||||
ExpectationToString(const ThreadLikeObject *checker)
|
|
||||||
{
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
}// namespace sled
|
|
||||||
|
|
||||||
#endif// SLED_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H
|
|
@ -4,9 +4,9 @@
|
|||||||
* @license : MIT
|
* @license : MIT
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SLED_SYNCHRONIZATION_THREAD_LOCAL_H
|
#ifndef SLED_SYNCHRONIZATION_THREAD_LOCAL_H
|
||||||
#define SLED_SYNCHRONIZATION_THREAD_LOCAL_H
|
#define SLED_SYNCHRONIZATION_THREAD_LOCAL_H
|
||||||
|
#pragma once
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -47,46 +47,35 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename PointerT = T>
|
template<typename PointerT = T>
|
||||||
typename std::enable_if<std::is_pointer<PointerT>::value, PointerT>::type
|
typename std::enable_if<std::is_pointer<PointerT>::value, PointerT>::type Get() const
|
||||||
Get() const
|
|
||||||
{
|
{
|
||||||
auto ptr = detail::ThreadLocalManager::Instance().Get(
|
auto ptr = detail::ThreadLocalManager::Instance().Get(detail::ThreadLocalManager::CurrentThreadId(), key_);
|
||||||
detail::ThreadLocalManager::CurrentThreadId(), key_);
|
|
||||||
return static_cast<PointerT>(ptr);
|
return static_cast<PointerT>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename IntT = T>
|
template<typename IntT = T>
|
||||||
typename std::enable_if<std::is_integral<IntT>::value, IntT>::type
|
typename std::enable_if<std::is_integral<IntT>::value, IntT>::type Get() const
|
||||||
Get() const
|
|
||||||
{
|
{
|
||||||
static_assert(sizeof(IntT) <= sizeof(void *), "");
|
static_assert(sizeof(IntT) <= sizeof(void *), "");
|
||||||
auto ptr = detail::ThreadLocalManager::Instance().Get(
|
auto ptr = detail::ThreadLocalManager::Instance().Get(detail::ThreadLocalManager::CurrentThreadId(), key_);
|
||||||
detail::ThreadLocalManager::CurrentThreadId(), key_);
|
return static_cast<IntT>(static_cast<char *>(ptr) - static_cast<char *>(0));
|
||||||
return static_cast<IntT>(static_cast<char *>(ptr)
|
|
||||||
- static_cast<char *>(0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename PointerT = T,
|
template<typename PointerT = T,
|
||||||
typename std::enable_if<
|
typename std::enable_if<std::is_pointer<PointerT>::value || std::is_same<std::nullptr_t, PointerT>::value,
|
||||||
std::is_pointer<PointerT>::value
|
PointerT>::type = nullptr>
|
||||||
|| std::is_same<std::nullptr_t, PointerT>::value,
|
|
||||||
PointerT>::type = nullptr>
|
|
||||||
void Set(PointerT value)
|
void Set(PointerT value)
|
||||||
{
|
{
|
||||||
detail::ThreadLocalManager::Instance().Set(
|
detail::ThreadLocalManager::Instance().Set(detail::ThreadLocalManager::CurrentThreadId(), key_,
|
||||||
detail::ThreadLocalManager::CurrentThreadId(), key_,
|
static_cast<void *>(value));
|
||||||
static_cast<void *>(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename IntT = T,
|
template<typename IntT = T, typename std::enable_if<std::is_integral<IntT>::value, IntT>::type * = nullptr>
|
||||||
typename std::enable_if<std::is_integral<IntT>::value, IntT>::type
|
|
||||||
* = nullptr>
|
|
||||||
void Set(IntT value)
|
void Set(IntT value)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(IntT) <= sizeof(void *), "");
|
static_assert(sizeof(IntT) <= sizeof(void *), "");
|
||||||
detail::ThreadLocalManager::Instance().Set(
|
detail::ThreadLocalManager::Instance().Set(detail::ThreadLocalManager::CurrentThreadId(), key_,
|
||||||
detail::ThreadLocalManager::CurrentThreadId(), key_,
|
(char *) 0 + value);
|
||||||
(char *) 0 + value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "sled/network/async_resolver.h"
|
#include "sled/network/async_resolver.h"
|
||||||
#include "sled/network/async_resolver_interface.h"
|
|
||||||
#include "sled/ref_counted_base.h"
|
#include "sled/ref_counted_base.h"
|
||||||
#include "sled/synchronization/mutex.h"
|
#include "sled/synchronization/mutex.h"
|
||||||
#include "sled/task_queue/task_queue_base.h"
|
#include "sled/task_queue/task_queue_base.h"
|
||||||
@ -15,9 +14,7 @@ struct AsyncResolver::State : public RefCountedBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ResolveHostname(const std::string &hostname,
|
ResolveHostname(const std::string &hostname, int family, std::vector<IPAddress> *addresses)
|
||||||
int family,
|
|
||||||
std::vector<IPAddress> *addresses)
|
|
||||||
{
|
{
|
||||||
if (!addresses) { return -1; }
|
if (!addresses) { return -1; }
|
||||||
|
|
||||||
|
@ -85,10 +85,7 @@ private:
|
|||||||
bool &flag_to_clear_;
|
bool &flag_to_clear_;
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalSocketServer::PhysicalSocketServer() : fWait_(false)
|
PhysicalSocketServer::PhysicalSocketServer() : fWait_(false) { signal_wakeup_ = new Signaler(this, fWait_); }
|
||||||
{
|
|
||||||
signal_wakeup_ = new Signaler(this, fWait_);
|
|
||||||
}
|
|
||||||
|
|
||||||
PhysicalSocketServer::~PhysicalSocketServer() { delete signal_wakeup_; }
|
PhysicalSocketServer::~PhysicalSocketServer() { delete signal_wakeup_; }
|
||||||
|
|
||||||
@ -158,9 +155,7 @@ PhysicalSocketServer::Update(Dispatcher *pdispatcher)
|
|||||||
int
|
int
|
||||||
PhysicalSocketServer::ToCusWait(TimeDelta max_wait_duration)
|
PhysicalSocketServer::ToCusWait(TimeDelta max_wait_duration)
|
||||||
{
|
{
|
||||||
return max_wait_duration == Event::kForever
|
return max_wait_duration == Event::kForever ? kForeverMs : max_wait_duration.RoundUpTo(TimeDelta::Micros(1)).us();
|
||||||
? kForeverMs
|
|
||||||
: max_wait_duration.RoundUpTo(TimeDelta::Micros(1)).us();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -174,17 +169,12 @@ PhysicalSocketServer::Wait(TimeDelta max_wait_duration, bool process_io)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ProcessEvents(Dispatcher *pdispatcher,
|
ProcessEvents(Dispatcher *pdispatcher, bool readable, bool writable, bool error_event, bool check_error)
|
||||||
bool readable,
|
|
||||||
bool writable,
|
|
||||||
bool error_event,
|
|
||||||
bool check_error)
|
|
||||||
{
|
{
|
||||||
int errcode = 0;
|
int errcode = 0;
|
||||||
if (check_error) {
|
if (check_error) {
|
||||||
socklen_t len = sizeof(errcode);
|
socklen_t len = sizeof(errcode);
|
||||||
int res = ::getsockopt(pdispatcher->GetDescriptor(), SOL_SOCKET,
|
int res = ::getsockopt(pdispatcher->GetDescriptor(), SOL_SOCKET, SO_ERROR, &errcode, &len);
|
||||||
SO_ERROR, &errcode, &len);
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (error_event || errno != ENOTSOCK) { errcode = EBADF; }
|
if (error_event || errno != ENOTSOCK) { errcode = EBADF; }
|
||||||
}
|
}
|
||||||
@ -243,9 +233,7 @@ PhysicalSocketServer::WaitSelect(int64_t cusWait, bool process_io)
|
|||||||
for (auto const &kv : dispatcher_by_key_) {
|
for (auto const &kv : dispatcher_by_key_) {
|
||||||
uint64_t key = kv.first;
|
uint64_t key = kv.first;
|
||||||
Dispatcher *pdispatcher = kv.second;
|
Dispatcher *pdispatcher = kv.second;
|
||||||
if (!process_io && (pdispatcher != signal_wakeup_)) {
|
if (!process_io && (pdispatcher != signal_wakeup_)) { continue; }
|
||||||
continue;
|
|
||||||
}
|
|
||||||
current_dispatcher_keys_.push_back(key);
|
current_dispatcher_keys_.push_back(key);
|
||||||
int fd = pdispatcher->GetDescriptor();
|
int fd = pdispatcher->GetDescriptor();
|
||||||
if (fd > fdmax) { fdmax = fd; }
|
if (fd > fdmax) { fdmax = fd; }
|
||||||
@ -278,8 +266,7 @@ PhysicalSocketServer::WaitSelect(int64_t cusWait, bool process_io)
|
|||||||
bool writable = FD_ISSET(fd, &fdsWrite);
|
bool writable = FD_ISSET(fd, &fdsWrite);
|
||||||
if (writable) { FD_CLR(fd, &fdsWrite); }
|
if (writable) { FD_CLR(fd, &fdsWrite); }
|
||||||
|
|
||||||
ProcessEvents(pdispatcher, readable, writable, false,
|
ProcessEvents(pdispatcher, readable, writable, false, readable || writable);
|
||||||
readable || writable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,8 +296,7 @@ PhysicalSocket::PhysicalSocket(PhysicalSocketServer *ss, SOCKET s)
|
|||||||
SetEnabledEvents(DE_READ | DE_WRITE);
|
SetEnabledEvents(DE_READ | DE_WRITE);
|
||||||
int type = SOCK_STREAM;
|
int type = SOCK_STREAM;
|
||||||
socklen_t len = sizeof(type);
|
socklen_t len = sizeof(type);
|
||||||
const int res =
|
const int res = getsockopt(s_, SOL_SOCKET, SO_TYPE, (void *) &type, &len);
|
||||||
getsockopt(s_, SOL_SOCKET, SO_TYPE, (void *) &type, &len);
|
|
||||||
udp_ = (SOCK_DGRAM == type);
|
udp_ = (SOCK_DGRAM == type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -399,8 +385,7 @@ void
|
|||||||
|
|
||||||
PhysicalSocket::SetError(int error)
|
PhysicalSocket::SetError(int error)
|
||||||
{
|
{
|
||||||
// MutexLock lock(&mutex_);
|
MutexLock lock(&mutex_);
|
||||||
MutexGuard lock(&mutex_);
|
|
||||||
error_ = error;
|
error_ = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,31 +416,24 @@ PhysicalSocket::SetOption(Option opt, int value)
|
|||||||
int
|
int
|
||||||
PhysicalSocket::Send(const void *pv, size_t cb)
|
PhysicalSocket::Send(const void *pv, size_t cb)
|
||||||
{
|
{
|
||||||
int sent = DoSend(s_, reinterpret_cast<const char *>(pv),
|
int sent = DoSend(s_, reinterpret_cast<const char *>(pv), static_cast<int>(cb), MSG_NOSIGNAL);
|
||||||
static_cast<int>(cb), MSG_NOSIGNAL);
|
|
||||||
UpdateLastError();
|
UpdateLastError();
|
||||||
if ((sent > 0 && sent < static_cast<int>(cb))
|
if ((sent > 0 && sent < static_cast<int>(cb)) || (sent < 0 && IsBlockingError(GetError()))) {
|
||||||
|| (sent < 0 && IsBlockingError(GetError()))) {
|
|
||||||
EnableEvents(DE_WRITE);
|
EnableEvents(DE_WRITE);
|
||||||
}
|
}
|
||||||
return sent;
|
return sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PhysicalSocket::SendTo(const void *buffer,
|
PhysicalSocket::SendTo(const void *buffer, size_t length, const SocketAddress &addr)
|
||||||
size_t length,
|
|
||||||
const SocketAddress &addr)
|
|
||||||
{
|
{
|
||||||
sockaddr_storage saddr;
|
sockaddr_storage saddr;
|
||||||
size_t len = addr.ToSockAddrStorage(&saddr);
|
size_t len = addr.ToSockAddrStorage(&saddr);
|
||||||
|
|
||||||
int sent =
|
int sent = DoSendTo(s_, static_cast<const char *>(buffer), static_cast<int>(length), MSG_NOSIGNAL,
|
||||||
DoSendTo(s_, static_cast<const char *>(buffer),
|
reinterpret_cast<sockaddr *>(&saddr), static_cast<int>(len));
|
||||||
static_cast<int>(length), MSG_NOSIGNAL,
|
|
||||||
reinterpret_cast<sockaddr *>(&saddr), static_cast<int>(len));
|
|
||||||
UpdateLastError();
|
UpdateLastError();
|
||||||
if ((sent > 0 && sent < static_cast<int>(length))
|
if ((sent > 0 && sent < static_cast<int>(length)) || (sent < 0 && IsBlockingError(GetError()))) {
|
||||||
|| (sent < 0 && IsBlockingError(GetError()))) {
|
|
||||||
EnableEvents(DE_WRITE);
|
EnableEvents(DE_WRITE);
|
||||||
}
|
}
|
||||||
return sent;
|
return sent;
|
||||||
@ -483,10 +461,7 @@ PhysicalSocket::Recv(void *buffer, size_t length, int64_t *timestamp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PhysicalSocket::RecvFrom(void *buffer,
|
PhysicalSocket::RecvFrom(void *buffer, size_t length, SocketAddress *out_addr, int64_t *timestamp)
|
||||||
size_t length,
|
|
||||||
SocketAddress *out_addr,
|
|
||||||
int64_t *timestamp)
|
|
||||||
{
|
{
|
||||||
int received = DoReadFromSocket(buffer, length, out_addr, timestamp);
|
int received = DoReadFromSocket(buffer, length, out_addr, timestamp);
|
||||||
UpdateLastError();
|
UpdateLastError();
|
||||||
@ -516,17 +491,12 @@ GetSocketRecvTimestamp(int socket)
|
|||||||
|
|
||||||
if (ret != 0) { return -1; }
|
if (ret != 0) { return -1; }
|
||||||
|
|
||||||
int64_t timestamp =
|
int64_t timestamp = static_cast<int64_t>(tv_ioctl.tv_sec) * kNumMicrosecsPerSec + tv_ioctl.tv_usec;
|
||||||
static_cast<int64_t>(tv_ioctl.tv_sec) * kNumMicrosecsPerSec
|
|
||||||
+ tv_ioctl.tv_usec;
|
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PhysicalSocket::DoReadFromSocket(void *buffer,
|
PhysicalSocket::DoReadFromSocket(void *buffer, size_t length, SocketAddress *out_addr, int64_t *timestamp)
|
||||||
size_t length,
|
|
||||||
SocketAddress *out_addr,
|
|
||||||
int64_t *timestamp)
|
|
||||||
{
|
{
|
||||||
sockaddr_storage addr_storage;
|
sockaddr_storage addr_storage;
|
||||||
socklen_t addr_len = sizeof(addr_storage);
|
socklen_t addr_len = sizeof(addr_storage);
|
||||||
@ -534,12 +504,10 @@ PhysicalSocket::DoReadFromSocket(void *buffer,
|
|||||||
|
|
||||||
int received = 0;
|
int received = 0;
|
||||||
if (out_addr) {
|
if (out_addr) {
|
||||||
received = ::recvfrom(s_, static_cast<char *>(buffer),
|
received = ::recvfrom(s_, static_cast<char *>(buffer), static_cast<int>(length), 0, addr, &addr_len);
|
||||||
static_cast<int>(length), 0, addr, &addr_len);
|
|
||||||
SocketAddressFromSockAddrStorage(addr_storage, out_addr);
|
SocketAddressFromSockAddrStorage(addr_storage, out_addr);
|
||||||
} else {
|
} else {
|
||||||
received = ::recv(s_, static_cast<char *>(buffer),
|
received = ::recv(s_, static_cast<char *>(buffer), static_cast<int>(length), 0);
|
||||||
static_cast<int>(length), 0);
|
|
||||||
}
|
}
|
||||||
if (timestamp) { *timestamp = GetSocketRecvTimestamp(s_); }
|
if (timestamp) { *timestamp = GetSocketRecvTimestamp(s_); }
|
||||||
|
|
||||||
@ -592,10 +560,7 @@ PhysicalSocket::Close()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SOCKET
|
SOCKET
|
||||||
PhysicalSocket::DoAccept(SOCKET socket, sockaddr *addr, socklen_t *addrlen)
|
PhysicalSocket::DoAccept(SOCKET socket, sockaddr *addr, socklen_t *addrlen) { return ::accept(socket, addr, addrlen); }
|
||||||
{
|
|
||||||
return ::accept(socket, addr, addrlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
PhysicalSocket::DoSend(SOCKET socket, const char *buf, int len, int flags)
|
PhysicalSocket::DoSend(SOCKET socket, const char *buf, int len, int flags)
|
||||||
@ -617,9 +582,7 @@ PhysicalSocket::DoSendTo(SOCKET socket,
|
|||||||
int
|
int
|
||||||
PhysicalSocket::DoConnect(const SocketAddress &connect_addr)
|
PhysicalSocket::DoConnect(const SocketAddress &connect_addr)
|
||||||
{
|
{
|
||||||
if ((s_ == INVALID_SOCKET) && !Create(connect_addr.family(), SOCK_STREAM)) {
|
if ((s_ == INVALID_SOCKET) && !Create(connect_addr.family(), SOCK_STREAM)) { return SOCKET_ERROR; }
|
||||||
return SOCKET_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_storage addr_storage;
|
sockaddr_storage addr_storage;
|
||||||
size_t len = connect_addr.ToSockAddrStorage(&addr_storage);
|
size_t len = connect_addr.ToSockAddrStorage(&addr_storage);
|
||||||
@ -702,13 +665,9 @@ PhysicalSocket::TranslateOption(Option opt, int *slevel, int *sopt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss)
|
SocketDispatcher::SocketDispatcher(PhysicalSocketServer *ss) : PhysicalSocket(ss) {}
|
||||||
: PhysicalSocket(ss)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss)
|
SocketDispatcher::SocketDispatcher(SOCKET s, PhysicalSocketServer *ss) : PhysicalSocket(ss, s) {}
|
||||||
: PhysicalSocket(ss, s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
SocketDispatcher::~SocketDispatcher() { Close(); }
|
SocketDispatcher::~SocketDispatcher() { Close(); }
|
||||||
|
|
||||||
|
56
src/synchronization/sequence_checker.cc
Normal file
56
src/synchronization/sequence_checker.cc
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "sled/synchronization/sequence_checker.h"
|
||||||
|
|
||||||
|
namespace sled {
|
||||||
|
SequenceChecker::SequenceChecker(InitialState initial_state)
|
||||||
|
: attached_(initial_state),
|
||||||
|
valid_thread_(pthread_self()),
|
||||||
|
valid_queue_(TaskQueueBase::Current())
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SequenceChecker::IsCurrent() const
|
||||||
|
{
|
||||||
|
const TaskQueueBase *const current_queue = TaskQueueBase::Current();
|
||||||
|
const pthread_t current_thread = pthread_self();
|
||||||
|
MutexLock lock(&mutex_);
|
||||||
|
if (!attached_) {
|
||||||
|
attached_ = true;
|
||||||
|
valid_thread_ = current_thread;
|
||||||
|
valid_queue_ = current_queue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_queue_) { return valid_queue_ == current_queue; }
|
||||||
|
return pthread_equal(valid_thread_, current_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SequenceChecker::Detach()
|
||||||
|
{
|
||||||
|
MutexLock lock(&mutex_);
|
||||||
|
attached_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
SequenceChecker::ExpectationToString() const
|
||||||
|
{
|
||||||
|
const TaskQueueBase *const current_queue = TaskQueueBase::Current();
|
||||||
|
const pthread_t current_thread = pthread_self();
|
||||||
|
|
||||||
|
MutexLock lock(&mutex_);
|
||||||
|
if (!attached_) { return "Checker currently not attached."; }
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "# Expected: TQ: " << valid_queue_ << " Thread: " << reinterpret_cast<const void *>(valid_thread_)
|
||||||
|
<< std::endl;
|
||||||
|
ss << "# Current: TQ: " << current_queue << " Thread: " << reinterpret_cast<const void *>(current_thread)
|
||||||
|
<< std::endl;
|
||||||
|
if ((valid_queue_ || current_queue) && valid_queue_ != current_queue) {
|
||||||
|
ss << "# Mismatched TaskQueue" << std::endl;
|
||||||
|
} else if (valid_thread_ != current_thread) {
|
||||||
|
ss << "# Mismatched Thread" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
}// namespace sled
|
@ -1,13 +0,0 @@
|
|||||||
#include "sled/synchronization/sequence_checker_internal.h"
|
|
||||||
|
|
||||||
namespace sled {
|
|
||||||
SequenceCheckerImpl::SequenceCheckerImpl(bool attach_to_current_thread)
|
|
||||||
: attached_(attach_to_current_thread)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
SequenceCheckerImpl::IsCurrent() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}// namespace sled
|
|
68
src/synchronization/sequence_checker_test.cc
Normal file
68
src/synchronization/sequence_checker_test.cc
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <sled/log/log.h>
|
||||||
|
#include <sled/synchronization/event.h>
|
||||||
|
#include <sled/synchronization/sequence_checker.h>
|
||||||
|
#include <sled/system/thread.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
RunOnDifferentThread(std::function<void()> func)
|
||||||
|
{
|
||||||
|
sled::Event thread_has_run_event;
|
||||||
|
std::thread thread([&] {
|
||||||
|
func();
|
||||||
|
thread_has_run_event.Set();
|
||||||
|
});
|
||||||
|
thread.detach();
|
||||||
|
EXPECT_TRUE(thread_has_run_event.Wait(sled::TimeDelta::Seconds(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SequenceChecker, CallsAllowedOnSameThread)
|
||||||
|
{
|
||||||
|
sled::SequenceChecker sequence_checker;
|
||||||
|
EXPECT_TRUE(sequence_checker.IsCurrent());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SequenceChecker, DestructorAllowedOnDifferentThread)
|
||||||
|
{
|
||||||
|
auto sequence_checker = std::make_unique<sled::SequenceChecker>();
|
||||||
|
RunOnDifferentThread([&] { sequence_checker.reset(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SequenceChecker, Detach)
|
||||||
|
{
|
||||||
|
sled::SequenceChecker sequence_checker;
|
||||||
|
sequence_checker.Detach();
|
||||||
|
|
||||||
|
RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SequenceChecker, OnlyCurrentOnOneThread)
|
||||||
|
{
|
||||||
|
sled::SequenceChecker sequence_checker(sled::SequenceChecker::kDetached);
|
||||||
|
RunOnDifferentThread([&] {
|
||||||
|
EXPECT_TRUE(sequence_checker.IsCurrent());
|
||||||
|
RunOnDifferentThread([&] { EXPECT_FALSE(sequence_checker.IsCurrent()); });
|
||||||
|
EXPECT_TRUE(sequence_checker.IsCurrent());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SequenceChecker, DeatchFromThreadAndUseOnTaskQueue)
|
||||||
|
{
|
||||||
|
auto queue = sled::Thread::Create();
|
||||||
|
ASSERT_TRUE(queue->Start());
|
||||||
|
sled::SequenceChecker sequence_checker;
|
||||||
|
sequence_checker.Detach();
|
||||||
|
queue->BlockingCall([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SequenceChecker, DetachFromTaskQueueAndUseOnThread)
|
||||||
|
{
|
||||||
|
auto queue = sled::Thread::Create();
|
||||||
|
ASSERT_TRUE(queue->Start());
|
||||||
|
queue->BlockingCall([&] {
|
||||||
|
sled::SequenceChecker sequence_checker;
|
||||||
|
sequence_checker.Detach();
|
||||||
|
RunOnDifferentThread([&] { EXPECT_TRUE(sequence_checker.IsCurrent()); });
|
||||||
|
});
|
||||||
|
queue->Stop();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user