Change Mac platform impl to inherit from Unix base
This commit is contained in:
@@ -4,12 +4,10 @@
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||
#include "Win32/Win32ConditionVariable.h"
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC
|
||||
#include "Unix/UnixConditionVariable.h"
|
||||
#elif PLATFORM_SWITCH
|
||||
#include "Platforms/Switch/Engine/Platform/SwitchConditionVariable.h"
|
||||
#elif PLATFORM_MAC
|
||||
#include "Mac/MacConditionVariable.h"
|
||||
#else
|
||||
#error Missing Condition Variable implementation!
|
||||
#endif
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||
#include "Win32/Win32CriticalSection.h"
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC
|
||||
#include "Unix/UnixCriticalSection.h"
|
||||
#elif PLATFORM_SWITCH
|
||||
#include "Platforms/Switch/Engine/Platform/SwitchCriticalSection.h"
|
||||
#elif PLATFORM_MAC
|
||||
#include "Mac/MacCriticalSection.h"
|
||||
#else
|
||||
#error Missing Critical Section implementation!
|
||||
#endif
|
||||
|
||||
@@ -192,8 +192,8 @@ API_ENUM() enum class ArchitectureType
|
||||
// Platform family defines
|
||||
#define PLATFORM_WINDOWS_FAMILY (PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT)
|
||||
#define PLATFORM_MICROSOFT_FAMILY (PLATFORM_WINDOWS_FAMILY)
|
||||
#define PLATFORM_UNIX_FAMILY (PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5)
|
||||
#define PLATFORM_APPLE_FAMILY (PLATFORM_MAC || PLATFORM_IOS)
|
||||
#define PLATFORM_UNIX_FAMILY (PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_APPLE_FAMILY)
|
||||
|
||||
// SIMD defines
|
||||
#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(__SSE2__)
|
||||
|
||||
@@ -4,14 +4,12 @@
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||
#include "Win32/Win32File.h"
|
||||
#elif PLATFORM_LINUX || PLATFORM_PS4 || PLATFORM_PS5
|
||||
#elif PLATFORM_LINUX || PLATFORM_PS4 || PLATFORM_PS5 || PLATFORM_MAC
|
||||
#include "Unix/UnixFile.h"
|
||||
#elif PLATFORM_ANDROID
|
||||
#include "Android/AndroidFile.h"
|
||||
#elif PLATFORM_SWITCH
|
||||
#include "Platforms/Switch/Engine/Platform/SwitchFile.h"
|
||||
#elif PLATFORM_MAC
|
||||
#include "Mac/MacFile.h"
|
||||
#else
|
||||
#error Missing File implementation!
|
||||
#endif
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "MacCriticalSection.h"
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/// <summary>
|
||||
/// Mac implementation of a condition variables. Condition variables are synchronization primitives that enable threads to wait until a particular condition occurs. Condition variables enable threads to atomically release a lock and enter the sleeping state.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API MacConditionVariable
|
||||
{
|
||||
private:
|
||||
|
||||
pthread_cond_t _cond;
|
||||
|
||||
private:
|
||||
|
||||
MacConditionVariable(const MacConditionVariable&);
|
||||
MacConditionVariable& operator=(const MacConditionVariable&);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MacConditionVariable"/> class.
|
||||
/// </summary>
|
||||
MacConditionVariable()
|
||||
{
|
||||
pthread_cond_init(&_cond, nullptr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="MacConditionVariable"/> class.
|
||||
/// </summary>
|
||||
~MacConditionVariable()
|
||||
{
|
||||
pthread_cond_destroy(&_cond);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Blocks the current thread execution until the condition variable is woken up.
|
||||
/// </summary>
|
||||
/// <param name="lock">The critical section locked by the current thread.</param>
|
||||
void Wait(const MacCriticalSection& lock)
|
||||
{
|
||||
pthread_cond_wait(&_cond, lock._mutexPtr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blocks the current thread execution until the condition variable is woken up or after the specified timeout duration.
|
||||
/// </summary>
|
||||
/// <param name="lock">The critical section locked by the current thread.</param>
|
||||
/// <param name="timeout">The time-out interval, in milliseconds. If the time-out interval elapses, the function re-acquires the critical section and returns zero. If timeout is zero, the function tests the states of the specified objects and returns immediately. If timeout is INFINITE, the function's time-out interval never elapses.</param>
|
||||
/// <returns>If the function succeeds, the return value is true, otherwise, if the function fails or the time-out interval elapses, the return value is false.</returns>
|
||||
bool Wait(const MacCriticalSection& lock, const int32 timeout)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
ts.tv_sec = time(NULL) + timeout / 1000;
|
||||
ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timeout % 1000);
|
||||
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
|
||||
ts.tv_nsec %= (1000 * 1000 * 1000);
|
||||
|
||||
return pthread_cond_timedwait(&_cond, lock._mutexPtr, &ts) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies one waiting thread.
|
||||
/// </summary>
|
||||
void NotifyOne()
|
||||
{
|
||||
pthread_cond_signal(&_cond);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies all waiting threads.
|
||||
/// </summary>
|
||||
void NotifyAll()
|
||||
{
|
||||
pthread_cond_broadcast(&_cond);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,91 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "Engine/Platform/Platform.h"
|
||||
#include <pthread.h>
|
||||
|
||||
class MacConditionVariable;
|
||||
|
||||
/// <summary>
|
||||
/// Mac implementation of a critical section.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API MacCriticalSection
|
||||
{
|
||||
friend MacConditionVariable;
|
||||
private:
|
||||
|
||||
pthread_mutex_t _mutex;
|
||||
pthread_mutex_t* _mutexPtr;
|
||||
#if BUILD_DEBUG
|
||||
pthread_t _owningThreadId;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
MacCriticalSection(const MacCriticalSection&);
|
||||
MacCriticalSection& operator=(const MacCriticalSection&);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MacCriticalSection"/> class.
|
||||
/// </summary>
|
||||
MacCriticalSection()
|
||||
{
|
||||
pthread_mutexattr_t attributes;
|
||||
pthread_mutexattr_init(&attributes);
|
||||
pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&_mutex, &attributes);
|
||||
pthread_mutexattr_destroy(&attributes);
|
||||
_mutexPtr = &_mutex;
|
||||
#if BUILD_DEBUG
|
||||
_owningThreadId = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="MacCriticalSection"/> class.
|
||||
/// </summary>
|
||||
~MacCriticalSection()
|
||||
{
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Locks the critical section.
|
||||
/// </summary>
|
||||
void Lock() const
|
||||
{
|
||||
pthread_mutex_lock(_mutexPtr);
|
||||
#if BUILD_DEBUG
|
||||
((MacCriticalSection*)this)->_owningThreadId = pthread_self();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to enter a critical section without blocking. If the call is successful, the calling thread takes ownership of the critical section.
|
||||
/// </summary>
|
||||
/// <returns>True if calling thread took ownership of the critical section.</returns>
|
||||
bool TryLock() const
|
||||
{
|
||||
return pthread_mutex_trylock(_mutexPtr) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the lock on the critical section.
|
||||
/// </summary>
|
||||
void Unlock() const
|
||||
{
|
||||
#if BUILD_DEBUG
|
||||
((MacCriticalSection*)this)->_owningThreadId = 0;
|
||||
#endif
|
||||
pthread_mutex_unlock(_mutexPtr);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "../Unix/UnixDefines.h"
|
||||
|
||||
// Platform description
|
||||
#define PLATFORM_64BITS 1
|
||||
#define PLATFORM_ARCH_X64 1
|
||||
@@ -13,7 +15,5 @@
|
||||
#define PLATFORM_CACHE_LINE_SIZE 128
|
||||
#define PLATFORM_HAS_HEADLESS_MODE 1
|
||||
#define PLATFORM_DEBUG_BREAK __builtin_trap()
|
||||
#define PLATFORM_LINE_TERMINATOR "\n"
|
||||
#define PLATFORM_TEXT_IS_CHAR16 1
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "../File.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
#include "Engine/Core/Types/TimeSpan.h"
|
||||
#include "Engine/Utilities/StringConverter.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cerrno>
|
||||
|
||||
MacFile::MacFile(int32 handle)
|
||||
: _handle(handle)
|
||||
{
|
||||
}
|
||||
|
||||
MacFile::~MacFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
MacFile* MacFile::Open(const StringView& path, FileMode mode, FileAccess access, FileShare share)
|
||||
{
|
||||
int flags = O_CLOEXEC;
|
||||
switch (access)
|
||||
{
|
||||
case FileAccess::Read:
|
||||
flags |= O_RDONLY;
|
||||
break;
|
||||
case FileAccess::Write:
|
||||
flags |= O_WRONLY;
|
||||
break;
|
||||
case FileAccess::ReadWrite:
|
||||
flags |= O_RDWR;
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
switch (mode)
|
||||
{
|
||||
case FileMode::CreateAlways:
|
||||
flags |= O_CREAT | O_TRUNC;
|
||||
break;
|
||||
case FileMode::CreateNew:
|
||||
flags |= O_CREAT | O_EXCL;
|
||||
break;
|
||||
case FileMode::OpenAlways:
|
||||
break;
|
||||
case FileMode::OpenExisting:
|
||||
break;
|
||||
case FileMode::TruncateExisting:
|
||||
flags |= O_TRUNC;
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
|
||||
mode_t omode = S_IRUSR | S_IWUSR;
|
||||
if ((uint32)share & (uint32)FileShare::Delete)
|
||||
omode |= 0;
|
||||
if ((uint32)share & (uint32)FileShare::Read)
|
||||
omode |= (mode_t)(S_IRGRP | S_IROTH);
|
||||
if ((uint32)share & (uint32)FileShare::Write)
|
||||
omode |= (mode_t)(S_IWGRP | S_IWOTH);
|
||||
if ((uint32)share & (uint32)FileShare::Delete)
|
||||
omode |= 0;
|
||||
|
||||
const StringAsANSI<> pathANSI(*path, path.Length());
|
||||
auto handle = open(pathANSI.Get(), flags, omode);
|
||||
if (handle == -1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return New<MacFile>(handle);
|
||||
}
|
||||
|
||||
bool MacFile::Read(void* buffer, uint32 bytesToRead, uint32* bytesRead)
|
||||
{
|
||||
const ssize_t tmp = read(_handle, buffer, bytesToRead);
|
||||
if (tmp != -1)
|
||||
{
|
||||
if (bytesRead)
|
||||
*bytesRead = tmp;
|
||||
return false;
|
||||
}
|
||||
if (bytesRead)
|
||||
*bytesRead = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacFile::Write(const void* buffer, uint32 bytesToWrite, uint32* bytesWritten)
|
||||
{
|
||||
const ssize_t tmp = write(_handle, buffer, bytesToWrite);
|
||||
if (tmp != -1)
|
||||
{
|
||||
if (bytesWritten)
|
||||
*bytesWritten = tmp;
|
||||
return false;
|
||||
}
|
||||
if (bytesWritten)
|
||||
*bytesWritten = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacFile::Close()
|
||||
{
|
||||
if (_handle != -1)
|
||||
{
|
||||
close(_handle);
|
||||
_handle = -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 MacFile::GetSize() const
|
||||
{
|
||||
struct stat fileInfo;
|
||||
fstat(_handle, &fileInfo);
|
||||
return fileInfo.st_size;
|
||||
}
|
||||
|
||||
DateTime MacFile::GetLastWriteTime() const
|
||||
{
|
||||
struct stat fileInfo;
|
||||
if (fstat(_handle, &fileInfo) == -1)
|
||||
{
|
||||
return DateTime::MinValue();
|
||||
}
|
||||
const TimeSpan timeSinceEpoch(0, 0, fileInfo.st_mtime);
|
||||
const DateTime MacEpoch(1970, 1, 1);
|
||||
return MacEpoch + timeSinceEpoch;
|
||||
}
|
||||
|
||||
uint32 MacFile::GetPosition() const
|
||||
{
|
||||
return lseek(_handle, 0, SEEK_CUR);
|
||||
}
|
||||
|
||||
void MacFile::SetPosition(uint32 seek)
|
||||
{
|
||||
lseek(_handle, seek, SEEK_SET);
|
||||
}
|
||||
|
||||
bool MacFile::IsOpened() const
|
||||
{
|
||||
return _handle != -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "Engine/Platform/Base/FileBase.h"
|
||||
|
||||
/// <summary>
|
||||
/// Mac platform file object implementation.
|
||||
/// </summary>
|
||||
class MacFile : public FileBase
|
||||
{
|
||||
protected:
|
||||
|
||||
int32 _handle;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MacFile"/> class.
|
||||
/// </summary>
|
||||
/// <param name="handle">The handle.</param>
|
||||
MacFile(int32 handle);
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="MacFile"/> class.
|
||||
/// </summary>
|
||||
~MacFile();
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Creates or opens a file.
|
||||
/// </summary>
|
||||
/// <param name="path">The name of the file to be created or opened.</param>
|
||||
/// <param name="mode">An action to take on a file that exists or does not exist.</param>
|
||||
/// <param name="access">The requested access to the file.</param>
|
||||
/// <param name="share">The requested sharing mode of the file.</param>
|
||||
/// <returns>Opened file handle or null if cannot.</returns>
|
||||
static MacFile* Open(const StringView& path, FileMode mode, FileAccess access = FileAccess::ReadWrite, FileShare share = FileShare::None);
|
||||
|
||||
public:
|
||||
|
||||
// [FileBase]
|
||||
bool Read(void* buffer, uint32 bytesToRead, uint32* bytesRead = nullptr) override;
|
||||
bool Write(const void* buffer, uint32 bytesToWrite, uint32* bytesWritten = nullptr) override;
|
||||
void Close() override;
|
||||
uint32 GetSize() const override;
|
||||
DateTime GetLastWriteTime() const override;
|
||||
uint32 GetPosition() const override;
|
||||
void SetPosition(uint32 seek) override;
|
||||
bool IsOpened() const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
// TODO: networking on Mac
|
||||
|
||||
#endif
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "Engine/Platform/Base/NetworkBase.h"
|
||||
|
||||
class FLAXENGINE_API MacNetwork : public NetworkBase
|
||||
{
|
||||
public:
|
||||
|
||||
// [NetworkBase]
|
||||
static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv);
|
||||
static bool DestroySocket(NetworkSocket& socket);
|
||||
static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value);
|
||||
static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32& value);
|
||||
static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint);
|
||||
static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint);
|
||||
static bool Listen(NetworkSocket& socket, uint16 queueSize);
|
||||
static bool Accept(NetworkSocket& serverSocket, NetworkSocket& newSocket, NetworkEndPoint& newEndPoint);
|
||||
static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr);
|
||||
static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr);
|
||||
static bool CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -80,50 +80,6 @@ public:
|
||||
typedef uint16_t offset_t;
|
||||
#define align_mem_up(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
void* MacPlatform::Allocate(uint64 size, uint64 alignment)
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
|
||||
// Alignment always has to be power of two
|
||||
ASSERT_LOW_LAYER((alignment & (alignment - 1)) == 0);
|
||||
|
||||
if (alignment && size)
|
||||
{
|
||||
uint32_t pad = sizeof(offset_t) + (alignment - 1);
|
||||
void* p = malloc(size + pad);
|
||||
if (p)
|
||||
{
|
||||
// Add the offset size to malloc's pointer
|
||||
ptr = (void*)align_mem_up(((uintptr_t)p + sizeof(offset_t)), alignment);
|
||||
|
||||
// Calculate the offset and store it behind aligned pointer
|
||||
*((offset_t*)ptr - 1) = (offset_t)((uintptr_t)ptr - (uintptr_t)p);
|
||||
}
|
||||
#if COMPILE_WITH_PROFILER
|
||||
OnMemoryAlloc(ptr, size);
|
||||
#endif
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void MacPlatform::Free(void* ptr)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
#if COMPILE_WITH_PROFILER
|
||||
OnMemoryFree(ptr);
|
||||
#endif
|
||||
// Walk backwards from the passed-in pointer to get the pointer offset
|
||||
offset_t offset = *((offset_t*)ptr - 1);
|
||||
|
||||
// Get original pointer
|
||||
void* p = (void*)((uint8_t*)ptr - offset);
|
||||
|
||||
// Free memory
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
bool MacPlatform::Is64BitPlatform()
|
||||
{
|
||||
return PLATFORM_64BITS;
|
||||
@@ -237,7 +193,7 @@ void MacPlatform::GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32&
|
||||
|
||||
bool MacPlatform::Init()
|
||||
{
|
||||
if (PlatformBase::Init())
|
||||
if (UnixPlatform::Init())
|
||||
return true;
|
||||
|
||||
// Init timing
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
/// <summary>
|
||||
/// The Mac platform implementation and application management utilities.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API MacPlatform : public PlatformBase
|
||||
class FLAXENGINE_API MacPlatform : public UnixPlatform
|
||||
{
|
||||
public:
|
||||
|
||||
// [PlatformBase]
|
||||
// [UnixPlatform]
|
||||
FORCE_INLINE static void MemoryBarrier()
|
||||
{
|
||||
__sync_synchronize();
|
||||
@@ -66,14 +66,11 @@ public:
|
||||
{
|
||||
__builtin_prefetch(static_cast<char const*>(ptr));
|
||||
}
|
||||
static void* Allocate(uint64 size, uint64 alignment);
|
||||
static void Free(void* ptr);
|
||||
static bool Is64BitPlatform();
|
||||
static CPUInfo GetCPUInfo();
|
||||
static int32 GetCacheLineSize();
|
||||
static MemoryStats GetMemoryStats();
|
||||
static ProcessMemoryStats GetProcessMemoryStats();
|
||||
static uint64 GetCurrentProcessId();
|
||||
static uint64 GetCurrentThreadID();
|
||||
static void SetThreadPriority(ThreadPriority priority);
|
||||
static void SetThreadAffinityMask(uint64 affinityMask);
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "Engine/Platform/StringUtils.h"
|
||||
#include <wctype.h>
|
||||
#include <cctype>
|
||||
#include <wchar.h>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Reuse Unix-impl
|
||||
#define PLATFORM_UNIX 1
|
||||
#include "../Unix/UnixStringUtils.cpp"
|
||||
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "MacThread.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Threading/IRunnable.h"
|
||||
#include "Engine/Threading/ThreadRegistry.h"
|
||||
|
||||
MacThread::MacThread(IRunnable* runnable, const String& name, ThreadPriority priority)
|
||||
: ThreadBase(runnable, name, priority)
|
||||
, _thread(0)
|
||||
{
|
||||
}
|
||||
|
||||
MacThread::~MacThread()
|
||||
{
|
||||
ASSERT(_thread == 0);
|
||||
}
|
||||
|
||||
MacThread* MacThread::Create(IRunnable* runnable, const String& name, ThreadPriority priority, uint32 stackSize)
|
||||
{
|
||||
auto thread = New<MacThread>(runnable, name, priority);
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
if (stackSize != 0)
|
||||
pthread_attr_setstacksize(&attr, stackSize);
|
||||
const int32 result = pthread_create(&thread->_thread, &attr, ThreadProc, thread);
|
||||
if (result != 0)
|
||||
{
|
||||
LOG(Warning, "Failed to spawn a thread. Result code: {0}", result);
|
||||
Delete(thread);
|
||||
return nullptr;
|
||||
}
|
||||
thread->SetPriorityInternal(thread->GetPriority());
|
||||
return thread;
|
||||
}
|
||||
|
||||
void MacThread::Join()
|
||||
{
|
||||
pthread_join(_thread, nullptr);
|
||||
}
|
||||
|
||||
void* MacThread::ThreadProc(void* pThis)
|
||||
{
|
||||
auto thread = (MacThread*)pThis;
|
||||
const int32 exitCode = thread->Run();
|
||||
return (void*)(uintptr)exitCode;
|
||||
}
|
||||
|
||||
void MacThread::ClearHandleInternal()
|
||||
{
|
||||
_thread = 0;
|
||||
}
|
||||
|
||||
void MacThread::SetPriorityInternal(ThreadPriority priority)
|
||||
{
|
||||
// TODO: impl this
|
||||
}
|
||||
|
||||
void MacThread::KillInternal(bool waitForJoin)
|
||||
{
|
||||
if (waitForJoin)
|
||||
pthread_join(_thread, nullptr);
|
||||
pthread_kill(_thread, SIGKILL);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -4,34 +4,72 @@
|
||||
|
||||
#if PLATFORM_MAC
|
||||
|
||||
#include "../Base/ThreadBase.h"
|
||||
#include "../Unix/UnixThread.h"
|
||||
#include <signal.h>
|
||||
|
||||
/// <summary>
|
||||
/// Thread object for Mac platform.
|
||||
/// </summary>
|
||||
class MacThread : public ThreadBase
|
||||
class MacThread : public UnixThread
|
||||
{
|
||||
protected:
|
||||
|
||||
pthread_t _thread;
|
||||
|
||||
public:
|
||||
|
||||
MacThread(IRunnable* runnable, const String& name, ThreadPriority priority);
|
||||
~MacThread();
|
||||
static MacThread* Create(IRunnable* runnable, const String& name, ThreadPriority priority = ThreadPriority::Normal, uint32 stackSize = 0);
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MacThread"/> class.
|
||||
/// </summary>
|
||||
/// <param name="runnable">The runnable.</param>
|
||||
/// <param name="name">The thread name.</param>
|
||||
/// <param name="priority">The thread priority.</param>
|
||||
MacThread(IRunnable* runnable, const String& name, ThreadPriority priority)
|
||||
: UnixThread(runnable, name, priority)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// [ThreadBase]
|
||||
void Join() override;
|
||||
/// <summary>
|
||||
/// Factory method to create a thread with the specified stack size and thread priority
|
||||
/// </summary>
|
||||
/// <param name="runnable">The runnable object to execute</param>
|
||||
/// <param name="name">Name of the thread</param>
|
||||
/// <param name="priority">Tells the thread whether it needs to adjust its priority or not. Defaults to normal priority</param>
|
||||
/// <param name="stackSize">The size of the stack to create. 0 means use the current thread's stack size</param>
|
||||
/// <returns>Pointer to the new thread or null if cannot create it</returns>
|
||||
static MacThread* Create(IRunnable* runnable, const String& name, ThreadPriority priority = ThreadPriority::Normal, uint32 stackSize = 0)
|
||||
{
|
||||
return (MacThread*)Setup(New<MacThread>(runnable, name, priority), stackSize);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static void* ThreadProc(void* pThis);
|
||||
|
||||
// [ThreadBase]
|
||||
void ClearHandleInternal() override;
|
||||
void SetPriorityInternal(ThreadPriority priority) override;
|
||||
void KillInternal(bool waitForJoin) override;
|
||||
// [UnixThread]
|
||||
int32 GetThreadPriority(ThreadPriority priority) override
|
||||
{
|
||||
switch (priority)
|
||||
{
|
||||
case ThreadPriority::Highest:
|
||||
return 45;
|
||||
case ThreadPriority::AboveNormal:
|
||||
return 37;
|
||||
case ThreadPriority::Normal:
|
||||
return 31;
|
||||
case ThreadPriority::BelowNormal:
|
||||
return 25;
|
||||
case ThreadPriority::Lowest:
|
||||
return 20;
|
||||
}
|
||||
return 31;
|
||||
}
|
||||
int32 Start(pthread_attr_t& attr) override
|
||||
{
|
||||
return pthread_create(&_thread, &attr, ThreadProc, this);
|
||||
}
|
||||
void KillInternal(bool waitForJoin) override
|
||||
{
|
||||
if (waitForJoin)
|
||||
pthread_join(_thread, nullptr);
|
||||
pthread_kill(_thread, SIGKILL);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_UWP || PLATFORM_XBOX_ONE || PLATFORM_XBOX_SCARLETT
|
||||
#include "Win32/Win32Network.h"
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID
|
||||
#elif PLATFORM_LINUX || PLATFORM_ANDROID || PLATFORM_MAC
|
||||
#include "Unix/UnixNetwork.h"
|
||||
#elif PLATFORM_PS4
|
||||
#include "Platforms/PS4/Engine/Platform/PS4Network.h"
|
||||
|
||||
@@ -78,6 +78,7 @@ public class Platform : EngineModule
|
||||
options.SourcePaths.Add(Path.Combine(Globals.EngineRoot, "Source", "Platforms", "Switch", "Engine", "Platform"));
|
||||
break;
|
||||
case TargetPlatform.Mac:
|
||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Unix"));
|
||||
options.SourcePaths.Add(Path.Combine(FolderPath, "Mac"));
|
||||
break;
|
||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||
|
||||
@@ -231,24 +231,24 @@ typedef UserBase User;
|
||||
|
||||
class ClipboardBase;
|
||||
typedef ClipboardBase Clipboard;
|
||||
class MacCriticalSection;
|
||||
typedef MacCriticalSection CriticalSection;
|
||||
class MacConditionVariable;
|
||||
typedef MacConditionVariable ConditionVariable;
|
||||
class UnixCriticalSection;
|
||||
typedef UnixCriticalSection CriticalSection;
|
||||
class UnixConditionVariable;
|
||||
typedef UnixConditionVariable ConditionVariable;
|
||||
class MacFileSystem;
|
||||
typedef MacFileSystem FileSystem;
|
||||
class FileSystemWatcherBase;
|
||||
typedef FileSystemWatcherBase FileSystemWatcher;
|
||||
class MacFile;
|
||||
typedef MacFile File;
|
||||
class UnixFile;
|
||||
typedef UnixFile File;
|
||||
class MacPlatform;
|
||||
typedef MacPlatform Platform;
|
||||
class MacThread;
|
||||
typedef MacThread Thread;
|
||||
class MacWindow;
|
||||
typedef MacWindow Window;
|
||||
class MacNetwork;
|
||||
typedef MacNetwork Network;
|
||||
class UnixNetwork;
|
||||
typedef UnixNetwork Network;
|
||||
class UserBase;
|
||||
typedef UserBase User;
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ private:
|
||||
|
||||
pthread_cond_t _cond;
|
||||
|
||||
private:
|
||||
|
||||
UnixConditionVariable(const UnixConditionVariable&);
|
||||
UnixConditionVariable& operator=(const UnixConditionVariable&);
|
||||
|
||||
@@ -61,13 +59,11 @@ public:
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
ts.tv_sec = time(NULL) + timeout / 1000;
|
||||
ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timeout % 1000);
|
||||
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
|
||||
ts.tv_nsec %= (1000 * 1000 * 1000);
|
||||
|
||||
return pthread_cond_timedwait(&_cond, lock._mutexPtr, &ts) == 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ class UnixConditionVariable;
|
||||
class FLAXENGINE_API UnixCriticalSection
|
||||
{
|
||||
friend UnixConditionVariable;
|
||||
|
||||
private:
|
||||
|
||||
pthread_mutex_t _mutex;
|
||||
@@ -24,8 +23,6 @@ private:
|
||||
pthread_t _owningThreadId;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
UnixCriticalSection(const UnixCriticalSection&);
|
||||
UnixCriticalSection& operator=(const UnixCriticalSection&);
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ static void TranslateSockOptToNative(NetworkSocketOption option, int32* level, i
|
||||
SOCKOPT(NetworkSocketOption::NoDelay, IPPROTO_TCP, TCP_NODELAY)
|
||||
#endif
|
||||
SOCKOPT(NetworkSocketOption::IPv6Only, IPPROTO_IPV6, IPV6_V6ONLY)
|
||||
#ifdef IP_MTU
|
||||
SOCKOPT(NetworkSocketOption::Mtu, IPPROTO_IP, IP_MTU)
|
||||
#endif
|
||||
SOCKOPT(NetworkSocketOption::Type, SOL_SOCKET, SO_TYPE)
|
||||
#undef SOCKOPT
|
||||
default:
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Flax.Build.Platforms
|
||||
/// <summary>
|
||||
/// The build platform for all Mac systems.
|
||||
/// </summary>
|
||||
/// <seealso cref="Platform" />
|
||||
public sealed class MacPlatform : Platform
|
||||
/// <seealso cref="UnixPlatform" />
|
||||
public sealed class MacPlatform : UnixPlatform
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override TargetPlatform Target => TargetPlatform.Mac;
|
||||
@@ -22,24 +22,15 @@ namespace Flax.Build.Platforms
|
||||
/// <inheritdoc />
|
||||
public override bool HasSharedLibrarySupport => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ExecutableFileExtension => string.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SharedLibraryFileExtension => ".dylib";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string StaticLibraryFileExtension => ".a";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ProgramDatabaseFileExtension => ".dSYM";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SharedLibraryFilePrefix => string.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string StaticLibraryFilePrefix => "lib";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ProjectFormat DefaultProjectFormat => ProjectFormat.XCode;
|
||||
|
||||
@@ -75,5 +66,15 @@ namespace Flax.Build.Platforms
|
||||
{
|
||||
return new MacToolchain(this, architecture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanBuildPlatform(TargetPlatform platform)
|
||||
{
|
||||
switch (platform)
|
||||
{
|
||||
case TargetPlatform.Mac: return HasRequiredSDKsInstalled;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,13 @@ namespace Flax.Build.Platforms
|
||||
/// <summary>
|
||||
/// The build toolchain for all Mac systems.
|
||||
/// </summary>
|
||||
/// <seealso cref="Toolchain" />
|
||||
public sealed class MacToolchain : Toolchain
|
||||
/// <seealso cref="UnixToolchain" />
|
||||
public sealed class MacToolchain : UnixToolchain
|
||||
{
|
||||
private string MinMacOSXVer = "10.14";
|
||||
|
||||
public string ToolchainPath;
|
||||
public string SdkPath;
|
||||
public string ClangPath;
|
||||
public string LinkerPath;
|
||||
public string ArchiverPath;
|
||||
|
||||
@@ -47,7 +46,7 @@ namespace Flax.Build.Platforms
|
||||
ClangPath = Path.Combine(ToolchainPath, "usr/bin/clang++");
|
||||
LinkerPath = Path.Combine(ToolchainPath, "usr/bin/clang++");
|
||||
ArchiverPath = Path.Combine(ToolchainPath, "usr/bin/libtool");
|
||||
var clangVersion = UnixToolchain.GetClangVersion(ClangPath);
|
||||
ClangVersion = GetClangVersion(ClangPath);
|
||||
SdkPath = Path.Combine(SdkPath, "SDKs");
|
||||
var sdks = Directory.GetDirectories(SdkPath);
|
||||
var sdkPrefix = "MacOSX";
|
||||
@@ -75,19 +74,13 @@ namespace Flax.Build.Platforms
|
||||
SdkPath = bestSdk;
|
||||
|
||||
// Setup system paths
|
||||
SystemIncludePaths.Add(Path.Combine(ToolchainPath, "usr/include"));
|
||||
SystemIncludePaths.Add(Path.Combine(ToolchainPath, "usr/include/c++/v1"));
|
||||
SystemIncludePaths.Add(Path.Combine(ToolchainPath, "usr/lib/clang", clangVersion.ToString(3), "include"));
|
||||
SystemIncludePaths.Add(Path.Combine(SdkPath, "usr/include"));
|
||||
//SystemIncludePaths.Add(Path.Combine(ToolchainPath, "usr/include"));
|
||||
//SystemIncludePaths.Add(Path.Combine(ToolchainPath, "usr/include/c++/v1"));
|
||||
//SystemIncludePaths.Add(Path.Combine(ToolchainPath, "usr/lib/clang", ClangVersion.ToString(3), "include"));
|
||||
//SystemIncludePaths.Add(Path.Combine(SdkPath, "usr/include"));
|
||||
SystemLibraryPaths.Add(Path.Combine(SdkPath, "usr/lib"));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string DllExport => "__attribute__((__visibility__(\\\"default\\\")))";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string DllImport => "";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void LogInfo()
|
||||
{
|
||||
|
||||
@@ -71,13 +71,15 @@ namespace Flax.Build.Platforms
|
||||
/// </summary>
|
||||
/// <param name="platform">The platform.</param>
|
||||
/// <param name="architecture">The target architecture.</param>
|
||||
/// <param name="toolchainRoots">The root folder for the toolchains installation.</param>
|
||||
/// <param name="toolchainRoots">The root folder for the toolchains installation. If null, then platform must specify tools paths manually.</param>
|
||||
/// <param name="systemCompiler">The system compiler to use. Null if use toolset root.</param>
|
||||
/// <param name="toolchainSubDir">The custom toolchain folder location in <paramref name="toolchainRoots"/> directory. If nul the architecture name will be used.</param>
|
||||
protected UnixToolchain(UnixPlatform platform, TargetArchitecture architecture, string toolchainRoots, string systemCompiler, string toolchainSubDir = null)
|
||||
protected UnixToolchain(UnixPlatform platform, TargetArchitecture architecture, string toolchainRoots = null, string systemCompiler = null, string toolchainSubDir = null)
|
||||
: base(platform, architecture)
|
||||
{
|
||||
ArchitectureName = GetToolchainName(platform.Target, architecture);
|
||||
if (toolchainRoots == null)
|
||||
return;
|
||||
|
||||
// Build paths
|
||||
if (systemCompiler != null)
|
||||
@@ -198,6 +200,12 @@ namespace Flax.Build.Platforms
|
||||
case TargetArchitecture.ARM64: return "aarch64-linux-android";
|
||||
default: throw new InvalidArchitectureException(architecture);
|
||||
}
|
||||
case TargetPlatform.Mac:
|
||||
switch (architecture)
|
||||
{
|
||||
case TargetArchitecture.x64: return "x86_64-apple-macos" + Configuration.MacOSXMinVer;
|
||||
default: throw new InvalidArchitectureException(architecture);
|
||||
}
|
||||
default: throw new InvalidPlatformException(platform);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user