- HAL: added thread/semaphore support for MacOS
parent
02f03aea2f
commit
cf7dbcc612
@ -1,183 +1,192 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
# automagically detect if we should cross-compile
|
# automagically detect if we should cross-compile
|
||||||
if(DEFINED ENV{TOOLCHAIN})
|
if(DEFINED ENV{TOOLCHAIN})
|
||||||
set(CMAKE_C_COMPILER $ENV{TOOLCHAIN}gcc)
|
set(CMAKE_C_COMPILER $ENV{TOOLCHAIN}gcc)
|
||||||
set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN}g++)
|
set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN}g++)
|
||||||
set(CMAKE_AR "$ENV{TOOLCHAIN}ar" CACHE FILEPATH "CW archiver" FORCE)
|
set(CMAKE_AR "$ENV{TOOLCHAIN}ar" CACHE FILEPATH "CW archiver" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(hal)
|
project(hal)
|
||||||
|
|
||||||
set(LIBHAL_VERSION_MAJOR "2")
|
set(LIBHAL_VERSION_MAJOR "2")
|
||||||
set(LIBHAL_VERSION_MINOR "0")
|
set(LIBHAL_VERSION_MINOR "0")
|
||||||
set(LIBHAL_VERSION_PATCH "0")
|
set(LIBHAL_VERSION_PATCH "0")
|
||||||
|
|
||||||
# feature checks
|
# feature checks
|
||||||
include(CheckLibraryExists)
|
include(CheckLibraryExists)
|
||||||
check_library_exists(rt clock_gettime "time.h" CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
|
check_library_exists(rt clock_gettime "time.h" CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
|
||||||
|
|
||||||
# check if we are on a little or a big endian
|
# check if we are on a little or a big endian
|
||||||
include (TestBigEndian)
|
include (TestBigEndian)
|
||||||
test_big_endian(PLATFORM_IS_BIGENDIAN)
|
test_big_endian(PLATFORM_IS_BIGENDIAN)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
|
||||||
message("Found winpcap -> compile ethernet HAL layer (required for GOOSE/SV support)")
|
message("Found winpcap -> compile ethernet HAL layer (required for GOOSE/SV support)")
|
||||||
set(WITH_WPCAP 1)
|
set(WITH_WPCAP 1)
|
||||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Include")
|
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Include")
|
||||||
else()
|
else()
|
||||||
message("winpcap not found -> skip ethernet HAL layer (no GOOSE/SV support)")
|
message("winpcap not found -> skip ethernet HAL layer (no GOOSE/SV support)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/inc
|
${CMAKE_CURRENT_LIST_DIR}/inc
|
||||||
)
|
)
|
||||||
|
|
||||||
set (libhal_linux_SRCS
|
set (libhal_linux_SRCS
|
||||||
${CMAKE_CURRENT_LIST_DIR}/socket/linux/socket_linux.c
|
${CMAKE_CURRENT_LIST_DIR}/socket/linux/socket_linux.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ethernet/linux/ethernet_linux.c
|
${CMAKE_CURRENT_LIST_DIR}/ethernet/linux/ethernet_linux.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/thread/linux/thread_linux.c
|
${CMAKE_CURRENT_LIST_DIR}/thread/linux/thread_linux.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
|
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
|
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/serial/linux/serial_port_linux.c
|
${CMAKE_CURRENT_LIST_DIR}/serial/linux/serial_port_linux.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set (libhal_windows_SRCS
|
set (libhal_windows_SRCS
|
||||||
${CMAKE_CURRENT_LIST_DIR}/socket/win32/socket_win32.c
|
${CMAKE_CURRENT_LIST_DIR}/socket/win32/socket_win32.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/thread/win32/thread_win32.c
|
${CMAKE_CURRENT_LIST_DIR}/thread/win32/thread_win32.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/filesystem/win32/file_provider_win32.c
|
${CMAKE_CURRENT_LIST_DIR}/filesystem/win32/file_provider_win32.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/time/win32/time.c
|
${CMAKE_CURRENT_LIST_DIR}/time/win32/time.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/serial/win32/serial_port_win32.c
|
${CMAKE_CURRENT_LIST_DIR}/serial/win32/serial_port_win32.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WITH_WPCAP)
|
if(WITH_WPCAP)
|
||||||
set (libhal_windows_SRCS ${libhal_windows_SRCS}
|
set (libhal_windows_SRCS ${libhal_windows_SRCS}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ethernet/win32/ethernet_win32.c
|
${CMAKE_CURRENT_LIST_DIR}/ethernet/win32/ethernet_win32.c
|
||||||
)
|
)
|
||||||
endif(WITH_WPCAP)
|
endif(WITH_WPCAP)
|
||||||
|
|
||||||
set (libhal_bsd_SRCS
|
set (libhal_bsd_SRCS
|
||||||
${CMAKE_CURRENT_LIST_DIR}/socket/bsd/socket_bsd.c
|
${CMAKE_CURRENT_LIST_DIR}/socket/bsd/socket_bsd.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/ethernet/bsd/ethernet_bsd.c
|
${CMAKE_CURRENT_LIST_DIR}/ethernet/bsd/ethernet_bsd.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/thread/bsd/thread_bsd.c
|
${CMAKE_CURRENT_LIST_DIR}/thread/bsd/thread_macos.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
|
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
|
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(WIN32)
|
set (libhal_macos_SRCS
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/socket/bsd/socket_bsd.c
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
|
${CMAKE_CURRENT_LIST_DIR}/ethernet/bsd/ethernet_bsd.c
|
||||||
message("Found winpcap -> can compile with GOOSE support")
|
${CMAKE_CURRENT_LIST_DIR}/thread/macos/thread_macos.c
|
||||||
set(WITH_WPCAP 1)
|
${CMAKE_CURRENT_LIST_DIR}/filesystem/linux/file_provider_linux.c
|
||||||
endif()
|
${CMAKE_CURRENT_LIST_DIR}/time/unix/time.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/memory/lib_memory.c
|
||||||
set (libhal_SRCS
|
)
|
||||||
${libhal_windows_SRCS}
|
|
||||||
)
|
IF(WIN32)
|
||||||
|
|
||||||
IF(MSVC)
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib")
|
||||||
set_source_files_properties(${libhal_SRCS}
|
message("Found winpcap -> can compile with GOOSE support")
|
||||||
PROPERTIES LANGUAGE CXX)
|
set(WITH_WPCAP 1)
|
||||||
ENDIF()
|
endif()
|
||||||
|
|
||||||
ELSEIF(UNIX)
|
set (libhal_SRCS
|
||||||
IF(APPLE)
|
${libhal_windows_SRCS}
|
||||||
set (libhal_SRCS
|
)
|
||||||
${libhal_bsd_SRCS}
|
|
||||||
)
|
IF(MSVC)
|
||||||
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
set_source_files_properties(${libhal_SRCS}
|
||||||
set (libhal_SRCS
|
PROPERTIES LANGUAGE CXX)
|
||||||
${libhal_bsd_SRCS}
|
ENDIF()
|
||||||
)
|
|
||||||
ELSE()
|
ELSEIF(UNIX)
|
||||||
set (libhal_SRCS
|
IF(APPLE)
|
||||||
${libhal_linux_SRCS}
|
set (libhal_SRCS
|
||||||
)
|
${libhal_macos_SRCS}
|
||||||
ENDIF(APPLE)
|
)
|
||||||
ENDIF(WIN32)
|
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||||
|
set (libhal_SRCS
|
||||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
|
${libhal_bsd_SRCS}
|
||||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" )
|
)
|
||||||
|
ELSE()
|
||||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16)
|
set (libhal_SRCS
|
||||||
message("Found mbedtls -> can compile with TLS support")
|
${libhal_linux_SRCS}
|
||||||
set(WITH_MBEDTLS 1)
|
)
|
||||||
endif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16)
|
ENDIF(APPLE)
|
||||||
|
ENDIF(WIN32)
|
||||||
if(WITH_MBEDTLS)
|
|
||||||
include_directories(
|
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
|
||||||
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls
|
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" )
|
||||||
${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/include
|
|
||||||
)
|
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16)
|
||||||
|
message("Found mbedtls -> can compile with TLS support")
|
||||||
file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/library/*.c)
|
set(WITH_MBEDTLS 1)
|
||||||
|
endif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16)
|
||||||
add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h")
|
|
||||||
|
if(WITH_MBEDTLS)
|
||||||
set (libhal_SRCS ${libhal_SRCS}
|
include_directories(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls/tls_mbedtls.c
|
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls
|
||||||
)
|
${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/include
|
||||||
|
)
|
||||||
IF(MSVC)
|
|
||||||
set_source_files_properties(${libhal_SRCS}
|
file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.16/library/*.c)
|
||||||
PROPERTIES LANGUAGE CXX)
|
|
||||||
ENDIF()
|
add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h")
|
||||||
|
|
||||||
list (APPEND libhal_SRCS ${tls_SRCS})
|
set (libhal_SRCS ${libhal_SRCS}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls/tls_mbedtls.c
|
||||||
endif(WITH_MBEDTLS)
|
)
|
||||||
|
|
||||||
add_library (hal STATIC ${libhal_SRCS})
|
IF(MSVC)
|
||||||
|
set_source_files_properties(${libhal_SRCS}
|
||||||
add_library (hal-shared STATIC ${libhal_SRCS})
|
PROPERTIES LANGUAGE CXX)
|
||||||
|
ENDIF()
|
||||||
target_compile_definitions(hal-shared PRIVATE EXPORT_FUNCTIONS_FOR_DLL)
|
|
||||||
|
list (APPEND libhal_SRCS ${tls_SRCS})
|
||||||
SET_TARGET_PROPERTIES(hal-shared PROPERTIES
|
|
||||||
COMPILE_FLAGS "-fPIC"
|
endif(WITH_MBEDTLS)
|
||||||
)
|
|
||||||
|
add_library (hal STATIC ${libhal_SRCS})
|
||||||
IF(UNIX)
|
|
||||||
IF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
|
add_library (hal-shared STATIC ${libhal_SRCS})
|
||||||
target_link_libraries (hal
|
|
||||||
-lpthread
|
target_compile_definitions(hal-shared PRIVATE EXPORT_FUNCTIONS_FOR_DLL)
|
||||||
-lrt
|
|
||||||
)
|
SET_TARGET_PROPERTIES(hal-shared PROPERTIES
|
||||||
ELSE ()
|
COMPILE_FLAGS "-fPIC"
|
||||||
target_link_libraries (hal
|
)
|
||||||
-lpthread
|
|
||||||
)
|
IF(UNIX)
|
||||||
ENDIF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
|
IF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
|
||||||
ENDIF(UNIX)
|
target_link_libraries (hal
|
||||||
IF(MINGW)
|
-lpthread
|
||||||
target_link_libraries(hal ws2_32 iphlpapi)
|
-lrt
|
||||||
ENDIF(MINGW)
|
)
|
||||||
|
ELSE ()
|
||||||
iF(WITH_WPCAP)
|
target_link_libraries (hal
|
||||||
target_link_libraries(hal
|
-lpthread
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib
|
)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/packet.lib
|
ENDIF (CONFIG_SYSTEM_HAS_CLOCK_GETTIME)
|
||||||
)
|
ENDIF(UNIX)
|
||||||
ENDIF(WITH_WPCAP)
|
IF(MINGW)
|
||||||
|
target_link_libraries(hal ws2_32 iphlpapi)
|
||||||
set(BINDIR "bin")
|
ENDIF(MINGW)
|
||||||
set(LIBDIR "lib")
|
|
||||||
if(UNIX)
|
iF(WITH_WPCAP)
|
||||||
# GNUInstallDirs is required for Debian multiarch
|
target_link_libraries(hal
|
||||||
include(GNUInstallDirs)
|
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/wpcap.lib
|
||||||
set(LIBDIR ${CMAKE_INSTALL_LIBDIR})
|
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/winpcap/Lib/packet.lib
|
||||||
set(BINDIR ${CMAKE_INSTALL_BINDIR})
|
)
|
||||||
endif()
|
ENDIF(WITH_WPCAP)
|
||||||
|
|
||||||
install (TARGETS hal hal-shared
|
set(BINDIR "bin")
|
||||||
RUNTIME DESTINATION ${BINDIR} COMPONENT Applications
|
set(LIBDIR "lib")
|
||||||
ARCHIVE DESTINATION ${LIBDIR} COMPONENT Libraries
|
if(UNIX)
|
||||||
LIBRARY DESTINATION ${LIBDIR} COMPONENT Libraries
|
# GNUInstallDirs is required for Debian multiarch
|
||||||
)
|
include(GNUInstallDirs)
|
||||||
|
set(LIBDIR ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
set(BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install (TARGETS hal hal-shared
|
||||||
|
RUNTIME DESTINATION ${BINDIR} COMPONENT Applications
|
||||||
|
ARCHIVE DESTINATION ${LIBDIR} COMPONENT Libraries
|
||||||
|
LIBRARY DESTINATION ${LIBDIR} COMPONENT Libraries
|
||||||
|
)
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* thread_macos.c
|
||||||
|
*
|
||||||
|
* Copyright 2013-2019 MZ Automation GmbH
|
||||||
|
*
|
||||||
|
* This file is part of Platform Abstraction Layer (libpal)
|
||||||
|
* for libiec61850, libmms, and lib60870.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: MacOS needs own thread layer because it doesn't support unnamed semaphores!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "hal_thread.h"
|
||||||
|
#include "lib_memory.h"
|
||||||
|
|
||||||
|
struct sThread {
|
||||||
|
ThreadExecutionFunction function;
|
||||||
|
void* parameter;
|
||||||
|
pthread_t pthread;
|
||||||
|
int state;
|
||||||
|
bool autodestroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
Semaphore
|
||||||
|
Semaphore_create(int initialValue)
|
||||||
|
{
|
||||||
|
char tmpname[] = {"/tmp/libiec61850.XXXXXX"};
|
||||||
|
mktemp(tmpname);
|
||||||
|
|
||||||
|
Semaphore self = (Semaphore) sem_open(tmpname, O_CREAT, 0666, initialValue);
|
||||||
|
|
||||||
|
if (self == SEM_FAILED) {
|
||||||
|
printf("ERROR: Failed to create semaphore (errno = %i)\n", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = sem_unlink(tmpname);
|
||||||
|
|
||||||
|
if (ret == -1)
|
||||||
|
printf("ERROR: Failed to unlink semaphore %s\n", tmpname);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait until semaphore value is more than zero. Then decrease the semaphore value. */
|
||||||
|
void
|
||||||
|
Semaphore_wait(Semaphore self)
|
||||||
|
{
|
||||||
|
sem_wait((sem_t*) self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Semaphore_post(Semaphore self)
|
||||||
|
{
|
||||||
|
sem_post((sem_t*) self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Semaphore_destroy(Semaphore self)
|
||||||
|
{
|
||||||
|
sem_close(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread
|
||||||
|
Thread_create(ThreadExecutionFunction function, void* parameter, bool autodestroy)
|
||||||
|
{
|
||||||
|
Thread thread = (Thread) GLOBAL_MALLOC(sizeof(struct sThread));
|
||||||
|
|
||||||
|
if (thread != NULL) {
|
||||||
|
thread->parameter = parameter;
|
||||||
|
thread->function = function;
|
||||||
|
thread->state = 0;
|
||||||
|
thread->autodestroy = autodestroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
destroyAutomaticThread(void* parameter)
|
||||||
|
{
|
||||||
|
Thread thread = (Thread) parameter;
|
||||||
|
|
||||||
|
thread->function(thread->parameter);
|
||||||
|
|
||||||
|
GLOBAL_FREEMEM(thread);
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread_start(Thread thread)
|
||||||
|
{
|
||||||
|
if (thread->autodestroy == true) {
|
||||||
|
pthread_create(&thread->pthread, NULL, destroyAutomaticThread, thread);
|
||||||
|
pthread_detach(thread->pthread);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pthread_create(&thread->pthread, NULL, thread->function, thread->parameter);
|
||||||
|
|
||||||
|
thread->state = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread_destroy(Thread thread)
|
||||||
|
{
|
||||||
|
if (thread->state == 1) {
|
||||||
|
pthread_join(thread->pthread, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLOBAL_FREEMEM(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Thread_sleep(int millies)
|
||||||
|
{
|
||||||
|
usleep(millies * 1000);
|
||||||
|
}
|
Loading…
Reference in New Issue