From d3f4062bc89e4dfd7029c3010f479560b90f9c21 Mon Sep 17 00:00:00 2001 From: Hugues Delorme Date: Mon, 30 Mar 2015 16:37:47 +0200 Subject: [PATCH] gmio_core: add utility functions for gmio_buffer --- CMakeLists.txt | 30 ++++++++--- benchs/bench_libstl/main.c | 96 ------------------------------------ src/gmio_core/buffer.c | 56 +++++++++++++++++++++ src/gmio_core/buffer.h | 16 ++++++ src/gmio_core/config.h.cmake | 3 ++ 5 files changed, 97 insertions(+), 104 deletions(-) delete mode 100644 benchs/bench_libstl/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b29d55e..5d2c730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ ## "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". ############################################################################# -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8) include(CheckIncludeFiles) include(CheckFunctionExists) @@ -54,18 +54,32 @@ if(NOT BUILD_STRICT_C90) check_include_files(stdbool.h GMIO_HAVE_STDBOOL_H) endif() +# Have alloca()-like function ? +check_c_source_compiles( + "#include + int main() { void* ptr = alloca(256); return 0; }" + GMIO_HAVE_BSD_ALLOCA_FUNC) + +check_c_source_compiles( + "#include + int main() { void* ptr = _alloca(256); return 0; }" + GMIO_HAVE_WIN_ALLOCA_FUNC) + # Have builtin byte swap functions ? if(CMAKE_COMPILER_IS_GNUCC) # __builtin_bswap16() is missing in x86 GCC version prior to v4.7 # See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 - check_c_source_compiles("int main() { return (int)__builtin_bswap16(0x1122); }" - GMIO_HAVE_GCC_BUILTIN_BSWAP16_FUNC) - check_c_source_compiles("int main() { return (int)__builtin_bswap32(0x11223344); }" - GMIO_HAVE_GCC_BUILTIN_BSWAP32_FUNC) + check_c_source_compiles( + "int main() { return (int)__builtin_bswap16(0x1122); }" + GMIO_HAVE_GCC_BUILTIN_BSWAP16_FUNC) + check_c_source_compiles( + "int main() { return (int)__builtin_bswap32(0x11223344); }" + GMIO_HAVE_GCC_BUILTIN_BSWAP32_FUNC) elseif(MSVC) - check_c_source_compiles("#include - int main() { return (int)_byteswap_ulong(0x11223344); }" - GMIO_HAVE_MSVC_BUILTIN_BSWAP_FUNC) + check_c_source_compiles( + "#include + int main() { return (int)_byteswap_ulong(0x11223344); }" + GMIO_HAVE_MSVC_BUILTIN_BSWAP_FUNC) endif() configure_file(src/gmio_core/config.h.cmake config.h @ONLY) diff --git a/benchs/bench_libstl/main.c b/benchs/bench_libstl/main.c deleted file mode 100644 index 092f595..0000000 --- a/benchs/bench_libstl/main.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include - -#include "../commons/bench_tools.h" -#include -#include - -typedef struct my_igeom -{ - uint32_t facet_count; -} my_igeom_t; - -static void dummy_process_triangle(void* cookie, - uint32_t triangle_id, - const gmio_stl_triangle_t* triangle) -{ - my_igeom_t* my_igeom = (my_igeom_t*)(cookie); - if (my_igeom != NULL) - ++(my_igeom->facet_count); -} - -static void libstl_gmio_stlb_read(const char* filepath) -{ - /* uint8_t stack_buff[30 * 1024]; */ - - my_igeom_t cookie; - gmio_transfer_t trsf; - gmio_stl_mesh_creator_t mesh_creator; - int result; - - FILE* file = fopen(filepath, "rb"); - if (file == NULL) { - fprintf(stderr, "Failed to open binary STL file %s\n", filepath); - return; - } - - cookie.facet_count = 0; - memset(&mesh_creator, 0, sizeof(gmio_stl_mesh_creator_t)); - mesh_creator.cookie = &cookie; - mesh_creator.add_triangle_func = dummy_process_triangle; - - memset(&trsf, 0, sizeof(gmio_transfer_t)); - gmio_stream_set_stdio(&trsf.stream, file); - trsf.buffer = (uint8_t*)malloc(512 * 1024); - trsf.buffer_size = 512 * 1024; - /* trsf.buffer = stack_buff; - trsf.buffer_size = 24 * 1024; */ - - result = gmio_stlb_read(&mesh_creator, &trsf, GMIO_LITTLE_ENDIAN); - if (gmio_error(result)) - fprintf(stderr, "gmio_stlb_read() error %i", result); - - fprintf(stdout, "Facet count: %i\n", cookie.facet_count); - - free(trsf.buffer); - fclose(file); -} - -static void libstl_gmio_stla_read(const char* filepath) -{ - gmio_transfer_t trsf; - int result; - FILE* file; - - file = fopen(filepath, "r"); - if (file == NULL) { - fprintf(stderr, "Failed to open ascii STL file %s\n", filepath); - return; - } - - memset(&trsf, 0, sizeof(gmio_transfer_t)); - gmio_stream_set_stdio(&trsf.stream, file); - trsf.buffer = (char*)malloc(512 * 1024); - trsf.buffer_size = 512 * 1024; - - result = gmio_stla_read(NULL, &trsf, 0); - if (gmio_error(result)) - fprintf(stderr, "gmio_stla_read() error %i", result); - - /* fprintf(stdout, "Facet count: %i\n", igeom.facet_count); */ - - fclose(file); -} - -int main(int argc, char** argv) -{ - if (argc < 3) - return -1; - - if (strcmp(argv[1], "--stla") == 0) - benchmark(&libstl_gmio_stla_read, "gmio_stla_read()", argc - 2, argv + 2); - else if (strcmp(argv[1], "--stlb") == 0) - benchmark(&libstl_gmio_stlb_read, "gmio_stlb_read()", argc - 2, argv + 2); - - return 0; -} diff --git a/src/gmio_core/buffer.c b/src/gmio_core/buffer.c index b511049..9967804 100644 --- a/src/gmio_core/buffer.c +++ b/src/gmio_core/buffer.c @@ -15,10 +15,66 @@ #include "buffer.h" +#include + +#if defined(GMIO_HAVE_BSD_ALLOCA_FUNC) +# include +#elif defined(GMIO_HAVE_WIN_ALLOCA_FUNC) +# include "error.h" +# include +# include +#endif + +GMIO_INLINE static gmio_buffer_t gmio_buffer_null() +{ + gmio_buffer_t buff = { 0 }; + return buff; +} + gmio_buffer_t gmio_buffer(void* ptr, size_t size) { gmio_buffer_t buff; buff.ptr = ptr; buff.size = size; + buff.deallocate_func = NULL; return buff; } + +gmio_buffer_t gmio_buffer_malloc(size_t size) +{ + gmio_buffer_t buff = gmio_buffer(malloc(size), size); + buff.deallocate_func = &free; + return buff; +} + +gmio_buffer_t gmio_buffer_calloc(size_t num, size_t size) +{ + gmio_buffer_t buff = gmio_buffer(calloc(num, size), num * size); + buff.deallocate_func = &free; + return buff; +} + +gmio_buffer_t gmio_buffer_alloca(size_t size) +{ +#if defined(GMIO_HAVE_BSD_ALLOCA_FUNC) + return gmio_buffer(alloca(size), size); +#elif defined(GMIO_HAVE_WIN_ALLOCA_FUNC) + __try { + return gmio_buffer(_alloca(size), size); + } + __except(GetExceptionCode() == STATUS_STACK_OVERFLOW) { + /* The stack overflowed */ + if (_resetstkoflw() == 0) + exit(GMIO_UNKNOWN_ERROR); + return gmio_buffer_null(); + } +#else + return gmio_buffer_null(); +#endif +} + +void gmio_buffer_deallocate(gmio_buffer_t *buffer) +{ + if (buffer != NULL && buffer->deallocate_func != NULL) + buffer->deallocate_func(buffer->ptr); +} diff --git a/src/gmio_core/buffer.h b/src/gmio_core/buffer.h index 0c46f28..a270644 100644 --- a/src/gmio_core/buffer.h +++ b/src/gmio_core/buffer.h @@ -32,6 +32,10 @@ struct gmio_buffer /*! Size (in bytes) of the memory buffer */ size_t size; + + /*! Optional pointer on function that deallocates the memory block \p ptr */ + void (*deallocate_func)(void* ptr); + }; typedef struct gmio_buffer gmio_buffer_t; @@ -40,6 +44,18 @@ GMIO_C_LINKAGE_BEGIN /*! Returns an initialized gmio_buffer object */ GMIO_LIB_EXPORT gmio_buffer_t gmio_buffer(void* ptr, size_t size); +/*! Returns a gmio_buffer object allocated with standard malloc() */ +GMIO_LIB_EXPORT gmio_buffer_t gmio_buffer_malloc(size_t size); + +/*! Returns a gmio_buffer object allocated with standard calloc() */ +GMIO_LIB_EXPORT gmio_buffer_t gmio_buffer_calloc(size_t num, size_t size); + +/*! Returns a gmio_buffer object allocated with OS-specific alloca() */ +GMIO_LIB_EXPORT gmio_buffer_t gmio_buffer_alloca(size_t size); + +/*! Safe and convenient call to gmio_buffer::deallocate_func() */ +GMIO_LIB_EXPORT void gmio_buffer_deallocate(gmio_buffer_t* buffer); + GMIO_C_LINKAGE_END #endif /* GMIO_BUFFER_H */ diff --git a/src/gmio_core/config.h.cmake b/src/gmio_core/config.h.cmake index 68b5167..02b157b 100644 --- a/src/gmio_core/config.h.cmake +++ b/src/gmio_core/config.h.cmake @@ -30,6 +30,9 @@ #cmakedefine GMIO_HOST_IS_BIG_ENDIAN +#cmakedefine GMIO_HAVE_BSD_ALLOCA_FUNC +#cmakedefine GMIO_HAVE_WIN_ALLOCA_FUNC + #if defined(__APPLE__) # if defined(__i386__) || defined(__ppc__) # define GMIO_TARGET_ARCH_BIT_SIZE 32