Mercurial > louis > mq > lightsd
view add_windows_support.patch @ 554:3fd912875434
windows wip, get the lgtd_time_monotonic library fully working and tested
author | Louis Opter <louis@opter.org> |
---|---|
date | Thu, 18 May 2017 11:00:10 -0700 |
parents | b3de1b255605 |
children |
line wrap: on
line source
# HG changeset patch # Parent 6ec1913ccfc63c8ca38368d04f885be5d59f8817 lightsd: get the build system and time_monotonic to work on Windows This is the first step towards Windows portability. diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,12 @@ ### Platform checks ############################################################ +INCLUDE(CheckFunctionExists) +INCLUDE(CheckVariableExists) +INCLUDE(TestBigEndian) + +TEST_BIG_ENDIAN(BIG_ENDIAN_SYSTEM) + # TODO: we need at least 2.0.19-stable because of the logging defines FIND_PACKAGE(Event2 REQUIRED COMPONENTS core) FIND_PACKAGE(Endian REQUIRED) @@ -37,16 +43,10 @@ INCLUDE(UseLATEX) ENDIF () -INCLUDE(CheckFunctionExists) -INCLUDE(CheckVariableExists) -INCLUDE(TestBigEndian) - INCLUDE(CompatReallocArray) INCLUDE(CompatSetProctitle) INCLUDE(CompatTimeMonotonic) -TEST_BIG_ENDIAN(BIG_ENDIAN_SYSTEM) - ### Global definitions ######################################################### INCLUDE(AddAllSubdirectories) @@ -54,11 +54,13 @@ SET(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) -SET(CMAKE_C_FLAGS "-pipe ${CMAKE_C_FLAGS}") -STRING(STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}") STRING(STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra -Wall -Wstrict-prototypes -std=c99") +IF (CMAKE_C_COMPILER_ID MATCHES "MSVC") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall") +ELSE () + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra -Wall -Wstrict-prototypes -std=c99 -pipe") +ENDIF () SET(CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE} "") IF (CMAKE_SYSTEM_NAME MATCHES "Linux") @@ -74,6 +76,13 @@ ADD_DEFINITIONS("-D_DARWIN_C_SOURCE=1") ENDIF () +IF (MSVC) + ADD_DEFINITIONS( + "-D_CRT_SECURE_NO_WARNINGS" + "-DNOMINMAX" + ) +ENDIF () + ADD_DEFINITIONS( "-DLGTD_BIG_ENDIAN_SYSTEM=${BIG_ENDIAN_SYSTEM}" "-DLGTD_SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P}" @@ -99,11 +108,12 @@ INCLUDE_DIRECTORIES( ${EVENT2_INCLUDE_DIR} + ${LIGHTSD_SOURCE_DIR} + ${LIGHTSD_SOURCE_DIR}/compat/generic + ${LIGHTSD_BINARY_DIR} ${LIGHTSD_BINARY_DIR}/compat - ${LIGHTSD_BINARY_DIR}/compat/generic ) -ADD_SUBDIRECTORY(compat) ADD_SUBDIRECTORY(core) ADD_SUBDIRECTORY(lifx) diff --git a/CMakeScripts/AddAllSubdirectories.cmake b/CMakeScripts/AddAllSubdirectories.cmake --- a/CMakeScripts/AddAllSubdirectories.cmake +++ b/CMakeScripts/AddAllSubdirectories.cmake @@ -1,8 +1,12 @@ FUNCTION(ADD_ALL_SUBDIRECTORIES) FILE(GLOB SUBDIRECTORIES "*") FOREACH (ENTRY ${SUBDIRECTORIES}) - IF (IS_DIRECTORY ${ENTRY} AND EXISTS "${ENTRY}/CMakeLists.txt") - ADD_SUBDIRECTORY(${ENTRY}) + IF ( + IS_DIRECTORY "${ENTRY}" AND + NOT IS_SYMLINK "${ENTRY}" AND + EXISTS "${ENTRY}/CMakeLists.txt" + ) + ADD_SUBDIRECTORY("${ENTRY}") ENDIF () ENDFOREACH () ENDFUNCTION() diff --git a/CMakeScripts/CompatTimeMonotonic.cmake b/CMakeScripts/CompatTimeMonotonic.cmake --- a/CMakeScripts/CompatTimeMonotonic.cmake +++ b/CMakeScripts/CompatTimeMonotonic.cmake @@ -1,8 +1,6 @@ IF (NOT TIME_MONOTONIC_LIBRARY) SET(COMPAT_TIME_MONOTONIC_IMPL "${LIGHTSD_SOURCE_DIR}/compat/${CMAKE_SYSTEM_NAME}/time_monotonic.c") - SET(COMPAT_TIME_MONOTONIC_H "${LIGHTSD_SOURCE_DIR}/compat/${CMAKE_SYSTEM_NAME}/time_monotonic.h") SET(GENERIC_TIME_MONOTONIC_IMPL "${LIGHTSD_SOURCE_DIR}/compat/generic/time_monotonic.c") - SET(GENERIC_TIME_MONOTONIC_H "${LIGHTSD_SOURCE_DIR}/compat/generic/time_monotonic.h") SET(TIME_MONOTONIC_LIBRARY time_monotonic CACHE INTERNAL "lgtd_time_monotonic implementation") IF (APPLE) @@ -18,6 +16,7 @@ ENDIF () SET(CMAKE_REQUIRED_QUIET TRUE) + MESSAGE(STATUS "Looking for clock_gettime") CHECK_FUNCTION_EXISTS("clock_gettime" HAVE_CLOCK_GETTIME) IF (NOT HAVE_CLOCK_GETTIME) @@ -32,19 +31,17 @@ UNSET(TIME_MONOTONIC_LIBRARY_DEP CACHE) ENDIF () ENDIF () - UNSET(CMAKE_REQUIRED_QUIET) + UNSET(CMAKE_REQUIRED_FLAGS) IF (HAVE_CLOCK_GETTIME) MESSAGE(STATUS "Looking for clock_gettime - found") - FILE(COPY "${GENERIC_TIME_MONOTONIC_H}" DESTINATION "${LIGHTSD_BINARY_DIR}/core/") SET( TIME_MONOTONIC_IMPL ${GENERIC_TIME_MONOTONIC_IMPL} CACHE INTERNAL "lgtd_time_monotonic (POSIX generic source)" ) ELSEIF (EXISTS "${COMPAT_TIME_MONOTONIC_IMPL}") MESSAGE(STATUS "Looking for clock_gettime - not found, using built-in compatibilty file") - FILE(COPY "${COMPAT_TIME_MONOTONIC_H}" DESTINATION "${LIGHTSD_BINARY_DIR}/core/") SET( TIME_MONOTONIC_IMPL "${COMPAT_TIME_MONOTONIC_IMPL}" CACHE INTERNAL "lgtd_time_monotonic (${CMAKE_SYSTEM_NAME} specific source)" @@ -52,9 +49,38 @@ ELSE () MESSAGE(SEND_ERROR "Looking for clock_gettime - not found") ENDIF () + + SET(COMPAT_SLEEP_MONOTONIC_IMPL "${LIGHTSD_SOURCE_DIR}/compat/${CMAKE_SYSTEM_NAME}/sleep_monotonic.c") + SET(GENERIC_SLEEP_MONOTONIC_IMPL "${LIGHTSD_SOURCE_DIR}/compat/generic/sleep_monotonic.c") + + MESSAGE(STATUS "Looking for nanosleep") + CHECK_FUNCTION_EXISTS("nanosleep" HAVE_NANOSLEEP) + IF (HAVE_NANOSLEEP) + MESSAGE(STATUS "Looking for nanosleep - found") + SET( + SLEEP_MONOTONIC_IMPL "${GENERIC_SLEEP_MONOTONIC_IMPL}" + CACHE INTERNAL "lgtd_sleep_monotonic (POSIX generic source)" + ) + ELSEIF (EXISTS "${COMPAT_SLEEP_MONOTONIC_IMPL}") + MESSAGE(STATUS "Looking for nanosleep - not found, using built-in compatibilty file") + SET( + SLEEP_MONOTONIC_IMPL "${COMPAT_SLEEP_MONOTONIC_IMPL}" + CACHE INTERNAL "lgtd_sleep_monotonic (${CMAKE_SYSTEM_NAME} specific source)" + ) + IF (WIN32) + SET(TIME_MONOTONIC_LIBRARY_DEP Winmm CACHE INTERNAL "dependency for lgtd_sleep_monotonic") + ENDIF () + ENDIF () + + UNSET(CMAKE_REQUIRED_QUIET) ENDIF () -ADD_LIBRARY(${TIME_MONOTONIC_LIBRARY} STATIC "${TIME_MONOTONIC_IMPL}") +ADD_LIBRARY( + ${TIME_MONOTONIC_LIBRARY} + STATIC + "${TIME_MONOTONIC_IMPL}" + "${SLEEP_MONOTONIC_IMPL}" +) IF (TIME_MONOTONIC_LIBRARY_DEP) TARGET_LINK_LIBRARIES(${TIME_MONOTONIC_LIBRARY} ${TIME_MONOTONIC_LIBRARY_DEP}) diff --git a/CMakeScripts/FindEndian.cmake b/CMakeScripts/FindEndian.cmake --- a/CMakeScripts/FindEndian.cmake +++ b/CMakeScripts/FindEndian.cmake @@ -12,10 +12,15 @@ IF (HAVE_ENDIAN_H) MESSAGE(STATUS "Looking for endian.h - found") SET(ENDIAN_H_PATH "using native headers" CACHE INTERNAL "endian.h path") - ELSEIF (EXISTS "${COMPAT_ENDIAN_H}") + ELSEIF (EXISTS "${COMPAT_ENDIAN_H}" OR EXISTS "${COMPAT_ENDIAN_H}.in") MESSAGE(STATUS "Looking for endian.h - not found, using built-in compatibility file") - FILE(COPY "${COMPAT_ENDIAN_H}" DESTINATION "${LIGHTSD_BINARY_DIR}/compat/") - SET(ENDIAN_H_PATH "${COMPAT_ENDIAN_H}" CACHE INTERNAL "endian.h path") + IF (EXISTS "${COMPAT_ENDIAN_H}") + FILE(COPY "${COMPAT_ENDIAN_H}" DESTINATION "${LIGHTSD_BINARY_DIR}/compat/") + SET(ENDIAN_H_PATH "${COMPAT_ENDIAN_H}" CACHE INTERNAL "endian.h path") + ELSE () + CONFIGURE_FILE("${COMPAT_ENDIAN_H}.in" "${LIGHTSD_BINARY_DIR}/compat/endian.h") + SET(ENDIAN_H_PATH "${COMPAT_ENDIAN_H}.in" CACHE INTERNAL "endian.h path") + ENDIF () ELSE () MESSAGE(STATUS "Looking for endian.h - not found") ENDIF () diff --git a/CMakeScripts/FindEvent2.cmake b/CMakeScripts/FindEvent2.cmake --- a/CMakeScripts/FindEvent2.cmake +++ b/CMakeScripts/FindEvent2.cmake @@ -1,14 +1,21 @@ FIND_PATH( EVENT2_INCLUDE_DIR event2/event.h - # OpenBSD has libevent1 in /usr/lib, always try /usr/local first: - HINTS /usr/local/ + HINTS + /usr/local/ # OpenBSD has libevent1 in /usr/lib, always try /usr/local first + $ENV{EVENT2_DIR}/include # Windows... ) FOREACH (COMPONENT ${Event2_FIND_COMPONENTS}) STRING(TOUPPER ${COMPONENT} UPPER_COMPONENT) FIND_LIBRARY( - EVENT2_${UPPER_COMPONENT}_LIBRARY event_${COMPONENT} HINTS /usr/local/ + EVENT2_${UPPER_COMPONENT}_LIBRARY + event_${COMPONENT} + NAMES + libevent_${COMPONENT} # Windows + HINTS + /usr/local/ + $ENV{EVENT2_DIR} ) IF (EVENT2_${UPPER_COMPONENT}_LIBRARY) SET(Event2_${COMPONENT}_FOUND TRUE) diff --git a/compat/CMakeLists.txt b/compat/CMakeLists.txt deleted file mode 100644 --- a/compat/CMakeLists.txt +++ /dev/null @@ -1,1 +0,0 @@ -ADD_SUBDIRECTORY(generic) diff --git a/compat/Darwin/time_monotonic.c b/compat/Darwin/time_monotonic.c --- a/compat/Darwin/time_monotonic.c +++ b/compat/Darwin/time_monotonic.c @@ -24,7 +24,7 @@ #include <assert.h> #include <stdint.h> -#include "time_monotonic.h" +#include "core/time_monotonic.h" enum { MSECS_IN_NSEC = 1000000 }; diff --git a/compat/Darwin/time_monotonic.h b/compat/Darwin/time_monotonic.h deleted file mode 100644 --- a/compat/Darwin/time_monotonic.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2015, Louis Opter <kalessin@kalessin.fr> -// -// This file is part of lighstd. -// -// lighstd 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. -// -// lighstd 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 lighstd. If not, see <http://www.gnu.org/licenses/>. - -#pragma once - -typedef uint64_t lgtd_time_mono_t; - -lgtd_time_mono_t lgtd_time_monotonic_msecs(void); diff --git a/compat/Windows/endian.h.in b/compat/Windows/endian.h.in new file mode 100644 --- /dev/null +++ b/compat/Windows/endian.h.in @@ -0,0 +1,35 @@ +#pragma once + +#include <stdlib.h> + +#if @BIG_ENDIAN_SYSTEM@ +# define htobe16(x) (x) +# define htole16(x) _byteswap_ushort(x) +# define be16toh(x) (x) +# define le16toh(x) _byteswap_ushort(x) + +# define htobe32(x) (x) +# define htole32(x) _byteswap_ulong(x) +# define be32toh(x) (x) +# define le32toh(x) _byteswap_ulong(x) + +# define htobe64(x) (x) +# define htole64(x) _byteswap_uint64(x) +# define be64toh(x) (x) +# define le64toh(x) _byteswap_uint64(x) +#else +# define htobe16(x) _byteswap_ushort(x) +# define htole16(x) (x) +# define be16toh(x) _byteswap_ushort(x) +# define le16toh(x) (x) + +# define htobe32(x) _byteswap_ulong(x) +# define htole32(x) (x) +# define be32toh(x) _byteswap_ulong(x) +# define le32toh(x) (x) + +# define htobe64(x) _byteswap_uint64(x) +# define htole64(x) (x) +# define be64toh(x) _byteswap_uint64(x) +# define le64toh(x) (x) +#endif diff --git a/compat/Windows/sleep_monotonic.c b/compat/Windows/sleep_monotonic.c new file mode 100644 --- /dev/null +++ b/compat/Windows/sleep_monotonic.c @@ -0,0 +1,63 @@ +// Copyright (c) 2017, Louis Opter <louis@opter.org> +// +// This file is part of lighstd. +// +// lighstd 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. +// +// lighstd 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 lighstd. If not, see <http://www.gnu.org/licenses/>. + +// See: +// +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx +// https://msdn.microsoft.com/en-us/library/dd743626(v=vs.85).aspx + +#include <Windows.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +#include "core/time_monotonic.h" +#include "core/lightsd.h" + +enum { TIMER_RESOLUTION_MS = 1 }; + +static UINT +_lgtd_set_timer_resolution(UINT resolution_ms) +{ + TIMECAPS tc; + if (timeGetDevCaps(&tc, sizeof(tc)) != TIMERR_NOERROR) { + fprintf(stderr, "lightsd: multimedia timers unavailable."); + exit(1); + } + + UINT resolution = LGTD_MAX(tc.wPeriodMin, resolution_ms); + resolution = LGTD_MIN(resolution, tc.wPeriodMax); + timeBeginPeriod(resolution); + return resolution; +} + +static void +_lgtd_reset_timer_resolution(UINT resolution_ms) +{ + if (timeEndPeriod(resolution_ms) != TIMERR_NOERROR) { + fprintf(stderr, "lightsd: can't reset timer resolution."); + } +} + +void +lgtd_sleep_monotonic_msecs(int msecs) +{ + UINT actual = _lgtd_set_timer_resolution(TIMER_RESOLUTION_MS); + Sleep(msecs); + _lgtd_reset_timer_resolution(actual); +} diff --git a/compat/Windows/time_monotonic.c b/compat/Windows/time_monotonic.c new file mode 100644 --- /dev/null +++ b/compat/Windows/time_monotonic.c @@ -0,0 +1,67 @@ +// Copyright (c) 2017, Louis Opter <louis@opter.org> +// +// This file is part of lighstd. +// +// lighstd 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. +// +// lighstd 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 lighstd. If not, see <http://www.gnu.org/licenses/>. + +// This is pretty much "Using QPC in native code" from: +// +// https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx + +#include <Windows.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#include "core/time_monotonic.h" + +lgtd_time_mono_t +lgtd_time_monotonic_msecs(void) +{ + static LARGE_INTEGER frequency = { .QuadPart = 0 }; // ticks per second + if (frequency.QuadPart == 0 + && QueryPerformanceFrequency(&frequency) == false) { + LPSTR msg = NULL; + DWORD msg_len = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + // By default the message is stored in the buffer pointed by + // lpMsgBuf, but we use FORMAT_MESSAGE_ALLOCATE_BUFFER to have + // the buffer allocated for us. + // So instead you need to give the function a pointer on your + // pointer instead of your buffer and do an ugly cast: + (LPSTR)&msg, + 0, + NULL + ); + if (!msg_len) { + msg = "unknown error"; + } + fprintf(stderr, "lightsd: QPC timer unavailable: %s.\r\n", msg); + exit(1); + } + + LARGE_INTEGER time; + QueryPerformanceCounter(&time); + // Multiply the number of ticks by 1000 first to get a final value in ms: + time.QuadPart *= 1000; + // Then (the order is important to avoid loosing precision) divide by the + // number of ticks per second: + time.QuadPart /= frequency.QuadPart; + return time.QuadPart; +} diff --git a/compat/generic/CMakeLists.txt b/compat/generic/CMakeLists.txt deleted file mode 100644 --- a/compat/generic/CMakeLists.txt +++ /dev/null @@ -1,1 +0,0 @@ -FILE(COPY sys DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/compat/generic/sleep_monotonic.c b/compat/generic/sleep_monotonic.c new file mode 100644 --- /dev/null +++ b/compat/generic/sleep_monotonic.c @@ -0,0 +1,48 @@ +// Copyright (c) 2017, Louis Opter <louis@opter.org> +// +// This file is part of lighstd. +// +// lighstd 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. +// +// lighstd 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 lighstd. If not, see <http://www.gnu.org/licenses/>. + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <time.h> + +#include "core/time_monotonic.h" +#include "core/lightsd.h" + +void +lgtd_sleep_monotonic_msecs(int msecs) +{ + assert(msecs >= 0); + + struct timespec remainder = LGTD_MSECS_TO_TIMESPEC(msecs), + request = { 0, 0 }, + *rmtp = &remainder, + *rqtp = &request; + do { + LGTD_SWAP(struct timespec *, rqtp, rmtp); + int err = nanosleep(rqtp, rmtp); + if (err && errno != EINTR) { + const char *reason = strerror(errno); + fprintf(stderr, "lightsd: nanosleep failed: %s.\n", reason); + abort(); + } + } while (remainder.tv_sec > 0 && remainder.tv_nsec > 0); +} diff --git a/compat/generic/time_monotonic.c b/compat/generic/time_monotonic.c --- a/compat/generic/time_monotonic.c +++ b/compat/generic/time_monotonic.c @@ -18,7 +18,7 @@ #include <stdint.h> #include <time.h> -#include "time_monotonic.h" +#include "core/time_monotonic.h" lgtd_time_mono_t lgtd_time_monotonic_msecs(void) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -2,9 +2,7 @@ # I only have lifx bulbs right now and I don't want to do any premature work. INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/../ ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/core/lightsd.h b/core/lightsd.h --- a/core/lightsd.h +++ b/core/lightsd.h @@ -35,7 +35,7 @@ #pragma once #ifndef __attribute__ -# define __atttribute__(e) +# define __attribute__(e) #endif #define LGTD_ABS(v) ((v) >= 0 ? (v) : (v) * -1) @@ -43,11 +43,16 @@ #define LGTD_MAX(a, b) ((a) > (b) ? (a) : (b)) #define LGTD_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#define LGTD_SWAP(type, a, b) do { type _tmp = a; a = b; b = _tmp; } while (0) #define LGTD_MSECS_TO_TIMEVAL(v) { \ .tv_sec = (v) / 1000, \ .tv_usec = ((v) % 1000) * 1000 \ } +#define LGTD_MSECS_TO_TIMESPEC(v) { \ + .tv_sec = (v) / 1000, \ + .tv_nsec = ((v) % 1000) * 1000000 \ +} #define LGTD_NSECS_TO_USECS(v) ((v) / (unsigned int)1E6) #define LGTD_NSECS_TO_SECS(v) ((v) / (unsigned int)1E9) #define LGTD_SECS_TO_NSECS(v) ((v) * (unsigned int)1E9) diff --git a/compat/generic/time_monotonic.h b/core/time_monotonic.h rename from compat/generic/time_monotonic.h rename to core/time_monotonic.h --- a/compat/generic/time_monotonic.h +++ b/core/time_monotonic.h @@ -20,3 +20,4 @@ typedef uint64_t lgtd_time_mono_t; lgtd_time_mono_t lgtd_time_monotonic_msecs(void); +void lgtd_sleep_monotonic_msecs(int); diff --git a/lifx/CMakeLists.txt b/lifx/CMakeLists.txt --- a/lifx/CMakeLists.txt +++ b/lifx/CMakeLists.txt @@ -1,7 +1,5 @@ INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/../ ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/tests/compat/CMakeLists.txt b/tests/compat/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/tests/compat/CMakeLists.txt @@ -0,0 +1,1 @@ +ADD_ALL_SUBDIRECTORIES() diff --git a/tests/compat/time_monotonic/CMakeLists.txt b/tests/compat/time_monotonic/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/tests/compat/time_monotonic/CMakeLists.txt @@ -0,0 +1,8 @@ +FUNCTION(ADD_TIME_MONOTONIC_TEST TEST_SOURCE) + ADD_TEST_FROM_C_SOURCES(${TEST_SOURCE} ${TIME_MONOTONIC_LIBRARY}) +ENDFUNCTION() + +FILE(GLOB TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "test_*.c") +FOREACH(TEST ${TESTS}) + ADD_TIME_MONOTONIC_TEST(${TEST}) +ENDFOREACH() diff --git a/tests/compat/time_monotonic/test_time_monotonic_msecs.c b/tests/compat/time_monotonic/test_time_monotonic_msecs.c new file mode 100644 --- /dev/null +++ b/tests/compat/time_monotonic/test_time_monotonic_msecs.c @@ -0,0 +1,17 @@ +#include <stdbool.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> + +#include "core/time_monotonic.h" +#include "core/lightsd.h" + +int +main(void) +{ + lgtd_time_mono_t start = lgtd_time_monotonic_msecs(); + lgtd_sleep_monotonic_msecs(50); + int duration = (int)(lgtd_time_monotonic_msecs() - start); + printf("slept for %dms\r\n", duration); + return LGTD_ABS(duration - 50) > 10; +} diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -1,9 +1,7 @@ INCLUDE_DIRECTORIES( - ${LIGHTSD_SOURCE_DIR} ${LIGHTSD_SOURCE_DIR}/core/ ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../lifx - ${LIGHTSD_BINARY_DIR} ${LIGHTSD_BINARY_DIR}/core/ ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/../lifx diff --git a/tests/lifx/CMakeLists.txt b/tests/lifx/CMakeLists.txt --- a/tests/lifx/CMakeLists.txt +++ b/tests/lifx/CMakeLists.txt @@ -1,9 +1,7 @@ INCLUDE_DIRECTORIES( - ${LIGHTSD_SOURCE_DIR} ${LIGHTSD_SOURCE_DIR}/lifx/ ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../core - ${LIGHTSD_BINARY_DIR} ${LIGHTSD_BINARY_DIR}/lifx/ ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/../core