Change Mac platform impl to inherit from Unix base

This commit is contained in:
Wojtek Figat
2021-12-29 17:01:58 +01:00
parent 378ddc66c7
commit 0dbbdc9149
25 changed files with 105 additions and 631 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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__)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,7 +0,0 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#if PLATFORM_MAC
// TODO: networking on Mac
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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&);

View File

@@ -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:

View File

@@ -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;
}
}
}
}

View File

@@ -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()
{

View File

@@ -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);
}
}