Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MinGW-w64 fixes #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
ctags
/build/
build.bat

# vim temporaries
*.swp
*.un~
*.~
2 changes: 1 addition & 1 deletion include/eathread/eathread_callstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ namespace EA

#endif

#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_SONY)
#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_SONY) || defined(EA_PLATFORM_MINGW)
// GetPthreadStackInfo
//
// With some implementations of pthread, the stack base is returned by pthread as NULL if it's the main thread,
Expand Down
12 changes: 12 additions & 0 deletions include/eathread/eathread_futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@
#define _Must_inspect_result_
#endif

#ifndef _Out_
#define _Out_
#endif

#ifndef _Inout_
#define _Inout_
#endif

#ifndef _In_
#define _In_
#endif

struct _RTL_CRITICAL_SECTION;
__declspec(dllimport) _Must_inspect_result_ int __stdcall InitializeCriticalSectionAndSpinCount(_Out_ _RTL_CRITICAL_SECTION* pCriticalSection, _In_ unsigned long dwSpinCount);
__declspec(dllimport) void __stdcall InitializeCriticalSection(_Out_ _RTL_CRITICAL_SECTION* pCriticalSection);
Expand Down
8 changes: 4 additions & 4 deletions include/eathread/internal/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ EA_RESTORE_VC_WARNING()
// Defined as 0 or 1
//
#ifndef EA_POSIX_THREADS_AVAILABLE
#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_APPLE)
#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_MINGW)
#define EA_POSIX_THREADS_AVAILABLE 1
#elif defined(EA_PLATFORM_SONY)
#define EA_POSIX_THREADS_AVAILABLE 0 // POSIX threading API is present but use is discouraged by Sony. They want shipping code to use their scePthreads* API.
Expand Down Expand Up @@ -484,9 +484,9 @@ EA_RESTORE_VC_WARNING()
#define EATHREAD_GETCALLSTACK_SUPPORTED 1
#elif defined(EA_PLATFORM_WINDOWS_PHONE) && defined(EA_PROCESSOR_ARM)
#define EATHREAD_GETCALLSTACK_SUPPORTED 0
#elif defined(EA_PLATFORM_MICROSOFT)
#elif defined(EA_PLATFORM_MICROSOFT) && !defined(EA_PLATFORM_MINGW)
#define EATHREAD_GETCALLSTACK_SUPPORTED 1
#elif defined(EA_PLATFORM_LINUX)
#elif defined(EA_PLATFORM_LINUX) && !defined(EA_PLATFORM_CYGWIN)
#define EATHREAD_GETCALLSTACK_SUPPORTED 1
#elif defined(EA_PLATFORM_OSX)
#define EATHREAD_GETCALLSTACK_SUPPORTED 1
Expand Down Expand Up @@ -537,7 +537,7 @@ EA_RESTORE_VC_WARNING()
#elif defined(EA_PLATFORM_SONY)
#define EATHREAD_THREAD_AFFINITY_MASK_SUPPORTED 1
#elif defined(EA_USE_CPP11_CONCURRENCY) && EA_USE_CPP11_CONCURRENCY
// CPP11 doesn't not provided a mechanism to set thread affinities.
// CPP11 doesn't provide a mechanism to set thread affinities.
#define EATHREAD_THREAD_AFFINITY_MASK_SUPPORTED 0
#elif defined(EA_PLATFORM_ANDROID) || defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_UNIX)
#define EATHREAD_THREAD_AFFINITY_MASK_SUPPORTED 0
Expand Down
4 changes: 2 additions & 2 deletions source/eathread_callstack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

#include <EABase/eabase.h>

#if defined(EA_PLATFORM_WIN32) && EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP)
#if defined(EA_PLATFORM_WIN32) && EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP) && !defined(EA_PLATFORM_MINGW)
#include "pc/eathread_callstack_win32.cpp"
#elif defined(EA_PLATFORM_MICROSOFT) && defined(EA_PROCESSOR_X86_64)
#elif defined(EA_PLATFORM_MICROSOFT) && defined(EA_PROCESSOR_X86_64) && !defined(EA_PLATFORM_MINGW)
#include "pc/eathread_callstack_win64.cpp"
#elif defined(EA_PLATFORM_SONY)
#include "kettle/eathread_callstack_kettle.cpp"
Expand Down
2 changes: 1 addition & 1 deletion source/pc/eathread_thread_pc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ EA_DISABLE_VC_WARNING(6312 6322)

EAThreadGlobalVars() {}
EAThreadGlobalVars(const EAThreadGlobalVars&) {}
EAThreadGlobalVars& operator=(const EAThreadGlobalVars&) {}
EAThreadGlobalVars& operator=(const EAThreadGlobalVars&) { return *this; }
};
EATHREAD_GLOBALVARS_CREATE_INSTANCE;

Expand Down
4 changes: 2 additions & 2 deletions source/unix/eathread_callstack_glibc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ EATHREADLIB_API void SetStackBase(void* pStackBase)
//
EATHREADLIB_API void* GetStackBase()
{
#if defined(EA_PLATFORM_UNIX)
#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_MINGW)
void* pBase;
if(GetPthreadStackInfo(&pBase, NULL))
return pBase;
Expand All @@ -246,7 +246,7 @@ EATHREADLIB_API void* GetStackBase()
//
EATHREADLIB_API void* GetStackLimit()
{
#if defined(EA_PLATFORM_UNIX)
#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_MINGW)
void* pLimit;
if(GetPthreadStackInfo(NULL, &pLimit))
return pLimit;
Expand Down
25 changes: 24 additions & 1 deletion source/unix/eathread_pthread_stack_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
#include <pthread.h>
#endif

#if defined(EA_PLATFORM_MICROSOFT)
#include <Windows.h>
#endif

namespace EA
{
namespace Thread
{

#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_SONY)
#if defined(EA_PLATFORM_UNIX) || defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_SONY) || defined(EA_PLATFORM_MINGW)
// With some implementations of pthread, the stack base is returned by pthread as NULL if it's the main thread,
// or possibly if it's a thread you created but didn't call pthread_attr_setstack manually to provide your
// own stack. It's impossible for us to tell here whether will be such a NULL return value, so we just do what
Expand Down Expand Up @@ -80,6 +84,25 @@ namespace Thread

return returnValue;
}
#elif defined(EA_PLATFORM_MINGW)
bool GetPthreadStackInfo(void** pBase, void** pLimit)
{
// Do the same as Windows x64 here, but also use the same strategy for 32 bit builds.

// NtCurrentTeb is defined in <WinNT.h> as an inline call to __readgsqword
#if defined(EA_PROCESSOR_X86)
NT_TIB *pTIB = reinterpret_cast<NT_TIB*>(NtCurrentTeb());
#else // defined(EA_PROCESSOR_X64)
NT_TIB64* pTIB = reinterpret_cast<NT_TIB64*>(NtCurrentTeb());
#endif

if(pBase)
*pBase = reinterpret_cast<void*>(pTIB->StackBase);
if(pLimit)
*pLimit = reinterpret_cast<void*>(pTIB->StackLimit);

return true;
}
#else
bool GetPthreadStackInfo(void** pBase, void** pLimit)
{
Expand Down
72 changes: 42 additions & 30 deletions source/unix/eathread_thread_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ namespace
using namespace EA::Thread;

#if defined(EA_PLATFORM_WINDOWS)
param.sched_priority = THREAD_PRIORITY_NORMAL + (nPriority - kThreadPriorityDefault);
param.sched_priority = THREAD_PRIORITY_NORMAL + (eathreadPriority - kThreadPriorityDefault);

#elif defined(EA_PLATFORM_LINUX) && !defined(EA_PLATFORM_CYGWIN)
// We are assuming Kernel 2.6 and later behaviour, but perhaps we should dynamically detect.
Expand Down Expand Up @@ -177,7 +177,7 @@ namespace
{
EAT_ASSERT(pTP->mnStackSize != 0);

#if !defined(EA_PLATFORM_CYGWIN) // Some implementations of pthreads does not support pthread_attr_setstack.
#if !defined(EA_PLATFORM_CYGWIN) && !defined(EA_PLATFORM_MINGW) // Some implementations of pthreads does not support pthread_attr_setstack.
#if defined(PTHREAD_STACK_MIN)
EAT_ASSERT((pTP->mnStackSize >= PTHREAD_STACK_MIN));
#endif
Expand Down Expand Up @@ -235,6 +235,26 @@ namespace
pthread_setaffinity_np(pTDD->mThreadId, sizeof(cpus), &cpus);
// We don't assert on the pthread_setaffinity_np return value, as that could be very noisy for some users.
#endif
#elif defined(EA_PLATFORM_WINDOWS)
int nProcessorCount = EA::Thread::GetProcessorCount();

if(pTDD->mStartupProcessor < 0)
pTDD->mStartupProcessor = MAXIMUM_PROCESSORS;
else
{
if(pTDD->mStartupProcessor >= nProcessorCount)
pTDD->mStartupProcessor %= nProcessorCount;
}

void *winThreadId = pthread_gethandle(pTDD->mThreadId);
EAT_ASSERT(winThreadId);

// SetThreadIdealProcessor differs from SetThreadAffinityMask in that SetThreadIdealProcessor is not
// a strict assignment, and it allows the OS to move the thread if the ideal processor is busy.
// SetThreadAffinityMask is a more rigid assignment, but it can result in slower performance and
// possibly hangs due to processor contention between threads. For Windows we use SetIdealThreadProcessor
// in the name of safety and likely better overall performance.
::SetThreadIdealProcessor(winThreadId, pTDD->mStartupProcessor);
#endif
}
// Else the thread hasn't started yet, or has already exited. Let the thread set its own
Expand Down Expand Up @@ -543,6 +563,16 @@ static void* RunnableFunctionInternal(void* pContext)
SetPlatformThreadAffinity(pTDD);
else if(pTDD->mStartupProcessor == EA::Thread::kProcessorAny)
EA::Thread::SetThreadAffinityMask(pTDD->mnThreadAffinityMask);

#elif defined(EA_PLATFORM_MINGW)
pTDD->mThreadPid = getpid();

if(pTDD->mStartupProcessor != EA::Thread::kProcessorDefault
&& pTDD->mStartupProcessor != EA::Thread::kProcessorAny)
SetPlatformThreadAffinity(pTDD);
else if(pTDD->mStartupProcessor == EA::Thread::kProcessorAny)
EA::Thread::SetThreadAffinityMask(pTDD->mnThreadAffinityMask);

#elif !defined(EA_PLATFORM_CONSOLE) && !defined(EA_PLATFORM_MOBILE)
pTDD->mThreadPid = getpid(); // We can't set a thread affinity with a process id.
#else
Expand Down Expand Up @@ -607,6 +637,15 @@ static void* RunnableObjectInternal(void* pContext)
else if(pTDD->mStartupProcessor == EA::Thread::kProcessorAny)
EA::Thread::SetThreadAffinityMask(pTDD->mnThreadAffinityMask);

#elif defined(EA_PLATFORM_MINGW)
pTDD->mThreadPid = getpid();

if(pTDD->mStartupProcessor != EA::Thread::kProcessorDefault
&& pTDD->mStartupProcessor != EA::Thread::kProcessorAny)
SetPlatformThreadAffinity(pTDD);
else if(pTDD->mStartupProcessor == EA::Thread::kProcessorAny)
EA::Thread::SetThreadAffinityMask(pTDD->mnThreadAffinityMask);

#elif !defined(EA_PLATFORM_CONSOLE) && !defined(EA_PLATFORM_MOBILE)
pTDD->mThreadPid = getpid(); // We can't set a thread affinity with a process id.
#else
Expand Down Expand Up @@ -970,34 +1009,7 @@ bool EA::Thread::Thread::SetPriority(int nPriority)
// To consider: Make it so we return a value.
void EA::Thread::Thread::SetProcessor(int nProcessor)
{
#if defined(EA_PLATFORM_WINDOWS)
if(mThreadData.mpData)
{
static AtomicInt32 nProcessorCount = 0;

if(nProcessorCount == 0)
{
SYSTEM_INFO systemInfo;
memset(&systemInfo, 0, sizeof(systemInfo));
GetSystemInfo(&systemInfo);
nProcessorCount = (int)systemInfo.dwNumberOfProcessors;
}

DWORD dwThreadAffinityMask;

if(nProcessor < 0)
dwThreadAffinityMask = 0xffffffff;
else
{
if(nProcessor >= nProcessorCount)
nProcessor %= nProcessorCount;

dwThreadAffinityMask = 1 << nProcessor;
}

SetThreadAffinityMask(mThreadData.mpData->mThreadId, dwThreadAffinityMask);
}
#elif defined(EA_PLATFORM_LINUX)
#if defined(EA_PLATFORM_LINUX) || defined(EA_PLATFORM_WINDOWS)
if(mThreadData.mpData)
{
mThreadData.mpData->mStartupProcessor = nProcessor; // Assign this in case the thread hasn't started yet and thus we are leaving it a message to set it when it has started.
Expand Down
Loading