From 549c19b42ed76f51fc0a928b61bd965f5dc99471 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 3 Oct 2018 14:54:33 -0700 Subject: [PATCH] portability macro flags updates, for Haiku some non-trivial changes to platform.h and util.h, initially related to compilation for Haiku, but I used this opportunity to make them cleaner and add some documentation. Noticed several tests that could be improved (too harsh conditions, useless exception, etc.) but I did not dare modifying too many tests just before release. --- programs/platform.h | 58 ++++++++++++++++++++++++++++++++------------- programs/util.h | 39 ++++++++++++++++++------------ 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/programs/platform.h b/programs/platform.h index aa19ee12..b6b3a3be 100644 --- a/programs/platform.h +++ b/programs/platform.h @@ -65,39 +65,52 @@ extern "C" { /* ************************************************************ * Detect POSIX version -* PLATFORM_POSIX_VERSION = -1 for non-Unix e.g. Windows -* PLATFORM_POSIX_VERSION = 0 for Unix-like non-POSIX -* PLATFORM_POSIX_VERSION >= 1 is equal to found _POSIX_VERSION +* PLATFORM_POSIX_VERSION = 0 for non-Unix e.g. Windows +* PLATFORM_POSIX_VERSION = 1 for Unix-like but non-POSIX +* PLATFORM_POSIX_VERSION > 1 is equal to found _POSIX_VERSION +* Value of PLATFORM_POSIX_VERSION can be forced on command line ***************************************************************/ -#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)) /* UNIX-like OS */ \ - || defined(__midipix__) || defined(__VMS) || defined(__HAIKU__)) +#ifndef PLATFORM_POSIX_VERSION + # if (defined(__APPLE__) && defined(__MACH__)) || defined(__SVR4) || defined(_AIX) || defined(__hpux) /* POSIX.1-2001 (SUSv3) conformant */ \ - || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* BSD distros */ \ - || defined(__HAIKU__) + || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) /* BSD distros */ + /* exception rule : force posix version to 200112L, + * note: it's better to use unistd.h's _POSIX_VERSION whenever possible */ # define PLATFORM_POSIX_VERSION 200112L -# else + +/* try to determine posix version through official unistd.h's _POSIX_VERSION (http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html). + * note : there is no simple way to know in advance if is present or not on target system, + * Posix specification mandates its presence and its content, but target system must respect this spec. + * It's necessary to _not_ #include whenever target OS is not unix-like + * otherwise it will block preprocessing stage. + * The following list of build macros tries to "guess" if target OS is likely unix-like, and therefore can #include + */ +# elif !defined(_WIN32) \ + && (defined(__unix__) || defined(__unix) \ + || defined(__midipix__) || defined(__VMS) || defined(__HAIKU__)) + # if defined(__linux__) || defined(__linux) # ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L /* use feature test macro */ +# define _POSIX_C_SOURCE 200112L /* feature test macro : https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html */ # endif # endif # include /* declares _POSIX_VERSION */ # if defined(_POSIX_VERSION) /* POSIX compliant */ # define PLATFORM_POSIX_VERSION _POSIX_VERSION # else -# define PLATFORM_POSIX_VERSION 0 +# define PLATFORM_POSIX_VERSION 1 # endif -# endif -#endif -#if !defined(PLATFORM_POSIX_VERSION) -# define PLATFORM_POSIX_VERSION -1 -#endif +# else /* non-unix target platform (like Windows) */ +# define PLATFORM_POSIX_VERSION 0 +# endif + +#endif /* PLATFORM_POSIX_VERSION */ /*-********************************************* * Detect if isatty() and fileno() are available ************************************************/ -#if (defined(__linux__) && (PLATFORM_POSIX_VERSION >= 1)) \ +#if (defined(__linux__) && (PLATFORM_POSIX_VERSION > 1)) \ || (PLATFORM_POSIX_VERSION >= 200112L) \ || defined(__DJGPP__) \ || defined(__MSYS__) @@ -160,6 +173,19 @@ static __inline int IS_CONSOLE(FILE* stdStream) { #endif +#ifndef ZSTD_SETPRIORITY_SUPPORT + /* mandates presence of and support for setpriority() : http://man7.org/linux/man-pages/man2/setpriority.2.html */ +# define ZSTD_SETPRIORITY_SUPPORT (PLATFORM_POSIX_VERSION >= 200112L) +#endif + + +#ifndef ZSTD_NANOSLEEP_SUPPORT + /* mandates support of nanosleep() within : http://man7.org/linux/man-pages/man2/nanosleep.2.html */ +# define ZSTD_NANOSLEEP_SUPPORT (defined(__linux__) && (PLATFORM_POSIX_VERSION >= 199309L)) \ + || (PLATFORM_POSIX_VERSION >= 200112L) +#endif + + #if defined (__cplusplus) } #endif diff --git a/programs/util.h b/programs/util.h index d6184fac..596f4bbb 100644 --- a/programs/util.h +++ b/programs/util.h @@ -26,7 +26,7 @@ extern "C" { #include /* fprintf */ #include /* strncmp */ #include /* stat, utime */ -#include /* stat */ +#include /* stat, chmod */ #if defined(_MSC_VER) # include /* utime */ # include /* _chmod */ @@ -53,32 +53,34 @@ extern "C" { #endif -/*-**************************************** -* Sleep functions: Windows - Posix - others -******************************************/ +/*-************************************************* +* Sleep & priority functions: Windows - Posix - others +***************************************************/ #if defined(_WIN32) # include # define SET_REALTIME_PRIORITY SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) # define UTIL_sleep(s) Sleep(1000*s) # define UTIL_sleepMilli(milli) Sleep(milli) -#elif PLATFORM_POSIX_VERSION >= 0 /* Unix-like operating system */ -# include -# include /* setpriority */ -# if defined(PRIO_PROCESS) -# define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20) -# else -# define SET_REALTIME_PRIORITY /* disabled */ -# endif + +#elif PLATFORM_POSIX_VERSION > 0 /* Unix-like operating system */ +# include /* sleep */ # define UTIL_sleep(s) sleep(s) -# if (defined(__linux__) && (PLATFORM_POSIX_VERSION >= 199309L)) || (PLATFORM_POSIX_VERSION >= 200112L) /* nanosleep requires POSIX.1-2001 */ +# if ZSTD_NANOSLEEP_SUPPORT # define UTIL_sleepMilli(milli) { struct timespec t; t.tv_sec=0; t.tv_nsec=milli*1000000ULL; nanosleep(&t, NULL); } # else # define UTIL_sleepMilli(milli) /* disabled */ # endif -#else -# define SET_REALTIME_PRIORITY /* disabled */ +# if ZSTD_SETPRIORITY_SUPPORT +# include /* setpriority */ +# define SET_REALTIME_PRIORITY setpriority(PRIO_PROCESS, 0, -20) +# else +# define SET_REALTIME_PRIORITY /* disabled */ +# endif + +#else /* unknown non-unix operating systen */ # define UTIL_sleep(s) /* disabled */ # define UTIL_sleepMilli(milli) /* disabled */ +# define SET_REALTIME_PRIORITY /* disabled */ #endif @@ -119,6 +121,7 @@ static int g_utilDisplayLevel; #if defined(_WIN32) /* Windows */ #define UTIL_TIME_INITIALIZER { { 0, 0 } } typedef LARGE_INTEGER UTIL_time_t; + UTIL_STATIC UTIL_time_t UTIL_getTime(void) { UTIL_time_t x; QueryPerformanceCounter(&x); return x; } UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t clockStart, UTIL_time_t clockEnd) { @@ -148,6 +151,7 @@ static int g_utilDisplayLevel; #include #define UTIL_TIME_INITIALIZER 0 typedef U64 UTIL_time_t; + UTIL_STATIC UTIL_time_t UTIL_getTime(void) { return mach_absolute_time(); } UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t clockStart, UTIL_time_t clockEnd) { @@ -179,6 +183,7 @@ static int g_utilDisplayLevel; #define UTIL_TIME_INITIALIZER { 0, 0 } typedef struct timespec UTIL_freq_t; typedef struct timespec UTIL_time_t; + UTIL_STATIC UTIL_time_t UTIL_getTime(void) { UTIL_time_t time; @@ -186,6 +191,7 @@ static int g_utilDisplayLevel; UTIL_DISPLAYLEVEL(1, "ERROR: Failed to get time\n"); /* we could also exit() */ return time; } + UTIL_STATIC UTIL_time_t UTIL_getSpanTime(UTIL_time_t begin, UTIL_time_t end) { UTIL_time_t diff; @@ -198,6 +204,7 @@ static int g_utilDisplayLevel; } return diff; } + UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_time_t begin, UTIL_time_t end) { UTIL_time_t const diff = UTIL_getSpanTime(begin, end); @@ -206,6 +213,7 @@ static int g_utilDisplayLevel; micro += diff.tv_nsec / 1000ULL; return micro; } + UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_time_t begin, UTIL_time_t end) { UTIL_time_t const diff = UTIL_getSpanTime(begin, end); @@ -214,6 +222,7 @@ static int g_utilDisplayLevel; nano += diff.tv_nsec; return nano; } + #else /* relies on standard C (note : clock_t measurements can be wrong when using multi-threading) */ typedef clock_t UTIL_time_t; #define UTIL_TIME_INITIALIZER 0