windows wip

This commit is contained in:
William Woodall 2015-12-11 17:47:49 -08:00
parent f528b7a925
commit 3e516c8c8f
5 changed files with 386 additions and 21 deletions

View file

@ -34,7 +34,9 @@ ament_target_dependencies(${PROJECT_NAME}
"rmw" "rmw"
"rosidl_generator_c" "rosidl_generator_c"
) )
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-std=c11") if(NOT WIN32)
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "-std=c11")
endif()
if(AMENT_ENABLE_TESTING) if(AMENT_ENABLE_TESTING)
find_package(ament_cmake_gtest REQUIRED) find_package(ament_cmake_gtest REQUIRED)
@ -42,58 +44,64 @@ if(AMENT_ENABLE_TESTING)
ament_lint_auto_find_test_dependencies() ament_lint_auto_find_test_dependencies()
set(extra_test_libraries) set(extra_test_libraries)
set(extra_memory_tools_env PHONY=) # Use a phony env var so there is always at least one.
ament_find_gtest() # For GTEST_LIBRARIES ament_find_gtest() # For GTEST_LIBRARIES
if(APPLE) if(APPLE)
add_library(${PROJECT_NAME}_memory_tools_interpose SHARED test/memory_tools_osx_interpose.cpp) add_library(${PROJECT_NAME}_memory_tools_interpose SHARED test/memory_tools_osx_interpose.cpp)
target_link_libraries(${PROJECT_NAME}_memory_tools_interpose ${GTEST_LIBRARIES}) target_link_libraries(${PROJECT_NAME}_memory_tools_interpose ${GTEST_LIBRARIES})
set_target_properties(${PROJECT_NAME}_memory_tools_interpose PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(${PROJECT_NAME}_memory_tools_interpose
PROPERTIES COMPILE_FLAGS "-std=c++11")
list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools_interpose) list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools_interpose)
list(APPEND extra_memory_tools_env
DYLD_INSERT_LIBRARIES=$<TARGET_FILE:${PROJECT_NAME}_memory_tools_interpose>)
endif() endif()
add_library(${PROJECT_NAME}_memory_tools SHARED test/memory_tools.cpp) add_library(${PROJECT_NAME}_memory_tools SHARED test/memory_tools.cpp)
if(NOT WIN32)
set_target_properties(${PROJECT_NAME}_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(${PROJECT_NAME}_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11")
endif()
target_link_libraries(${PROJECT_NAME}_memory_tools ${GTEST_LIBRARIES} ${extra_test_libraries}) target_link_libraries(${PROJECT_NAME}_memory_tools ${GTEST_LIBRARIES} ${extra_test_libraries})
list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools) list(APPEND extra_test_libraries ${PROJECT_NAME}_memory_tools)
ament_add_gtest(test_memory_tools ament_add_gtest(test_memory_tools test/test_memory_tools.cpp ENV ${extra_memory_tools_env})
test/test_memory_tools.cpp
ENV DYLD_INSERT_LIBRARIES=$<TARGET_FILE:${PROJECT_NAME}_memory_tools_interpose>)
if(TARGET test_memory_tools) if(TARGET test_memory_tools)
target_include_directories(test_memory_tools PUBLIC target_include_directories(test_memory_tools PUBLIC
${rcl_interfaces_INCLUDE_DIRS} ${rcl_interfaces_INCLUDE_DIRS}
${rmw_INCLUDE_DIRS} ${rmw_INCLUDE_DIRS}
) )
if(NOT WIN32)
set_target_properties(test_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(test_memory_tools PROPERTIES COMPILE_FLAGS "-std=c++11")
endif()
target_link_libraries(test_memory_tools ${PROJECT_NAME} ${extra_test_libraries}) target_link_libraries(test_memory_tools ${PROJECT_NAME} ${extra_test_libraries})
endif() endif()
ament_add_gtest(test_allocator ament_add_gtest(test_allocator test/rcl/test_allocator.cpp ENV ${extra_memory_tools_env})
test/rcl/test_allocator.cpp
ENV DYLD_INSERT_LIBRARIES=$<TARGET_FILE:${PROJECT_NAME}_memory_tools_interpose>)
if(TARGET test_allocator) if(TARGET test_allocator)
target_include_directories(test_allocator PUBLIC target_include_directories(test_allocator PUBLIC
${rcl_interfaces_INCLUDE_DIRS} ${rcl_interfaces_INCLUDE_DIRS}
${rmw_INCLUDE_DIRS} ${rmw_INCLUDE_DIRS}
) )
if(NOT WIN32)
set_target_properties(test_allocator PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(test_allocator PROPERTIES COMPILE_FLAGS "-std=c++11")
endif()
target_link_libraries(test_allocator ${PROJECT_NAME} ${extra_test_libraries}) target_link_libraries(test_allocator ${PROJECT_NAME} ${extra_test_libraries})
endif() endif()
ament_add_gtest(test_time ament_add_gtest(test_time test/rcl/test_time.cpp ENV ${extra_memory_tools_env})
test/rcl/test_time.cpp
ENV DYLD_INSERT_LIBRARIES=$<TARGET_FILE:${PROJECT_NAME}_memory_tools_interpose>)
if(TARGET test_time) if(TARGET test_time)
target_include_directories(test_time PUBLIC target_include_directories(test_time PUBLIC
${rcl_interfaces_INCLUDE_DIRS} ${rcl_interfaces_INCLUDE_DIRS}
${rmw_INCLUDE_DIRS} ${rmw_INCLUDE_DIRS}
) )
if(NOT WIN32)
set_target_properties(test_time PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(test_time PROPERTIES COMPILE_FLAGS "-std=c++11")
endif()
target_link_libraries(test_time ${PROJECT_NAME} ${extra_test_libraries}) target_link_libraries(test_time ${PROJECT_NAME} ${extra_test_libraries})
endif() endif()
ament_add_gtest(test_common ament_add_gtest(test_common
test/rcl/test_common.cpp test/rcl/test_common.cpp
ENV ENV
DYLD_INSERT_LIBRARIES=$<TARGET_FILE:${PROJECT_NAME}_memory_tools_interpose> ${extra_memory_tools_env}
EMPTY_TEST= EMPTY_TEST=
NORMAL_TEST=foo NORMAL_TEST=foo
) )
@ -102,7 +110,9 @@ if(AMENT_ENABLE_TESTING)
${rcl_interfaces_INCLUDE_DIRS} ${rcl_interfaces_INCLUDE_DIRS}
${rmw_INCLUDE_DIRS} ${rmw_INCLUDE_DIRS}
) )
if(NOT WIN32)
set_target_properties(test_common PROPERTIES COMPILE_FLAGS "-std=c++11") set_target_properties(test_common PROPERTIES COMPILE_FLAGS "-std=c++11")
endif()
target_link_libraries(test_common ${PROJECT_NAME} ${extra_test_libraries}) target_link_libraries(test_common ${PROJECT_NAME} ${extra_test_libraries})
endif() endif()
endif() endif()

View file

@ -36,7 +36,7 @@ rcl_impl_getenv(const char * env_name, const char ** env_value)
*env_value = getenv(env_name); *env_value = getenv(env_name);
#else #else
size_t required_size; size_t required_size;
error_t ret = getenv_s(&required_size, __env_buffer, sizeof(__env_buffer), env_name); errno_t ret = getenv_s(&required_size, __env_buffer, sizeof(__env_buffer), env_name);
if (ret != 0) { if (ret != 0) {
RCL_SET_ERROR_MSG("value in env variable too large to read in"); RCL_SET_ERROR_MSG("value in env variable too large to read in");
return RCL_RET_ERROR; return RCL_RET_ERROR;

View file

@ -19,19 +19,23 @@ extern "C"
#include "rcl/rcl.h" #include "rcl/rcl.h"
#ifndef WIN32
#include <stdatomic.h> #include <stdatomic.h>
#else
#include "./stdatomic/win32/stdatomic.h"
#endif
#include <string.h> #include <string.h>
#include "rcl/error_handling.h" #include "rcl/error_handling.h"
static atomic_bool __rcl_is_initialized = false; static atomic_bool __rcl_is_initialized = ATOMIC_VAR_INIT(false);
static rcl_allocator_t __rcl_allocator = {0}; static rcl_allocator_t __rcl_allocator = {0};
static int __rcl_argc = 0; static int __rcl_argc = 0;
static char ** __rcl_argv = NULL; static char ** __rcl_argv = NULL;
static atomic_uint_fast64_t __rcl_instance_id = 0; static atomic_uint_fast64_t __rcl_instance_id = ATOMIC_VAR_INIT(0);
static uint64_t __rcl_next_unique_id = 0; static uint64_t __rcl_next_unique_id = 0;
static inline void static void
__clean_up_init() __clean_up_init()
{ {
if (__rcl_argv) { if (__rcl_argv) {

View file

@ -0,0 +1,325 @@
/*
* An implementation of C11 stdatomic.h for Win32, part borrowed from FreeBSD
* (original copyright follows), with major modifications for
* portability to Win32 systems.
*
* Caveats and limitations:
* - Only the ``_Atomic parentheses'' notation is implemented, while
* the ``_Atomic space'' one is not.
* - _Atomic types must be typedef'ed, or programs using them will
* not type check correctly (incompatible anonymous structure
* types).
* - Support is limited to 16, 32, and 64 bit types only.
* - Stripped down to only the functions used locally in rcl.
*/
/*-
* Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
* David Chisnall <theraven@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/include/stdatomic.h,v 1.10.2.2 2012/05/30 19:21:54 theraven Exp $
*/
#ifndef _STDATOMIC_H_
#define _STDATOMIC_H_
#include <Windows.h>
#include <stddef.h>
#include <stdint.h>
#if !defined(WIN32)
#error "this stdatomic.h does not support your compiler"
#endif
// In MSVC, correct alignment of each type is already ensured.
#define _Atomic(T) struct { T __val; }
/*
* 7.17.2 Initialization.
*/
#define ATOMIC_VAR_INIT(value) { .__val = (value) }
#define atomic_init(obj, value) do { \
(obj)->__val = (value); \
} while (0)
/*
* Clang and recent GCC both provide predefined macros for the memory
* orderings. If we are using a compiler that doesn't define them, use the
* clang values - these will be ignored in the fallback path.
*/
#ifndef __ATOMIC_RELAXED
#define __ATOMIC_RELAXED 0
#endif
#ifndef __ATOMIC_CONSUME
#define __ATOMIC_CONSUME 1
#endif
#ifndef __ATOMIC_ACQUIRE
#define __ATOMIC_ACQUIRE 2
#endif
#ifndef __ATOMIC_RELEASE
#define __ATOMIC_RELEASE 3
#endif
#ifndef __ATOMIC_ACQ_REL
#define __ATOMIC_ACQ_REL 4
#endif
#ifndef __ATOMIC_SEQ_CST
#define __ATOMIC_SEQ_CST 5
#endif
/*
* 7.17.3 Order and consistency.
*
* The memory_order_* constants that denote the barrier behaviour of the
* atomic operations.
*/
enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST
};
typedef enum memory_order memory_order;
/*
* 7.17.4 Fences.
*/
#define atomic_thread_fence(order) MemoryBarrier()
#define atomic_signal_fence(order) _ReadWriteBarrier()
/*
* 7.17.5 Lock-free property.
*/
#define atomic_is_lock_free(obj) (sizeof((obj)->__val) <= sizeof(void *))
/*
* 7.17.6 Atomic integer types.
*/
typedef _Atomic(_Bool) atomic_bool;
typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short;
typedef _Atomic(unsigned short) atomic_ushort;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(long long) atomic_llong;
typedef _Atomic(unsigned long long) atomic_ullong;
#if 0
typedef _Atomic(char16_t) atomic_char16_t;
typedef _Atomic(char32_t) atomic_char32_t;
typedef _Atomic(wchar_t) atomic_wchar_t;
typedef _Atomic(int_least8_t) atomic_int_least8_t;
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
#endif
typedef _Atomic(int_least16_t) atomic_int_least16_t;
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
typedef _Atomic(int_least32_t) atomic_int_least32_t;
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
typedef _Atomic(int_least64_t) atomic_int_least64_t;
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
#if 0
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
#endif
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
typedef _Atomic(intmax_t) atomic_intmax_t;
typedef _Atomic(uintmax_t) atomic_uintmax_t;
/*
* 7.17.7 Operations on atomic types. (pruned modified for Windows' crappy C compiler)
*/
#define rcl_win32_atomic_compare_exchange_strong(object, out, expected, desired) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedCompareExchange64((LONGLONG *) object, desired, expected); \
break; \
case sizeof(uint32_t): \
out = _InterlockedCompareExchange((LONG *) object, desired, expected); \
break; \
case sizeof(uint16_t): \
out = _InterlockedCompareExchange16((SHORT *) object, desired, expected); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_compare_exchange_weak(object, out, expected, desired) \
rcl_win32_atomic_compare_exchange_strong(object, out, expected, desired)
#define rcl_win32_atomic_exchange((object), out, desired) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedExchange64((LONGLONG *) object, desired); \
break; \
case sizeof(uint32_t): \
out = _InterlockedExchange((LONG *) object, desired); \
break; \
case sizeof(uint16_t): \
out = _InterlockedExchange16((SHORT *) object, desired); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_fetch_add(object, out, operand) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedExchangeAdd64((LONGLONG *) object, operand); \
break; \
case sizeof(uint32_t): \
out = _InterlockedExchangeAdd((LONG *) object, operand); \
break; \
case sizeof(uint16_t): \
out = _InterlockedExchangeAdd16((SHORT *) object, operand); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_fetch_and(object, out, operand) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedAnd64((LONGLONG *) object, operand); \
break; \
case sizeof(uint32_t): \
out = _InterlockedAnd((LONG *) object, operand); \
break; \
case sizeof(uint16_t): \
out = _InterlockedAnd16((SHORT *) object, operand); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_fetch_or(object, out, operand) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedOr64((LONGLONG *) object, operand); \
break; \
case sizeof(uint32_t): \
out = _InterlockedOr((LONG *) object, operand); \
break; \
case sizeof(uint16_t): \
out = _InterlockedOr16((SHORT *) object, operand); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_fetch_sub(object, out, operand) \
rcl_win32_atomic_fetch_add(object, out, -(operand))
#define rcl_win32_atomic_fetch_xor(object, out, operand) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedXor64((LONGLONG *) object, operand); \
break; \
case sizeof(uint32_t): \
out = _InterlockedXor((LONG *) object, operand); \
break; \
case sizeof(uint16_t): \
out = _InterlockedXor16((SHORT *) object, operand); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_load(object) \
do { \
switch(sizeof(object)) { \
case sizeof(uint64_t): \
out = _InterlockedExchangeAdd64((LONGLONG *) object, 0); \
break; \
case sizeof(uint32_t): \
out = _InterlockedExchangeAdd((LONG *) object, 0); \
break; \
case sizeof(uint16_t): \
out = _InterlockedExchangeAdd16((SHORT *) object, 0); \
break; \
default: \
break; \
}; \
} while(0)
#define rcl_win32_atomic_store(object, desired) \
do { \
MemoryBarrier(); \
object = (desired); \
MemoryBarrier(); \
} while (0)
/*
* 7.17.8 Atomic flag type and operations. (disabled for now)
*/
// typedef atomic_bool atomic_flag;
// #define ATOMIC_FLAG_INIT ATOMIC_VAR_INIT(0)
// #define atomic_flag_clear_explicit(object, order) \
// atomic_store_explicit(object, 0, order)
// #define atomic_flag_test_and_set_explicit(object, order) \
// atomic_compare_exchange_strong_explicit(object, 0, 1, order, order)
// #define atomic_flag_clear(object) \
// atomic_flag_clear_explicit(object, memory_order_seq_cst)
// #define atomic_flag_test_and_set(object) \
// atomic_flag_test_and_set_explicit(object, memory_order_seq_cst)
#endif /* !_STDATOMIC_H_ */

View file

@ -0,0 +1,26 @@
// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef RCL__STDATOMICS_HELPER_H_
#define RCL__STDATOMICS_HELPER_H_
#if !defined(WIN32)
#else
#endif
#endif // RCL__STDATOMICS_HELPER_H_