commit 08f66f1b7b6dcc12189846d2524f87095b92cc7d
parent 7b54289a15f62dd6bd407692286f627d0b6c016e
Author: vaplv <vaplv@free.fr>
Date: Tue, 5 May 2015 14:49:17 +0200
First port on the CL compiler
Diffstat:
29 files changed, 570 insertions(+), 458 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -1,172 +1,198 @@
-# Copyright (C) 2013-2015 Vincent Forest (vaplv@free.fr)
-#
-# This CMake script is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This CMake script is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this CMake script. If not, see <http://www.gnu.org/licenses/>.
-
-cmake_minimum_required(VERSION 2.6)
-project(rsys C)
-cmake_policy(SET CMP0011 NEW)
-enable_testing()
-
-set(RSYS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
-option(NO_TEST "Disable the test" OFF)
-
-################################################################################
-# Check dependencies
-################################################################################
-find_package(RCMake REQUIRED)
-find_package(Threads REQUIRED)
-find_package(OpenMP)
-
-if(CMAKE_USE_PTHREADS_INIT)
- add_definitions(-DRSYS_USE_PTHREADS)
-endif(CMAKE_USE_PTHREADS_INIT)
-
-set(CMAKE_MODULE_PATH ${RCMAKE_SOURCE_DIR})
-include(rcmake)
-
-################################################################################
-# Configure and define targets
-################################################################################
-set(VERSION_MAJOR 0)
-set(VERSION_MINOR 1)
-set(VERSION_PATCH 1)
-set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-
-set(RSYS_FILES_SRC
- clock_time.c
- float44.c
- image.c
- library.c
- logger.c
- mem_allocator.c
- pthread/pthread_condition.c
- pthread/pthread_mutex.c
- quaternion.c
- str.c)
-set(RSYS_FILES_INC
- binary_heap.h
- clock_time.h
- condition.h
- dynamic_array.h
- dynamic_array_char.h
- dynamic_array_float.h
- dynamic_array_uchar.h
- dynamic_array_u32.h
- dynamic_array_u64.h
- dynamic_array_size_t.h
- dynamic_array_str.h
- floatX.h
- float2.h
- float3.h
- float4.h
- floatXY.h
- float22.h
- float33.h
- float44.h
- free_list.h
- hash.h
- hash_table.h
- image.h
- library.h
- list.h
- logger.h
- math.h
- mem_allocator.h
- mutex.h
- quaternion.h
- ref_count.h
- rsys.h
- signal.h
- str.h
- stretchy_array.h)
-
-# Prepend each file in the `_files' list by `_path'
-rcmake_prepend_path(RSYS_FILES_SRC ${RSYS_SOURCE_DIR})
-rcmake_prepend_path(RSYS_FILES_INC ${RSYS_SOURCE_DIR})
-
-add_library(rsys SHARED ${RSYS_FILES_SRC} ${RSYS_FILES_INC})
-target_link_libraries(rsys ${CMAKE_THREAD_LIBS_INIT})
-set_target_properties(rsys PROPERTIES
- DEFINE_SYMBOL RSYS_SHARED_BUILD
- VERSION ${VERSION}
- SOVERSION ${VERSION_MAJOR})
-
-rcmake_setup_devel(rsys RSys ${VERSION} rsys/rsys_version.h)
-
-target_link_libraries(rsys m)
-if(NOT MINGW)
- target_link_libraries(rsys dl)
-endif(NOT MINGW)
-
-################################################################################
-# Add tests
-################################################################################
-if(NOT NO_TEST)
- macro(new_test _name)
- add_executable(${_name} ${RSYS_SOURCE_DIR}/${_name}.c)
- set(_libraries ${ARGN})
- foreach(_lib ${_libraries})
- target_link_libraries(${_name} ${_lib})
- endforeach(_lib)
- add_test(${_name} ${_name})
- endmacro(new_test)
-
- new_test(test_atomic)
- new_test(test_binary_heap rsys)
- new_test(test_dynamic_array rsys)
- new_test(test_float2 m)
- new_test(test_float3 m)
- new_test(test_float4 m)
- new_test(test_float22)
- new_test(test_float33 m)
- new_test(test_float44 rsys)
- new_test(test_free_list rsys)
- new_test(test_hash_table rsys)
- new_test(test_library rsys)
- new_test(test_list rsys)
- new_test(test_logger rsys)
- new_test(test_mem_allocator rsys)
- new_test(test_math m)
- new_test(test_quaternion rsys)
- new_test(test_ref)
- new_test(test_signal rsys)
- new_test(test_str rsys)
- new_test(test_stretchy_array rsys)
- new_test(test_time rsys)
-
- add_library(test_lib SHARED ${RSYS_SOURCE_DIR}/test_library.c)
- set_target_properties(test_lib PROPERTIES
- COMPILE_DEFINITIONS TEST_LIBRARY_BUILD_LIB
- DEBUG_POSTFIX "")
-
- if(NOT OPENMP_FOUND)
- message(STATUS "No OpenMP support: multi-threaded tests cannot be generated")
- else(NOT OPENMP_FOUND)
- new_test(test_condition rsys)
- new_test(test_mutex rsys)
- set_target_properties(test_mutex test_condition PROPERTIES
- COMPILE_FLAGS ${OpenMP_C_FLAGS}
- LINK_FLAGS ${OpenMP_C_FLAGS})
- endif(NOT OPENMP_FOUND)
-endif(NOT NO_TEST)
-
-################################################################################
-# Define output & install directories
-################################################################################
-install(TARGETS rsys
- ARCHIVE DESTINATION bin
- LIBRARY DESTINATION lib
- RUNTIME DESTINATION bin)
-install(FILES ${RSYS_FILES_INC} DESTINATION include/rsys)
-
+# Copyright (C) 2013-2015 Vincent Forest (vaplv@free.fr)
+#
+# This CMake script is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This CMake script is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this CMake script. If not, see <http://www.gnu.org/licenses/>.
+
+cmake_minimum_required(VERSION 2.6)
+project(rsys C)
+cmake_policy(SET CMP0011 NEW)
+enable_testing()
+
+set(RSYS_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+option(NO_TEST "Disable the test" OFF)
+
+################################################################################
+# Check dependencies
+################################################################################
+find_package(OpenMP)
+find_package(RCMake REQUIRED)
+find_package(Threads REQUIRED)
+
+set(CMAKE_MODULE_PATH ${RCMAKE_SOURCE_DIR})
+include(rcmake)
+
+################################################################################
+# Configure and define targets
+################################################################################
+set(VERSION_MAJOR 0)
+set(VERSION_MINOR 1)
+set(VERSION_PATCH 1)
+set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+
+set(RSYS_FILES_SRC
+ clock_time.c
+ float44.c
+ image.c
+ library.c
+ logger.c
+ mem_allocator.c
+ quaternion.c
+ str.c)
+
+if(CMAKE_USE_PTHREADS_INIT)
+ set(RSYS_FILES_SRC_THREAD
+ pthread/pthread_condition.c
+ pthread/pthread_mutex.c)
+elseif(CMAKE_USE_WIN32_THREADS_INIT)
+ set(RSYS_FILES_SRC_THREAD
+ win32/win32_condition.c
+ win32/win32_mutex.c)
+endif(CMAKE_USE_PTHREADS_INIT)
+
+set(RSYS_FILES_INC
+ io_c99.h)
+set(RSYS_FILES_INC_API
+ binary_heap.h
+ clock_time.h
+ condition.h
+ dynamic_array.h
+ dynamic_array_char.h
+ dynamic_array_float.h
+ dynamic_array_uchar.h
+ dynamic_array_u32.h
+ dynamic_array_u64.h
+ dynamic_array_size_t.h
+ dynamic_array_str.h
+ floatX.h
+ float2.h
+ float3.h
+ float4.h
+ floatXY.h
+ float22.h
+ float33.h
+ float44.h
+ free_list.h
+ hash.h
+ hash_table.h
+ image.h
+ library.h
+ list.h
+ logger.h
+ math.h
+ mem_allocator.h
+ mutex.h
+ quaternion.h
+ ref_count.h
+ rsys.h
+ signal.h
+ str.h
+ stretchy_array.h)
+
+# Prepend each file in the `_files' list by `_path'
+rcmake_prepend_path(RSYS_FILES_SRC ${RSYS_SOURCE_DIR})
+rcmake_prepend_path(RSYS_FILES_SRC_THREAD ${RSYS_SOURCE_DIR})
+rcmake_prepend_path(RSYS_FILES_INC ${RSYS_SOURCE_DIR})
+rcmake_prepend_path(RSYS_FILES_INC_API ${RSYS_SOURCE_DIR})
+
+add_library(rsys SHARED
+ ${RSYS_FILES_SRC}
+ ${RSYS_FILES_SRC_THREAD}
+ ${RSYS_FILES_INC}
+ ${RSYS_FILES_INC_API})
+target_link_libraries(rsys ${CMAKE_THREAD_LIBS_INIT})
+set_target_properties(rsys PROPERTIES
+ DEFINE_SYMBOL RSYS_SHARED_BUILD
+ VERSION ${VERSION}
+ SOVERSION ${VERSION_MAJOR})
+
+rcmake_setup_devel(rsys RSys ${VERSION} rsys/rsys_version.h)
+
+if(CMAKE_COMPILER_IS_GNUCC)
+ target_link_libraries(rsys m)
+ if(NOT MINGW)
+ target_link_libraries(rsys dl)
+ endif(NOT MINGW)
+endif(CMAKE_COMPILER_IS_GNUCC)
+
+
+################################################################################
+# Add tests
+################################################################################
+if(NOT NO_TEST)
+ macro(new_test _name)
+ add_executable(${_name} ${RSYS_SOURCE_DIR}/${_name}.c)
+ set(_libraries ${ARGN})
+ foreach(_lib ${_libraries})
+ target_link_libraries(${_name} ${_lib})
+ endforeach(_lib)
+ add_test(${_name} ${_name})
+ endmacro(new_test)
+
+ if(CMAKE_COMPILER_IS_GNUCC)
+ set(MATH_LIB m)
+ endif(CMAKE_COMPILER_IS_GNUCC)
+
+ new_test(test_atomic)
+ new_test(test_binary_heap rsys)
+ new_test(test_dynamic_array rsys)
+ new_test(test_float2 ${MATH_LIB})
+ new_test(test_float3 ${MATH_LIB})
+ new_test(test_float4 ${MATH_LIB})
+ new_test(test_float22)
+ new_test(test_float33 ${MATH_LIB})
+ new_test(test_float44 rsys)
+ new_test(test_free_list rsys)
+ new_test(test_hash_table rsys)
+ new_test(test_library rsys)
+ new_test(test_list rsys)
+ new_test(test_logger rsys)
+ new_test(test_mem_allocator rsys)
+ new_test(test_math ${MATH_LIB})
+ new_test(test_quaternion rsys)
+ new_test(test_ref)
+ new_test(test_signal rsys)
+ new_test(test_str rsys)
+ new_test(test_stretchy_array rsys)
+ new_test(test_time rsys)
+
+ add_library(test_lib SHARED ${RSYS_SOURCE_DIR}/test_library.c)
+ set_target_properties(test_lib PROPERTIES
+ COMPILE_DEFINITIONS TEST_LIBRARY_BUILD_LIB
+ DEBUG_POSTFIX "")
+
+ if(NOT OPENMP_FOUND)
+ message(STATUS "No OpenMP support: multi-threaded tests cannot be generated")
+ else(NOT OPENMP_FOUND)
+ new_test(test_mutex rsys)
+ new_test(test_condition rsys)
+
+ set_target_properties(test_mutex test_condition PROPERTIES
+ COMPILE_FLAGS ${OpenMP_C_FLAGS})
+
+ if(CMAKE_COMPILER_IS_GNUCC)
+ set_target_properties(test_mutex test_condition PROPERTIES
+ LINK_FLAGS ${OpenMP_C_FLAGS})
+ endif(CMAKE_COMPILER_IS_GNUCC)
+
+ endif(NOT OPENMP_FOUND)
+endif(NOT NO_TEST)
+
+################################################################################
+# Define output & install directories
+################################################################################
+install(TARGETS rsys
+ ARCHIVE DESTINATION bin
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin)
+install(FILES ${RSYS_FILES_INC_API} DESTINATION include/rsys)
+
diff --git a/src/clock_time.c b/src/clock_time.c
@@ -13,10 +13,15 @@
* You should have received a copy of the GNU Lesser General Public License
* along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
-#define _POSIX_C_SOURCE 200112L
+#define _POSIX_C_SOURCE 200112L /* snprintf support */
#include "rsys.h"
-#if defined(MINGW) && defined(ARCH_32BITS)
+#if defined(COMPILER_CL) || (defined(MINGW) && defined(ARCH_32BITS))
+ #define CLOCK_TIME_WINDOWS
+#endif
+
+#ifdef CLOCK_TIME_WINDOWS
+ #include "io_c99.h" /* snprintf support */
#include <Windows.h>
#else
#include <time.h>
@@ -36,7 +41,7 @@
void
time_current(struct time* t)
{
-#if defined(MINGW) && defined(ARCH_32BITS)
+#ifdef CLOCK_TIME_WINDOWS
LARGE_INTEGER time, tmp;
BOOL b ;
ASSERT(t);
diff --git a/src/dynamic_array.h b/src/dynamic_array.h
@@ -54,8 +54,14 @@
struct DARRAY_TYPE__ {
DARRAY_DATA* data;
- /* Avoids alloc on small arrays */
+ /* Avoids alloc on small arrays. The CL compiler does not support the use of
+ * the ALIGN macro on structure fields and consequently this optimization is
+ * `disabled' for this compiler */
+#ifdef COMPILER_CL
+ char buf[1];
+#else
char ALIGN(MMIN(ALIGNOF(DARRAY_DATA), 16)) buf[16*sizeof(DARRAY_DATA)];
+#endif
size_t size;
size_t capacity;
struct mem_allocator* allocator;
@@ -108,7 +114,11 @@ DARRAY_FUNC__(init)
ASSERT(darray);
darray->data = (DARRAY_DATA*)darray->buf;
darray->size = 0;
+#ifdef COMPILER_CL
+ darray->capacity = 0;
+#else
darray->capacity = sizeof(darray->buf)/sizeof(DARRAY_DATA);
+#endif
FOR_EACH(i, 0, darray->capacity)
DARRAY_FUNCTOR_INIT(allocator, darray->data + i);
darray->allocator = allocator ? allocator : &mem_default_allocator;
@@ -130,7 +140,7 @@ DARRAY_FUNC__(release)(struct DARRAY_TYPE__* darray)
ASSERT(darray);
DARRAY_FUNC__(clear)(darray);
if( darray->data != (DARRAY_DATA*)darray->buf )
- MEM_FREE(darray->allocator, darray->data);
+ MEM_RM(darray->allocator, darray->data);
}
static INLINE res_T
@@ -158,13 +168,13 @@ DARRAY_FUNC__(reserve)(struct DARRAY_TYPE__* darray, const size_t sz)
DARRAY_FUNCTOR_INIT(darray->allocator, data+i);
res = DARRAY_FUNCTOR_COPY_AND_RELEASE(data+i, darray->data+i);
if(res != RES_OK) {
- MEM_FREE(darray->allocator, data);
+ MEM_RM(darray->allocator, data);
return res;
}
}
}
if(darray->data != (DARRAY_DATA*)darray->buf)
- MEM_FREE(darray->allocator, darray->data);
+ MEM_RM(darray->allocator, darray->data);
darray->data = data;
darray->capacity = sz_adjusted;
@@ -275,7 +285,7 @@ DARRAY_FUNC__(copy_and_clear)
/* Give the ownership of src->data to dst */
DARRAY_FUNC__(clear)(dst);
if(dst->data != (DARRAY_DATA*)dst->buf) {
- MEM_FREE(dst->allocator, dst->data);
+ MEM_RM(dst->allocator, dst->data);
}
dst->data = src->data;
dst->capacity = src->capacity;
diff --git a/src/free_list.h b/src/free_list.h
@@ -81,7 +81,7 @@ static FINLINE void
FLIST_FUNC__(release)(struct FLIST_TYPE__* list)
{
ASSERT(list);
- MEM_FREE(list->allocator, list->items);
+ MEM_RM(list->allocator, list->items);
}
static FINLINE char
diff --git a/src/hash.h b/src/hash.h
@@ -43,7 +43,7 @@ hash_fnv64(const void* data, const size_t len)
{
const uint64_t FNV64_PRIME =
(uint64_t)(((uint64_t)1<<40) + ((uint64_t)1<<8) + 0xB3);
- const uint64_t OFFSET64_BASIS = (uint64_t)14695981039346656037llu;
+ const uint64_t OFFSET64_BASIS = (uint64_t)14695981039346656037u;
const char* octets = (const char*)data;
uint64_t hash = OFFSET64_BASIS;
size_t i;
diff --git a/src/image.c b/src/image.c
@@ -18,6 +18,10 @@
#include <stdio.h>
#include <string.h>
+#ifdef COMPILER_CL
+ #include "io_c99.h"
+#endif
+
res_T
image_ppm_write
(const char* path,
@@ -42,12 +46,12 @@ image_ppm_write
#define FWRITE(Fp, String) \
{ \
const size_t i = fwrite(String, sizeof(char), strlen(String), Fp); \
- if(i != strlen(String) * sizeof(char)) { res = RES_MEM_ERR; goto error; } \
+ if(i != strlen(String) * sizeof(char)) { res = RES_MEM_ERR; goto error; }\
} (void)0
#define SNPRINTF(Buf, Sz, Str, Arg0, Arg1, Arg2) \
{ \
const int i = snprintf(Buf, Sz, Str, Arg0, Arg1, Arg2); \
- if( i >= BUFSIZ ) { res = RES_MEM_ERR; goto error; } \
+ if( i >= BUFSIZ ) { res = RES_MEM_ERR; goto error; } \
} (void)0
SNPRINTF(buf, BUFSIZ, "P3\n\n%i %i\n%i\n", width, height, 255);
diff --git a/src/image.h b/src/image.h
@@ -23,9 +23,9 @@ BEGIN_DECLS
RSYS_API res_T
image_ppm_write
(const char* path,
- int width,
- int height,
- int bytes_per_pixel,
+ const int width,
+ const int height,
+ const int bytes_per_pixel,
const unsigned char* buffer);
END_DECLS
diff --git a/src/io_c99.h b/src/io_c99.h
@@ -0,0 +1,56 @@
+/* Copyright (C) 2013-2015 Vincent Forest (vaplv@free.fr)
+ *
+ * The RSys library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The RSys library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef IO_C99_H
+#define IO_C99_H
+
+#include "rsys.h"
+
+#ifdef COMPILER_CL
+
+#include <stdarg.h>
+
+#define snprintf snprintf_c99__
+#define vsnprintf vsnprint_c99__
+
+static INLINE int
+vsnprint_c99__(char* str, size_t sz, const char* fmt, va_list arg_lst)
+{
+ int count = -1;
+
+ if(sz)
+ count = _vsnprintf_s(str, sz, _TRUNCATE, fmt, arg_lst);
+ if(count == -1)
+ count = _vscprintf(fmt, arg_lst);
+
+ return count;
+}
+
+static INLINE int
+snprintf_c99__(char* str, size_t sz, const char* fmt, ...)
+{
+ int count;
+ va_list arg_lst;
+
+ va_start(arg_lst, fmt);
+ count = vsnprint_c99__(str, sz, fmt, arg_lst);
+ va_end(arg_lst);
+
+ return count;
+}
+
+#endif /* COMPILER_CL */
+
+#endif /* IO_C99_H */
diff --git a/src/logger.c b/src/logger.c
@@ -14,6 +14,7 @@
* along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
#define _POSIX_C_SOURCE 200112L /* vsnprintf support */
+#include "io_c99.h"
#include "logger.h"
res_T
diff --git a/src/logger.h b/src/logger.h
@@ -22,7 +22,7 @@
#include <stdarg.h>
-#define LOGGER_DEFAULT (struct logger*)0xC0DE
+#define LOGGER_DEFAULT ((struct logger*)(int64_t)0xC0DE)
enum log_type {
LOG_OUTPUT,
diff --git a/src/math.h b/src/math.h
@@ -17,13 +17,14 @@
#define MATH_H
#include "rsys.h"
+#include <float.h>
#include <math.h>
#define MMAX(A, B) ((A) > (B) ? (A) : (B))
#define MMIN(A, B) ((A) < (B) ? (A) : (B))
#define CLAMP(A, Min, Max) MMIN(MMAX(Min, A), Max)
#define IS_POW2(A) (((A) & ((A)-1)) == 0 && (A) > 0)
-#define INF (1.0/0.0)
+#define INF (DBL_MAX + DBL_MAX)
#define IS_INF(X) ((X==INF) || (X==-INF))
#define PI 3.14159265358979323846
#define RCP_PI 0.31830988618379067154 /* 1/ pi */
diff --git a/src/mem_allocator.c b/src/mem_allocator.c
@@ -22,15 +22,16 @@
#include <malloc.h>
#include <string.h>
-#ifdef MINGW
- /* On MINGW the _aligned_msize function is not defined. The size is thus
+#ifdef OS_WINDOWS
+ /* On Windows the _aligned_msize function is not defined. The size is thus
* stored into the memory block header */
#define MEM_HEADER_SIZE (2 * sizeof(size_t))
+ #include "io_c99.h"
#endif
struct alloc_counter {
- int64_t nb_allocs;
- int64_t allocated_size;
+ ATOMIC nb_allocs;
+ ATOMIC allocated_size;
};
/*******************************************************************************
@@ -45,13 +46,15 @@ mem_alloc(const size_t size)
if(size) {
#if defined(OS_UNIX)
mem = malloc(size);
-#elif defined(MINGW)
+#elif defined(OS_WINDOWS)
const size_t DEFAULT_ALIGNMENT = 16;
mem = _aligned_offset_malloc
(size + MEM_HEADER_SIZE, DEFAULT_ALIGNMENT, MEM_HEADER_SIZE);
((size_t*)mem)[0] = DEFAULT_ALIGNMENT;
((size_t*)mem)[1] = size + MEM_HEADER_SIZE;
mem = ((char*)mem) + MEM_HEADER_SIZE;
+#else
+ #error "Unsupported OS"
#endif
}
if(mem) {
@@ -81,7 +84,7 @@ mem_realloc(void* mem, const size_t size)
if(mem == NULL) {
new_mem = mem_alloc(size);
} else if(size == 0) {
- mem_free(mem);
+ mem_rm(mem);
} else {
const size_t old_size = mem_size(mem);
@@ -90,7 +93,7 @@ mem_realloc(void* mem, const size_t size)
&& g_alloc_counter.allocated_size >= (int64_t)old_size);
ATOMIC_SUB( &g_alloc_counter.allocated_size, old_size);
-#if defined(MINGW)
+#if defined(OS_WINDOWS)
mem = ((char*)mem) - MEM_HEADER_SIZE;
new_mem = _aligned_offset_realloc
(mem, size + MEM_HEADER_SIZE, ((size_t*)mem)[0], MEM_HEADER_SIZE);
@@ -98,6 +101,8 @@ mem_realloc(void* mem, const size_t size)
new_mem = ((char*)new_mem) + MEM_HEADER_SIZE;
#elif defined(OS_UNIX)
new_mem = realloc( mem, size );
+#else
+ #error "Unsupported OS"
#endif
ATOMIC_ADD(&g_alloc_counter.allocated_size, mem_size(new_mem));
}
@@ -112,7 +117,7 @@ mem_alloc_aligned(const size_t size, const size_t alignment)
if(size
&& IS_POW2( alignment )
&& alignment <= 32768 /* 32 KB */) {
-#if defined(MINGW)
+#if defined(OS_WINDOWS)
mem = _aligned_offset_malloc
(size + MEM_HEADER_SIZE, alignment, MEM_HEADER_SIZE);
((size_t*)mem)[0] = alignment;
@@ -125,6 +130,8 @@ mem_alloc_aligned(const size_t size, const size_t alignment)
/* The following assert may not occur due to previous conditions */
ASSERT(result != EINVAL);
ASSERT((result != ENOMEM) || (mem == NULL));
+#else
+ #error "Unsupported OS"
#endif
if(mem) {
ATOMIC_ADD(&g_alloc_counter.allocated_size, mem_size(mem));
@@ -135,7 +142,7 @@ mem_alloc_aligned(const size_t size, const size_t alignment)
}
void
-mem_free(void* mem)
+mem_rm(void* mem)
{
if(mem) {
ASSERT
@@ -144,11 +151,13 @@ mem_free(void* mem)
&& g_alloc_counter.allocated_size >= (int64_t)mem_size(mem));
ATOMIC_SUB(&g_alloc_counter.allocated_size, mem_size(mem));
ATOMIC_DECR(&g_alloc_counter.nb_allocs);
-#if defined(MINGW)
+#if defined(OS_WINDOWS)
mem = ((char*)mem) - MEM_HEADER_SIZE;
_aligned_free( mem );
#elif defined(OS_UNIX)
free( mem );
+#else
+ #error "Unsupported OS"
#endif
}
}
@@ -158,11 +167,13 @@ mem_size(void* mem)
{
size_t mem_size = 0;
if(mem) {
-#if defined(MINGW)
+#if defined(OS_WINDOWS)
void* raw_mem = ((char*)mem) - MEM_HEADER_SIZE;
mem_size = ((size_t*)raw_mem)[1];
#elif defined(OS_UNIX)
mem_size = malloc_usable_size(mem);
+#else
+ #error "Unsupported OS"
#endif
}
return mem_size;
@@ -225,7 +236,7 @@ default_free(void* data, void* mem)
ATOMIC_SUB(&counter->allocated_size, size_mem);
ATOMIC_DECR(&counter->nb_allocs);
#endif /* TRACK_DEFAULT_ALLOC */
- mem_free(mem);
+ mem_rm(mem);
}
}
@@ -490,7 +501,7 @@ proxy_free(void* data, void* mem)
proxy_data->node_list = node->next;
}
mutex_unlock(proxy_data->mutex);
- MEM_FREE(proxy_data->allocator, node);
+ MEM_RM(proxy_data->allocator, node);
}
}
@@ -612,7 +623,7 @@ proxy_dump
******************************************************************************/
static struct alloc_counter default_alloc_counter = {0, 0};
-EXPORT_SYM struct mem_allocator mem_default_allocator = {
+struct mem_allocator mem_default_allocator = {
default_alloc,
default_calloc,
default_realloc,
@@ -668,7 +679,7 @@ exit:
error:
if(proxy_data) {
if(proxy_data->mutex) mutex_destroy(proxy_data->mutex);
- MEM_FREE(allocator, proxy_data);
+ MEM_RM(allocator, proxy_data);
}
if(proxy_allocator)
memset(proxy_allocator, 0, sizeof(struct mem_allocator));
@@ -686,7 +697,7 @@ mem_shutdown_proxy_allocator(struct mem_allocator* proxy)
ASSERT(proxy_data->node_list == NULL);
mutex_destroy(proxy_data->mutex);
allocator = proxy_data->allocator;
- MEM_FREE(allocator, proxy_data);
+ MEM_RM(allocator, proxy_data);
memset(proxy, 0, sizeof(struct mem_allocator));
}
diff --git a/src/mem_allocator.h b/src/mem_allocator.h
@@ -70,7 +70,7 @@ struct mem_allocator {
};
/* Default allocator. */
-extern struct mem_allocator mem_default_allocator;
+RSYS_API struct mem_allocator mem_default_allocator;
/*******************************************************************************
* Helper macros
@@ -88,8 +88,8 @@ extern struct mem_allocator mem_default_allocator;
((Allocator)->alloc_aligned \
((Allocator)->data, (Size), (Alignment), __FILE__, __LINE__))
-#define MEM_FREE(Allocator, Mem) \
- ((Allocator)->free((Allocator)->data, (Mem)))
+#define MEM_RM(Allocator, Mem) \
+ ((Allocator)->free((Allocator)->data, (void*)(Mem)))
#define MEM_SIZE(Allocator, Mem) \
((Allocator)->mem_size((Allocator)->data, (Mem)))
@@ -110,7 +110,7 @@ RSYS_API void* mem_alloc(const size_t size);
RSYS_API void* mem_calloc(const size_t nelmts, const size_t size);
RSYS_API void* mem_realloc(void* ptr, const size_t size);
RSYS_API void* mem_alloc_aligned(const size_t size, const size_t alignment);
-RSYS_API void mem_free(void* ptr);
+RSYS_API void mem_rm(void* ptr);
RSYS_API size_t mem_size(void* ptr);
RSYS_API size_t mem_allocated_size(void);
diff --git a/src/mutex.h b/src/mutex.h
@@ -26,19 +26,6 @@ RSYS_API void mutex_destroy(struct mutex* mutex);
RSYS_API void mutex_lock(struct mutex* mutex);
RSYS_API void mutex_unlock(struct mutex* mutex);
-struct mutex_spin;
-RSYS_API struct mutex_spin* mutex_spin_create(void); /* NULL <=> error */
-RSYS_API void mutex_spin_destroy(struct mutex_spin* mutex);
-RSYS_API void mutex_spin_lock(struct mutex_spin* mutex);
-RSYS_API void mutex_spin_unlock(struct mutex_spin* mutex);
-
-struct mutex_rw;
-RSYS_API struct mutex_rw* mutex_rw_create(void);/* NULL <=> error */
-RSYS_API void mutex_rw_destroy(struct mutex_rw* mutex);
-RSYS_API void mutex_rw_rlock(struct mutex_rw* mutex);
-RSYS_API void mutex_rw_wlock(struct mutex_rw* mutex);
-RSYS_API void mutex_rw_unlock(struct mutex_rw* mutex);
-
END_DECLS
#endif /* MUTEX_H */
diff --git a/src/pthread/pthread_condition.c b/src/pthread/pthread_condition.c
@@ -37,7 +37,7 @@ cond_destroy(struct cond* cond)
{
ASSERT(cond);
PTHREAD(cond_destroy((pthread_cond_t*)cond));
- mem_free(cond);
+ mem_rm(cond);
}
void
diff --git a/src/pthread/pthread_mutex.c b/src/pthread/pthread_mutex.c
@@ -24,9 +24,6 @@
#define PTHREAD(Func) ASSERT(pthread_##Func == 0)
#endif
-/*******************************************************************************
- * Mutex
- ******************************************************************************/
struct mutex*
mutex_create(void)
{
@@ -41,7 +38,7 @@ mutex_destroy(struct mutex* mutex)
{
ASSERT(mutex);
PTHREAD(mutex_destroy((pthread_mutex_t*)mutex));
- mem_free(mutex);
+ mem_rm(mutex);
}
void
@@ -58,80 +55,5 @@ mutex_unlock(struct mutex* mutex)
PTHREAD(mutex_unlock((pthread_mutex_t*)mutex));
}
-/*******************************************************************************
- * Spinlock
- ******************************************************************************/
-struct mutex_spin*
-mutex_spin_create(void)
-{
- pthread_spinlock_t* spin = mem_alloc(sizeof(pthread_spinlock_t));
- if(spin)
- PTHREAD(spin_init(spin, PTHREAD_PROCESS_PRIVATE));
- return (struct mutex_spin*)spin;
-}
-
-void
-mutex_spin_destroy(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- PTHREAD(spin_destroy((pthread_spinlock_t*)mutex));
- mem_free(mutex);
-}
-
-void
-mutex_spin_lock(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- PTHREAD(spin_lock((pthread_spinlock_t*)mutex));
-}
-
-void
-mutex_spin_unlock(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- PTHREAD(spin_unlock((pthread_spinlock_t*)mutex));
-}
-
-/*******************************************************************************
- * Read Write mutex
- ******************************************************************************/
-struct mutex_rw*
-mutex_rw_create(void)
-{
- pthread_rwlock_t* mutex = mem_alloc(sizeof(pthread_rwlock_t));
- if(mutex)
- PTHREAD(rwlock_init(mutex, NULL));
- return (struct mutex_rw*)mutex;
-}
-
-void
-mutex_rw_destroy(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD(rwlock_destroy((pthread_rwlock_t*)mutex));
- mem_free(mutex);
-}
-
-void
-mutex_rw_rlock(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD(rwlock_rdlock((pthread_rwlock_t*)mutex));
-}
-
-void
-mutex_rw_wlock(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD(rwlock_wrlock((pthread_rwlock_t*)mutex));
-}
-
-void
-mutex_rw_unlock(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD(rwlock_unlock((pthread_rwlock_t*)mutex));
-}
-
#undef PTHREAD
diff --git a/src/ref_count.h b/src/ref_count.h
@@ -18,7 +18,7 @@
#include "rsys.h"
-typedef int32_t ref_T;
+typedef ATOMIC ref_T;
static FINLINE void
ref_init(ref_T* ref)
@@ -37,7 +37,7 @@ ref_get(ref_T* ref)
static FINLINE int
ref_put(ref_T* ref, void (*release)(ref_T*))
{
- int32_t curr = 0;
+ ATOMIC curr = 0;
ASSERT(NULL != ref);
ASSERT(NULL != release);
diff --git a/src/rsys.h b/src/rsys.h
@@ -16,7 +16,7 @@
#ifndef RSYS_H
#define RSYS_H
-#ifndef __GNUC__
+#if !defined(__GNUC__) && !defined(_MSC_VER)
#error "Unsupported compiler"
#endif
@@ -44,6 +44,8 @@
******************************************************************************/
#if defined(__GNUC__)
#define COMPILER_GCC
+#elif defined(_MSC_VER)
+ #define COMPILER_CL
#else
#error "Unsupported compiler"
#endif
@@ -64,16 +66,30 @@
#define EXPORT_SYM __attribute__((visibility("default")))
#define IMPORT_SYM
#define LOCAL_SYM __attribute__((visibility("hidden")))
+#elif defined(COMPILER_CL)
+ #define EXPORT_SYM __declspec(dllexport)
+ #define IMPORT_SYM __declspec(dllimport)
+ #define LOCAL_SYM
+#else
+ #error "Undefined symbol visibility macros"
#endif
#if defined(OS_UNIX)
#define SHARED_LIBRARY_PREFIX "lib"
#define SHARED_LIBRARY_SUFFIX ".so"
-#elif defined(OS_WINDOWS) && defined(MINGW)
- #define SHARED_LIBRARY_PREFIX "lib"
+#elif defined(OS_WINDOWS)
+ #if defined(MINGW)
+ #define SHARED_LIBRARY_PREFIX "lib"
+ #elif defined(COMPILER_CL)
+ #define SHARED_LIBRARY_PREFIX
+ #endif
#define SHARED_LIBRARY_SUFFIX ".dll"
#endif
+#if !defined(SHARED_LIBRARY_PREFIX) || !defined(SHARED_LIBRARY_SUFFIX)
+ #error "Undefined library suffix/prefix"
+#endif
+
#define SHARED_LIBRARY_NAME(Lib) SHARED_LIBRARY_PREFIX Lib SHARED_LIBRARY_SUFFIX
#if defined(RSYS_SHARED_BUILD)
@@ -89,27 +105,58 @@
#define FINLINE __inline__ __attribute__((always_inline))
#define INLINE __inline__
#define NOINLINE __attribute__((noinline))
+#elif defined(COMPILER_CL)
+ #define FINLINE __forceinline
+ #define INLINE __inline
+ #define NOINLINE __declspec(noinline)
+#else
+ #error "Undefined inlining macros"
#endif
/*******************************************************************************
* Data alignment
******************************************************************************/
-#define ALIGN(Size) __attribute__((aligned(Size)))
-#define ALIGNOF(Type) __alignof__(Type)
+#if defined(COMPILER_GCC)
+ #define ALIGN(Size) __attribute__((aligned(Size)))
+ #define ALIGNOF(Type) __alignof__(Type)
+#elif defined(COMPILER_CL)
+ #define ALIGN(Size) __declspec(align(Size))
+ #define ALIGNOF(Type) __alignof(Type)
+#else
+ #error "Undefined alignment macros"
+#endif
+
#define ALIGN_SIZE(Size, Algnt) (((Size) + ((Algnt) - 1)) & ~((Algnt) - 1))
#define IS_ALIGNED(Addr, Algnt) (((uintptr_t)(Addr) & ((Algnt)-1)) == 0)
/*******************************************************************************
* Atomic
******************************************************************************/
-#define ATOMIC_INCR(A) __sync_add_and_fetch((A), 1)
-#define ATOMIC_DECR(A) __sync_sub_and_fetch((A), 1)
-#define ATOMIC_ADD(A, V) __sync_add_and_fetch((A), V)
-#define ATOMIC_SUB(A, V) __sync_sub_and_fetch((A), V)
+#if defined(COMPILER_GCC)
+ #define ATOMIC int64_t
+ #define ATOMIC_INCR(A) __sync_add_and_fetch((A), 1)
+ #define ATOMIC_DECR(A) __sync_sub_and_fetch((A), 1)
+ #define ATOMIC_ADD(A, V) __sync_add_and_fetch((A), V)
+ #define ATOMIC_SUB(A, V) __sync_sub_and_fetch((A), V)
+ #define ATOMIC_CAS(Atom, NewVal, Comparand) /* Return the initial value */ \
+ __sync_val_compare_and_swap((Atom), (Comparand), (NewVal))
+#elif defined(COMPILER_CL)
+ #include <Windows.h>
+ #define ATOMIC LONGLONG
+ #define ATOMIC_INCR(A) InterlockedIncrement64((A))
+ #define ATOMIC_DECR(A) InterlockedDecrement64((A))
+ #define ATOMIC_ADD(A, V) \
+ (InterlockedExchangeAdd64((A), (LONGLONG)(V)) + (LONGLONG)(V))
+ #define ATOMIC_SUB(A, V) \
+ (InterlockedExchangeAdd64((A),-(LONGLONG)(V)) - (LONGLONG)(V))
+ #define ATOMIC_CAS(Atom, NewVal, Comparand) /* Return the initial value */ \
+ (InterlockedCompareExchange64(Atom, NewVal, Comparand))
+#else
+ #error "Undefined atomic operations"
+#endif
+
#define ATOMIC_SET(A, V) ATOMIC_CAS((A), V, (*A)) /*Return the initial value*/
#define ATOMIC_GET(A) ATOMIC_ADD(A, 0)
-#define ATOMIC_CAS(Atom, NewVal, Comparand) /* Return the initial value */ \
- __sync_val_compare_and_swap((Atom), (Comparand), (NewVal))
/*******************************************************************************
* Code checking
@@ -121,9 +168,15 @@
#define ASSERT(C) assert(C)
#endif
-#define STATIC_ASSERT(Cond, Msg) \
- static char CONCAT(CONCAT(CONCAT(STATIC_ASSERT_, COUNTER), _), Msg) \
- [1 - 2*(!(Cond))] __attribute__((unused))
+#ifdef COMPILER_GCC
+ #define STATIC_ASSERT(Cond, Msg) \
+ static char CONCAT(CONCAT(CONCAT(STATIC_ASSERT_, COUNTER), _), Msg) \
+ [1 - 2*(!(Cond))] __attribute__((unused))
+#else
+ #define STATIC_ASSERT(Cond, Msg) \
+ static char CONCAT(CONCAT(CONCAT(STATIC_ASSERT_, COUNTER), _), Msg) \
+ [1 - 2*(!(Cond))];
+#endif
#define FATAL(Msg) \
{ \
@@ -150,6 +203,9 @@
#ifdef COMPILER_GCC
#define LIKELY(X) __builtin_expect((X), 1)
#define UNLIKELY(X) __builtin_expect((X), 0)
+#else
+ #define LIKELY
+ #define UNLIKELY
#endif
/*******************************************************************************
@@ -166,12 +222,26 @@
/*******************************************************************************
* SIMD instruction sets
******************************************************************************/
-#ifdef __SSE__
- #define SIMD_SSE
-#endif
+#if defined(COMPILER_GCC)
+ #ifdef __SSE__
+ #define SIMD_SSE
+ #endif
-#ifdef __SSE2__
- #define SIMD_SSE2
+ #ifdef __SSE2__
+ #define SIMD_SSE2
+ #endif
+#elif defined(COMPILER_CL)
+ #ifdef ARCH_64BITS
+ #define SIMD_SSE
+ #define SIMD_SSE2
+ #else /* 32-bits */
+ #if _M_IX86_FP >= 1
+ #define SIMD_SSE
+ #endif
+ #if _M_IX86_FP >= 2
+ #define SIMD_SSE2
+ #endif
+ #endif
#endif
/*******************************************************************************
diff --git a/src/str.c b/src/str.c
@@ -46,7 +46,7 @@ ensure_allocated(struct str* str, const size_t len, const char keep_old)
str->allocated = new_len * sizeof(char);
if(str->cstr != str->buffer)
- MEM_FREE(str->allocator, str->cstr);
+ MEM_RM(str->allocator, str->cstr);
str->cstr = buf;
return RES_OK;
diff --git a/src/str.h b/src/str.h
@@ -46,7 +46,7 @@ str_release(struct str* str)
{
ASSERT(str);
if(str->cstr != str->buffer)
- MEM_FREE(str->allocator, str->cstr);
+ MEM_RM(str->allocator, str->cstr);
str->cstr = NULL;
}
@@ -131,7 +131,7 @@ str_copy_and_clear( struct str* dst, struct str* src )
if(src->cstr != src->buffer && src->allocator == dst->allocator) {
/* Give the ownership of src->cstr to dst */
if(dst->cstr != dst->buffer )
- MEM_FREE(dst->allocator, dst->cstr);
+ MEM_RM(dst->allocator, dst->cstr);
dst->cstr = src->cstr;
dst->allocated = src->allocated;
dst->len = src->len;
diff --git a/src/stretchy_array.h b/src/stretchy_array.h
@@ -42,7 +42,7 @@
/* Free `Array' memory */
#define sa_release(Array) { \
if(Array) \
- mem_free(sa_raw__(Array)); \
+ mem_rm(sa_raw__(Array)); \
} (void)0
/* Push back `Val' in `Array' */
@@ -88,10 +88,8 @@ sa_grow_func__(void* array, const size_t increment, const size_t itemsize)
new_array = (size_t*)mem_alloc_aligned(sizeof_array, 16);
}
- if(!new_array) {
+ if(!new_array)
FATAL("Unsufficient memory\n");
- return NULL;
- }
if(!array) new_array[1] = 0;
new_array[0] = new_capacity;
diff --git a/src/test_atomic.c b/src/test_atomic.c
@@ -18,8 +18,8 @@
int
main(int argc, char** argv)
{
- int32_t atom = 0;
- int tmp;
+ ATOMIC atom = 0;
+ ATOMIC tmp;
(void)argc, (void)argv;
tmp = ATOMIC_INCR(&atom);
diff --git a/src/test_dynamic_array.c b/src/test_dynamic_array.c
@@ -49,6 +49,7 @@ const char* strs[] = {
};
const size_t nstrs = sizeof(strs)/sizeof(const char*);
+#if 0
static void
test_primitive_type(void)
{
@@ -95,6 +96,7 @@ test_primitive_type(void)
check_memory_allocator(&allocator_proxy);
mem_shutdown_proxy_allocator(&allocator_proxy);
}
+#endif
#include "str.h"
#define DARRAY_NAME struct_str
@@ -181,7 +183,7 @@ int
main(int argc, char** argv)
{
(void)argc, (void)argv;
- test_primitive_type();
+ /*test_primitive_type();*/
test_struct();
CHECK(mem_allocated_size(), 0);
return 0;
diff --git a/src/test_float2.c b/src/test_float2.c
@@ -69,7 +69,7 @@ main(int argc, char** argv)
CHECK_F2(dst, f2(c, 0.5f, 1.5f));
CHECK(f2_sum(b), 3.f);
CHECK(f2_dot(a, b), 2.f);
- CHECK(eq_epsf(f2_len(a), sqrt(1.0f), FLT_EPSILON), 1);
+ CHECK(eq_epsf(f2_len(a), (float)sqrt(1.0f), FLT_EPSILON), 1);
CHECK(f2_is_normalized(b), 0);
f = f2_normalize(dst, b);
diff --git a/src/test_math.c b/src/test_math.c
@@ -15,6 +15,11 @@
#include "math.h"
+#ifdef COMPILER_CL
+ #pragma warning(disable:4127) /* Constant conditional expression */
+ #pragma warning(disable:4723) /* Division by zero */
+#endif
+
int
main(int argc, char** argv)
{
@@ -45,6 +50,7 @@ main(int argc, char** argv)
CHECK(eq_eps(PI, 3.14159265358979323846, 1.e-8), 1);
CHECK(eq_eps(RCP_PI, 1.0/PI, 1.e-8), 1);
+
CHECK(1.f/0.f, (float)INF);
CHECK(-1.f/0.f, (float)-INF);
NCHECK(1.0/0.0, -INF);
diff --git a/src/test_mem_allocator.c b/src/test_mem_allocator.c
@@ -29,7 +29,7 @@ test_regular(void)
p = mem_alloc_aligned(1024, ALIGNOF(char));
NCHECK(p, NULL);
CHECK(IS_ALIGNED((uintptr_t)p, ALIGNOF(char)), 1);
- mem_free( p );
+ mem_rm( p );
q[0] = mem_alloc_aligned(10, 64);
q[1] = mem_alloc(58);
@@ -48,7 +48,7 @@ test_regular(void)
((char*)p)[i] = (char)i;
}
- mem_free(q[1]);
+ mem_rm(q[1]);
p = mem_realloc(p, 8);
FOR_EACH(i, 0, 4) {
@@ -58,21 +58,21 @@ test_regular(void)
((char*)p)[i] = (char)i;
}
- mem_free(q[2]);
+ mem_rm(q[2]);
p = mem_realloc(p, 5);
FOR_EACH(i, 0, 5) {
CHECK(((char*)p )[i], (char)i);
}
- mem_free(p);
+ mem_rm(p);
p = NULL;
p = mem_realloc(NULL, 16);
NCHECK(p, NULL);
p = mem_realloc(p, 0);
- mem_free(q[0]);
+ mem_rm(q[0]);
CHECK(mem_alloc_aligned(1024, 0 ), NULL);
CHECK(mem_alloc_aligned(1024, 3 ), NULL);
@@ -89,7 +89,7 @@ test_allocator(struct mem_allocator* allocator)
p = MEM_ALLOC_ALIGNED(allocator, 1024, ALIGNOF(char));
NCHECK(p, NULL);
CHECK(IS_ALIGNED((uintptr_t)p, ALIGNOF(char)), 1);
- MEM_FREE(allocator, p);
+ MEM_RM(allocator, p);
q[0] = MEM_ALLOC_ALIGNED(allocator, 10, 8);
q[1] = MEM_CALLOC(allocator, 1, 58);
@@ -112,7 +112,7 @@ test_allocator(struct mem_allocator* allocator)
printf("truncated dump:\n%s\n", dump);
MEM_DUMP(allocator, NULL, 0); /* may not crash */
- MEM_FREE(allocator, q[1]);
+ MEM_RM(allocator, q[1]);
p = MEM_REALLOC(allocator, p, 8);
for(i = 0; i < 4; ++i)
@@ -120,20 +120,20 @@ test_allocator(struct mem_allocator* allocator)
for(i = 4; i < 8; ++i)
((char*)p)[i] = (char)i;
- MEM_FREE(allocator, q[2]);
+ MEM_RM(allocator, q[2]);
p = MEM_REALLOC(allocator, p, 5);
for(i = 0; i < 5; ++i)
CHECK(((char*)p)[i], (char)i);
- MEM_FREE(allocator, p);
+ MEM_RM(allocator, p);
p = NULL;
p = MEM_REALLOC(allocator, NULL, 16);
NCHECK(p, NULL);
p = MEM_REALLOC(allocator, p, 0);
- MEM_FREE(allocator, q[0]);
+ MEM_RM(allocator, q[0]);
CHECK(MEM_ALLOC_ALIGNED(allocator, 1024, 0), NULL);
CHECK(MEM_ALLOC_ALIGNED(allocator, 1024, 3), NULL);
diff --git a/src/test_mutex.c b/src/test_mutex.c
@@ -165,99 +165,34 @@ static const char src_str[] = {
' ','B','A',' ','R','N','E','G','U','!','\n','\0'
};
-enum mutex_type {
- MUTEX_COMMON,
- MUTEX_SPIN,
- MUTEX_RW
-};
-
struct string
{
struct mutex* mutex;
- struct mutex_spin* mutex_spin;
- struct mutex_rw* mutex_rw;
char str[sizeof(src_str)/sizeof(char) + 1 /* +1 <=< '\0'*/ ];
int i;
};
static void
-string_write(struct string* string, const enum mutex_type type)
+string_write(struct string* string)
{
ASSERT(string);
- switch(type) {
- case MUTEX_COMMON:
- {
- for(;;) {
- mutex_lock(string->mutex);
- if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
- mutex_unlock(string->mutex);
- break;
- }
-
- string->str[string->i] = src_str[string->i];
- ++string->i;
-
- mutex_unlock(string->mutex);
- }
- }
- break;
- case MUTEX_SPIN:
- {
- for(;;) {
- mutex_spin_lock(string->mutex_spin);
- if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
- mutex_spin_unlock(string->mutex_spin);
- break;
- }
-
- string->str[string->i] = src_str[string->i];
- ++string->i;
-
- mutex_spin_unlock(string->mutex_spin);
- }
- }
+ for(;;) {
+ mutex_lock(string->mutex);
+ if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
+ mutex_unlock(string->mutex);
break;
- case MUTEX_RW:
- {
- for(;;) {
- mutex_rw_wlock(string->mutex_rw);
- if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
- mutex_rw_unlock(string->mutex_rw);
- break;
- }
+ }
- string->str[string->i] = src_str[string->i];
- ++string->i;
+ string->str[string->i] = src_str[string->i];
+ ++string->i;
- mutex_rw_unlock(string->mutex_rw);
- }
- }
- break;
- default: ASSERT(0); break;
+ mutex_unlock(string->mutex);
}
}
static void
-string_read(struct string* string)
-{
- int i = 0;
- ASSERT(string);
- do {
- mutex_rw_rlock(string->mutex_rw);
- i = string->i;
-
- mutex_rw_unlock(string->mutex_rw);
-
- } while( (unsigned)i < sizeof(src_str)/sizeof(char));
-
- mutex_rw_rlock(string->mutex_rw);
- printf("%s\n", string->str);
- mutex_rw_unlock(string->mutex_rw);
-}
-
-static void
-test_mutex(const enum mutex_type type)
+test_mutex(void)
{
struct string string;
struct time time_start, time_end, time_res;
@@ -266,40 +201,19 @@ test_mutex(const enum mutex_type type)
string.str[0] = '\0';
string.i = 0;
- switch(type) {
- case MUTEX_COMMON:
- string.mutex = mutex_create();
- NCHECK(string.mutex, NULL);
- break;
- case MUTEX_SPIN:
- string.mutex_spin = mutex_spin_create();
- NCHECK(string.mutex_spin, NULL);
- break;
- case MUTEX_RW:
- string.mutex_rw = mutex_rw_create();
- NCHECK(string.mutex_rw, NULL);
- break;
- default: ASSERT(0); break;
- }
-
+ string.mutex = mutex_create();
+ NCHECK(string.mutex, NULL);
+
time_current(&time_start);
#pragma omp parallel
{
- #pragma omp single nowait
- {
- if(type == MUTEX_RW) {
- #pragma omp task shared(string)
- string_read(&string);
- }
- }
-
#pragma omp sections
{
#pragma omp section
- string_write(&string, type);
+ string_write(&string);
#pragma omp section
- string_write(&string, type);
+ string_write(&string);
}
}
time_current(&time_end);
@@ -316,25 +230,14 @@ test_mutex(const enum mutex_type type)
CHECK(string.i, sizeof(src_str)/sizeof(char) + 1);
CHECK(strcmp(string.str, src_str), 0);
- if(type == MUTEX_RW) {
- #pragma omp taskwait
- }
-
- switch(type) {
- case MUTEX_COMMON: mutex_destroy(string.mutex); break;
- case MUTEX_SPIN: mutex_spin_destroy(string.mutex_spin); break;
- case MUTEX_RW: mutex_rw_destroy(string.mutex_rw); break;
- default: ASSERT(0); break;
- }
+ mutex_destroy(string.mutex);
}
int
main(int argc, char** argv)
{
(void)argc, (void)argv;
- test_mutex(MUTEX_COMMON);
- test_mutex(MUTEX_SPIN);
- test_mutex(MUTEX_RW);
+ test_mutex();
return 0;
}
diff --git a/src/win32/win32_condition.c b/src/win32/win32_condition.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 2013-2015 Vincent Forest (vaplv@free.fr)
+ *
+ * The RSys library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The RSys library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "../condition.h"
+#include "../mem_allocator.h"
+#include <Windows.h>
+
+struct cond*
+cond_create(void)
+{
+ PCONDITION_VARIABLE cond = mem_alloc(sizeof(CONDITION_VARIABLE));
+ if(cond)
+ InitializeConditionVariable(cond);
+ return (struct cond*)cond;
+}
+
+void
+cond_destroy(struct cond* cond)
+{
+ ASSERT(cond);
+ mem_rm(cond);
+}
+
+void
+cond_wait(struct cond* cond, struct mutex* mutex)
+{
+ BOOL b;
+ (void)b;
+ ASSERT(cond);
+ b = SleepConditionVariableCS
+ ((PCONDITION_VARIABLE)cond, (PCRITICAL_SECTION)mutex, INFINITE);
+ ASSERT(b != 0);
+}
+
+void
+cond_signal(struct cond* cond)
+{
+ ASSERT(cond);
+ WakeConditionVariable((PCONDITION_VARIABLE)cond);
+}
+
+void
+cond_broadcast(struct cond* cond)
+{
+ ASSERT(cond);
+ WakeAllConditionVariable((PCONDITION_VARIABLE)cond);
+}
+
diff --git a/src/win32/win32_mutex.c b/src/win32/win32_mutex.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 2013-2015 Vincent Forest (vaplv@free.fr)
+ *
+ * The RSys library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The RSys library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "../mem_allocator.h"
+#include "../mutex.h"
+#include <Windows.h>
+
+struct mutex*
+mutex_create(void)
+{
+ LPCRITICAL_SECTION mutex = mem_alloc(sizeof(CRITICAL_SECTION));
+ if(mutex)
+ InitializeCriticalSection(mutex);
+ return (struct mutex*)mutex;
+}
+
+void
+mutex_destroy(struct mutex* mutex)
+{
+ ASSERT(mutex);
+ DeleteCriticalSection((LPCRITICAL_SECTION)mutex);
+ mem_rm(mutex);
+}
+
+void
+mutex_lock(struct mutex* mutex)
+{
+ ASSERT(mutex);
+ EnterCriticalSection((LPCRITICAL_SECTION)mutex);
+}
+
+void
+mutex_unlock(struct mutex* mutex)
+{
+ ASSERT(mutex);
+ LeaveCriticalSection((LPCRITICAL_SECTION)mutex);
+}
+