Fix MacOS and POSIX semaphores related issues
Recently got a MacBook Pro and decided to check how things build on MacOS. Discovered that POSIX unnamed semaphores weren't implemented, so I reimplemented them with conditional variable and mutex. Additionally, fixed scripts and CMake on MacOS
This commit is contained in:
@@ -22,12 +22,12 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS_ASAN
|
set(CMAKE_C_FLAGS_ASAN
|
||||||
"${CMAKE_C_FLAGS_DEBUG} -fsanitize=address,undefined -fno-omit-frame-pointer" CACHE STRING
|
"${CMAKE_C_FLAGS_DEBUG} -fsanitize=address,undefined -fno-omit-frame-pointer -Wno-deprecated-declarations" CACHE STRING
|
||||||
"Flags used by the C compiler for Asan build type or configuration." FORCE
|
"Flags used by the C compiler for Asan build type or configuration." FORCE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_ASAN
|
set(CMAKE_CXX_FLAGS_ASAN
|
||||||
"${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address,undefined -fno-omit-frame-pointer" CACHE STRING
|
"${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address,undefined -fno-omit-frame-pointer -Wno-deprecated-declarations" CACHE STRING
|
||||||
"Flags used by the C++ compiler for Asan build type or configuration." FORCE
|
"Flags used by the C++ compiler for Asan build type or configuration." FORCE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,6 +60,14 @@ if(ENABLE_LTO)
|
|||||||
message(STATUS "IPO/LTO enabled")
|
message(STATUS "IPO/LTO enabled")
|
||||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message(NOTICE "WARNING: IPO/LTO might cause issues while debugging")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_MT)
|
||||||
|
message(STATUS "Multithreading enabled")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Enable testing
|
# Enable testing
|
||||||
@@ -91,22 +99,22 @@ set(BH_SOURCE
|
|||||||
src/Math/Vec4f.c
|
src/Math/Vec4f.c
|
||||||
src/Math/Vec4i.c
|
src/Math/Vec4i.c
|
||||||
src/Queue.c
|
src/Queue.c
|
||||||
src/Util.c
|
|
||||||
src/String/Int.c
|
|
||||||
src/String/Float.c
|
src/String/Float.c
|
||||||
|
src/String/Int.c
|
||||||
src/String/Unicode.c
|
src/String/Unicode.c
|
||||||
|
src/Util.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BH_HEADER
|
set(BH_HEADER
|
||||||
include/BH/Common.h
|
|
||||||
include/BH/Algo.h
|
include/BH/Algo.h
|
||||||
include/BH/Args.h
|
include/BH/Args.h
|
||||||
|
include/BH/Common.h
|
||||||
include/BH/Hashmap.h
|
include/BH/Hashmap.h
|
||||||
include/BH/IO.h
|
include/BH/IO.h
|
||||||
include/BH/Math.h
|
include/BH/Math.h
|
||||||
include/BH/Queue.h
|
include/BH/Queue.h
|
||||||
include/BH/Util.h
|
|
||||||
include/BH/Thread.h
|
include/BH/Thread.h
|
||||||
|
include/BH/Util.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BH_SOURCE_DUMMY
|
set(BH_SOURCE_DUMMY
|
||||||
@@ -122,12 +130,12 @@ set(BH_SOURCE_POSIX
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(BH_SOURCE_WIN32_MT
|
set(BH_SOURCE_WIN32_MT
|
||||||
|
src/Platform/Spinlock.c
|
||||||
src/Platform/Win32/Condition.c
|
src/Platform/Win32/Condition.c
|
||||||
src/Platform/Win32/Mutex.c
|
src/Platform/Win32/Mutex.c
|
||||||
src/Platform/Win32/Semaphore.c
|
src/Platform/Win32/Semaphore.c
|
||||||
src/Platform/Win32/Thread.c
|
src/Platform/Win32/Thread.c
|
||||||
src/Platform/Win32/Tss.c
|
src/Platform/Win32/Tss.c
|
||||||
src/Platform/Spinlock.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BH_HEADER_WIN32_MT
|
set(BH_HEADER_WIN32_MT
|
||||||
|
|||||||
@@ -2,13 +2,24 @@
|
|||||||
SET(CMAKE_SYSTEM_NAME Windows)
|
SET(CMAKE_SYSTEM_NAME Windows)
|
||||||
SET(CMAKE_SYSTEM_PROCESSOR i686)
|
SET(CMAKE_SYSTEM_PROCESSOR i686)
|
||||||
|
|
||||||
# which compilers to use for C and C++ and ASM-ATT
|
# Check path
|
||||||
SET(CMAKE_C_COMPILER /usr/bin/i686-w64-mingw32-gcc)
|
if(EXISTS /usr/bin/i686-w64-mingw32-gcc)
|
||||||
SET(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++)
|
# which compilers to use for C and C++ and ASM-ATT
|
||||||
SET(CMAKE_ASM-ATT_COMPILER /usr/bin/i686-w64-mingw32-as)
|
SET(CMAKE_C_COMPILER /usr/bin/i686-w64-mingw32-gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER /usr/bin/i686-w64-mingw32-g++)
|
||||||
|
SET(CMAKE_ASM-ATT_COMPILER /usr/bin/i686-w64-mingw32-as)
|
||||||
|
|
||||||
# here is the target environment located
|
# here is the target environment located
|
||||||
SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
|
SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
|
||||||
|
elseif(EXISTS /usr/local/opt/mingw-w64/toolchain-i686/bin/i686-w64-mingw32-gcc)
|
||||||
|
# which compilers to use for C and C++ and ASM-ATT
|
||||||
|
SET(CMAKE_C_COMPILER /usr/local/opt/mingw-w64/toolchain-i686/bin/i686-w64-mingw32-gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER /usr/local/opt/mingw-w64/toolchain-i686/bin/i686-w64-mingw32-g++)
|
||||||
|
SET(CMAKE_ASM-ATT_COMPILER /usr/local/opt/mingw-w64/toolchain-i686/bin/i686-w64-mingw32-as)
|
||||||
|
|
||||||
|
# here is the target environment located
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH /usr/local/opt/mingw-w64/toolchain-i686/i686-w64-mingw32)
|
||||||
|
endif()
|
||||||
|
|
||||||
# adjust the default behaviour of the FIND_XXX() commands:
|
# adjust the default behaviour of the FIND_XXX() commands:
|
||||||
# search headers and libraries in the target environment, search
|
# search headers and libraries in the target environment, search
|
||||||
|
|||||||
@@ -2,13 +2,25 @@
|
|||||||
SET(CMAKE_SYSTEM_NAME Windows)
|
SET(CMAKE_SYSTEM_NAME Windows)
|
||||||
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
|
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||||
|
|
||||||
# which compilers to use for C and C++ and ASM-ATT
|
|
||||||
SET(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
|
|
||||||
SET(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)
|
|
||||||
SET(CMAKE_ASM-ATT_COMPILER /usr/bin/x86_64-w64-mingw32-as)
|
|
||||||
|
|
||||||
# here is the target environment located
|
# Check path
|
||||||
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
|
if(EXISTS /usr/bin/x86_64-w64-mingw32-gcc)
|
||||||
|
# which compilers to use for C and C++ and ASM-ATT
|
||||||
|
SET(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)
|
||||||
|
SET(CMAKE_ASM-ATT_COMPILER /usr/bin/x86_64-w64-mingw32-as)
|
||||||
|
|
||||||
|
# here is the target environment located
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
|
||||||
|
elseif(EXISTS /usr/local/opt/mingw-w64/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc)
|
||||||
|
# which compilers to use for C and C++ and ASM-ATT
|
||||||
|
SET(CMAKE_C_COMPILER /usr/local/opt/mingw-w64/toolchain-x86_64/bin/x86_64-w64-mingw32-gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER /usr/local/opt/mingw-w64/toolchain-x86_64/bin/x86_64-w64-mingw32-g++)
|
||||||
|
SET(CMAKE_ASM-ATT_COMPILER /usr/local/opt/mingw-w64/toolchain-x86_64/bin/x86_64-w64-mingw32-as)
|
||||||
|
|
||||||
|
# here is the target environment located
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH /usr/local/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32)
|
||||||
|
endif()
|
||||||
|
|
||||||
# adjust the default behaviour of the FIND_XXX() commands:
|
# adjust the default behaviour of the FIND_XXX() commands:
|
||||||
# search headers and libraries in the target environment, search
|
# search headers and libraries in the target environment, search
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if (_POSIX_SEMAPHORES >= 200112L)
|
||||||
BH_Semaphore *BH_SemaphoreNew(int value)
|
BH_Semaphore *BH_SemaphoreNew(int value)
|
||||||
{
|
{
|
||||||
BH_Semaphore *semaphore;
|
BH_Semaphore *semaphore;
|
||||||
@@ -70,3 +71,125 @@ int BH_SemaphoreWaitFor(BH_Semaphore *semaphore,
|
|||||||
default: return BH_ERROR;
|
default: return BH_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
BH_Semaphore *BH_SemaphoreNew(int value)
|
||||||
|
{
|
||||||
|
BH_Semaphore *semaphore;
|
||||||
|
|
||||||
|
/* Allocate space for mutex and initialize it */
|
||||||
|
semaphore = malloc(sizeof(BH_Semaphore));
|
||||||
|
if (semaphore)
|
||||||
|
{
|
||||||
|
semaphore->count = value;
|
||||||
|
semaphore->waiters = 0;
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&semaphore->mutex, NULL))
|
||||||
|
{
|
||||||
|
free(semaphore);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_cond_init(&semaphore->condition, NULL))
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&semaphore->mutex);
|
||||||
|
free(semaphore);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BH_SemaphoreFree(BH_Semaphore *semaphore)
|
||||||
|
{
|
||||||
|
/* Destroy condition variable and mutex */
|
||||||
|
pthread_cond_destroy(&semaphore->condition);
|
||||||
|
pthread_mutex_destroy(&semaphore->mutex);
|
||||||
|
free(semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BH_SemaphorePost(BH_Semaphore *semaphore)
|
||||||
|
{
|
||||||
|
/* Increase semaphore value */
|
||||||
|
pthread_mutex_lock(&semaphore->mutex);
|
||||||
|
semaphore->count++;
|
||||||
|
if (semaphore->waiters)
|
||||||
|
pthread_cond_signal(&semaphore->condition);
|
||||||
|
pthread_mutex_unlock(&semaphore->mutex);
|
||||||
|
|
||||||
|
return BH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BH_SemaphoreWait(BH_Semaphore *semaphore)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* Wait until semaphore count is not zero */
|
||||||
|
result = BH_ERROR;
|
||||||
|
pthread_mutex_lock(&semaphore->mutex);
|
||||||
|
semaphore->waiters++;
|
||||||
|
while (!semaphore->count)
|
||||||
|
pthread_cond_wait(&semaphore->condition, &semaphore->mutex);
|
||||||
|
semaphore->waiters--;
|
||||||
|
semaphore->count--;
|
||||||
|
pthread_mutex_unlock(&semaphore->mutex);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BH_SemaphoreWaitTry(BH_Semaphore *semaphore)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = BH_OK;
|
||||||
|
|
||||||
|
/* Check if semaphore count is not zero and decrement it */
|
||||||
|
pthread_mutex_lock(&semaphore->mutex);
|
||||||
|
if (!semaphore->count)
|
||||||
|
result = BH_ERROR;
|
||||||
|
else
|
||||||
|
semaphore->count--;
|
||||||
|
pthread_mutex_unlock(&semaphore->mutex);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int BH_SemaphoreWaitFor(BH_Semaphore *semaphore,
|
||||||
|
uint32_t timeout)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
/* Setup timeout */
|
||||||
|
ts.tv_sec = timeout / 1000;
|
||||||
|
ts.tv_nsec = (timeout - ts.tv_sec * 1000) * 1000000;
|
||||||
|
result = BH_OK;
|
||||||
|
|
||||||
|
/* Wait until semaphore count is not zero or timeout */
|
||||||
|
pthread_mutex_lock(&semaphore->mutex);
|
||||||
|
semaphore->waiters++;
|
||||||
|
while (!semaphore->count && result == BH_OK)
|
||||||
|
{
|
||||||
|
switch (pthread_cond_timedwait(&semaphore->condition, &semaphore->mutex, &ts))
|
||||||
|
{
|
||||||
|
case 0: result = BH_OK; break;
|
||||||
|
case ETIMEDOUT: result = BH_TIMEOUT; break;
|
||||||
|
default: result = BH_ERROR; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
semaphore->waiters--;
|
||||||
|
|
||||||
|
/* If everything went fine - decrement semaphore counter */
|
||||||
|
if (!result)
|
||||||
|
semaphore->count--;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&semaphore->mutex);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <BH/Thread.h>
|
#include <BH/Thread.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct BH_Condition
|
struct BH_Condition
|
||||||
@@ -19,10 +19,22 @@ struct BH_Mutex
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#if (_POSIX_SEMAPHORES >= 200112L)
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
struct BH_Semaphore
|
struct BH_Semaphore
|
||||||
{
|
{
|
||||||
sem_t handle;
|
sem_t handle;
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
struct BH_Semaphore
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int waiters;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t condition;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct BH_Thread
|
struct BH_Thread
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ if [ ! -f $1 ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Checking file" $1
|
||||||
|
|
||||||
|
|
||||||
# Message about trailing space before EOL
|
# Message about trailing space before EOL
|
||||||
eolerrors=$(grep -n "\s$" "$1" | cut -f1 -d: | while read -r line; do
|
eolerrors=$(grep -n "\s$" "$1" | cut -f1 -d: | while read -r line; do
|
||||||
@@ -22,7 +24,7 @@ done)
|
|||||||
|
|
||||||
|
|
||||||
# Message about non-empty last-line
|
# Message about non-empty last-line
|
||||||
linecount=$(($(wc -l "$1" | cut -f1 -d " ") + 1))
|
linecount=$(($(wc -l "$1" | xargs | cut -f1 -d " ") + 1))
|
||||||
lastline=$(tail -n "+$linecount" $1)
|
lastline=$(tail -n "+$linecount" $1)
|
||||||
|
|
||||||
llerrors=$(if [ "$lastline" ]; then
|
llerrors=$(if [ "$lastline" ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user