summaryrefslogtreecommitdiff
path: root/src/pal/src/configure.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/src/configure.cmake')
-rw-r--r--src/pal/src/configure.cmake1281
1 files changed, 1281 insertions, 0 deletions
diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake
new file mode 100644
index 0000000000..cc38bc8541
--- /dev/null
+++ b/src/pal/src/configure.cmake
@@ -0,0 +1,1281 @@
+include(CheckCXXSourceCompiles)
+include(CheckCXXSourceRuns)
+include(CheckCXXSymbolExists)
+include(CheckFunctionExists)
+include(CheckIncludeFiles)
+include(CheckStructHasMember)
+include(CheckTypeSize)
+include(CheckLibraryExists)
+
+if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ set(CMAKE_REQUIRED_INCLUDES /usr/local/include)
+elseif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
+ set(CMAKE_REQUIRED_INCLUDES /opt/local/include)
+endif()
+if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin AND NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ set(CMAKE_REQUIRED_DEFINITIONS "-D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L")
+endif()
+
+list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64)
+
+check_include_files(ieeefp.h HAVE_IEEEFP_H)
+check_include_files(sys/vmparam.h HAVE_SYS_VMPARAM_H)
+check_include_files(mach/vm_types.h HAVE_MACH_VM_TYPES_H)
+check_include_files(mach/vm_param.h HAVE_MACH_VM_PARAM_H)
+check_include_files("sys/param.h;sys/types.h;machine/npx.h" HAVE_MACHINE_NPX_H)
+check_include_files("sys/param.h;sys/cdefs.h;machine/reg.h" HAVE_MACHINE_REG_H)
+check_include_files(machine/vmparam.h HAVE_MACHINE_VMPARAM_H)
+check_include_files(procfs.h HAVE_PROCFS_H)
+check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H)
+check_include_files(sys/time.h HAVE_SYS_TIME_H)
+check_include_files(pthread_np.h HAVE_PTHREAD_NP_H)
+check_include_files(sys/lwp.h HAVE_SYS_LWP_H)
+check_include_files(lwp.h HAVE_LWP_H)
+check_include_files(libunwind.h HAVE_LIBUNWIND_H)
+check_include_files(runetype.h HAVE_RUNETYPE_H)
+check_include_files(lttng/tracepoint.h HAVE_LTTNG_TRACEPOINT_H)
+check_include_files(uuid/uuid.h HAVE_LIBUUID_H)
+check_include_files(sys/sysctl.h HAVE_SYS_SYSCTL_H)
+check_include_files(gnu/lib-names.h HAVE_GNU_LIBNAMES_H)
+
+check_function_exists(kqueue HAVE_KQUEUE)
+check_function_exists(getpwuid_r HAVE_GETPWUID_R)
+check_library_exists(pthread pthread_suspend "" HAVE_PTHREAD_SUSPEND)
+check_library_exists(pthread pthread_suspend_np "" HAVE_PTHREAD_SUSPEND_NP)
+check_library_exists(pthread pthread_continue "" HAVE_PTHREAD_CONTINUE)
+check_library_exists(pthread pthread_continue_np "" HAVE_PTHREAD_CONTINUE_NP)
+check_library_exists(pthread pthread_resume_np "" HAVE_PTHREAD_RESUME_NP)
+check_library_exists(pthread pthread_attr_get_np "" HAVE_PTHREAD_ATTR_GET_NP)
+check_library_exists(pthread pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP)
+check_library_exists(pthread pthread_getcpuclockid "" HAVE_PTHREAD_GETCPUCLOCKID)
+check_library_exists(pthread pthread_sigqueue "" HAVE_PTHREAD_SIGQUEUE)
+check_function_exists(sigreturn HAVE_SIGRETURN)
+check_function_exists(_thread_sys_sigreturn HAVE__THREAD_SYS_SIGRETURN)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_function_exists(copysign HAVE_COPYSIGN)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_function_exists(fsync HAVE_FSYNC)
+check_function_exists(futimes HAVE_FUTIMES)
+check_function_exists(utimes HAVE_UTIMES)
+check_function_exists(sysctl HAVE_SYSCTL)
+check_function_exists(sysconf HAVE_SYSCONF)
+check_function_exists(localtime_r HAVE_LOCALTIME_R)
+check_function_exists(gmtime_r HAVE_GMTIME_R)
+check_function_exists(timegm HAVE_TIMEGM)
+check_function_exists(_snwprintf HAVE__SNWPRINTF)
+check_function_exists(poll HAVE_POLL)
+check_function_exists(statvfs HAVE_STATVFS)
+check_function_exists(thread_self HAVE_THREAD_SELF)
+check_function_exists(_lwp_self HAVE__LWP_SELF)
+check_function_exists(pthread_mach_thread_np HAVE_MACH_THREADS)
+check_function_exists(thread_set_exception_ports HAVE_MACH_EXCEPTIONS)
+check_function_exists(vm_allocate HAVE_VM_ALLOCATE)
+check_function_exists(vm_read HAVE_VM_READ)
+check_function_exists(directio HAVE_DIRECTIO)
+check_function_exists(semget HAS_SYSV_SEMAPHORES)
+check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES)
+check_function_exists(ttrace HAVE_TTRACE)
+set(CMAKE_REQUIRED_LIBRARIES unwind unwind-generic)
+check_cxx_source_compiles("
+#include <libunwind.h>
+
+int main(int argc, char **argv) {
+ unw_cursor_t cursor;
+ unw_save_loc_t saveLoc;
+ int reg = UNW_REG_IP;
+ unw_get_save_loc(&cursor, reg, &saveLoc);
+
+ return 0;
+}" HAVE_UNW_GET_SAVE_LOC)
+check_cxx_source_compiles("
+#include <libunwind.h>
+
+int main(int argc, char **argv) {
+ unw_addr_space_t as;
+ unw_get_accessors(as);
+
+ return 0;
+}" HAVE_UNW_GET_ACCESSORS)
+set(CMAKE_REQUIRED_LIBRARIES)
+
+check_struct_has_member ("struct stat" st_atimespec "sys/types.h;sys/stat.h" HAVE_STAT_TIMESPEC)
+check_struct_has_member ("struct stat" st_atimensec "sys/types.h;sys/stat.h" HAVE_STAT_NSEC)
+check_struct_has_member ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
+check_struct_has_member ("ucontext_t" uc_mcontext.gregs[0] ucontext.h HAVE_GREGSET_T)
+check_struct_has_member ("ucontext_t" uc_mcontext.__gregs[0] ucontext.h HAVE___GREGSET_T)
+
+set(CMAKE_EXTRA_INCLUDE_FILES machine/reg.h)
+check_type_size("struct reg" BSD_REGS_T)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+set(CMAKE_EXTRA_INCLUDE_FILES asm/ptrace.h)
+check_type_size("struct pt_regs" PT_REGS)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+set(CMAKE_EXTRA_INCLUDE_FILES signal.h)
+check_type_size(siginfo_t SIGINFO_T)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+set(CMAKE_EXTRA_INCLUDE_FILES ucontext.h)
+check_type_size(ucontext_t UCONTEXT_T)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+set(CMAKE_EXTRA_INCLUDE_FILES pthread.h)
+check_type_size(pthread_rwlock_t PTHREAD_RWLOCK_T)
+set(CMAKE_EXTRA_INCLUDE_FILES)
+set(CMAKE_EXTRA_INCLUDE_FILE procfs.h)
+check_type_size(prwatch_t PRWATCH_T)
+set(CMAKE_EXTRA_INCLUDE_FILE)
+check_type_size(off_t SIZEOF_OFF_T)
+
+check_cxx_symbol_exists(SYS_yield sys/syscall.h HAVE_YIELD_SYSCALL)
+check_cxx_symbol_exists(INFTIM poll.h HAVE_INFTIM)
+check_cxx_symbol_exists(CHAR_BIT limits.h HAVE_CHAR_BIT)
+check_cxx_symbol_exists(_DEBUG sys/user.h USER_H_DEFINES_DEBUG)
+check_cxx_symbol_exists(_SC_PHYS_PAGES unistd.h HAVE__SC_PHYS_PAGES)
+check_cxx_symbol_exists(_SC_AVPHYS_PAGES unistd.h HAVE__SC_AVPHYS_PAGES)
+
+check_cxx_source_runs("
+#include <uuid.h>
+
+int main(void) {
+ uuid_t uuid;
+ uint32_t status;
+ uuid_create(&uuid, &status);
+ return 0;
+}" HAVE_BSD_UUID_H)
+
+check_cxx_source_runs("
+#include <sys/param.h>
+#include <stdlib.h>
+
+int main(void) {
+ char *path;
+#ifdef PATH_MAX
+ char resolvedPath[PATH_MAX];
+#elif defined(MAXPATHLEN)
+ char resolvedPath[MAXPATHLEN];
+#else
+ char resolvedPath[1024];
+#endif
+ path = realpath(\"a_nonexistent_file\", resolvedPath);
+ if (path == NULL) {
+ exit(1);
+ }
+ exit(0);
+}" REALPATH_SUPPORTS_NONEXISTENT_FILES)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+int main(void)
+{
+ long long n = 0;
+ sscanf(\"5000000000\", \"%qu\", &n);
+ exit (n != 5000000000);
+ }" SSCANF_SUPPORT_ll)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+
+int main()
+{
+ int ret;
+ float f = 0;
+ char * strin = \"12.34e\";
+
+ ret = sscanf (strin, \"%e\", &f);
+ if (ret <= 0)
+ exit (0);
+ exit(1);
+}" SSCANF_CANNOT_HANDLE_MISSING_EXPONENT)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void) {
+ char buf[256] = { 0 };
+ snprintf(buf, 0x7fffffff, \"%#x\", 0x12345678);
+ if (buf[0] == 0x0) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_LARGE_SNPRINTF_SUPPORT)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd, numFDs;
+ fd_set readFDs, writeFDs, exceptFDs;
+ struct timeval time = { 0 };
+ char * filename = NULL;
+
+ filename = (char *)malloc(L_tmpnam * sizeof(char)); /* ok to leak this at exit */
+ if (NULL == filename) {
+ exit(0);
+ }
+
+ /* On some platforms (e.g. HP-UX) the multithreading c-runtime does not
+ support the tmpnam(NULL) semantics, and it returns NULL. Therefore
+ we need to use the tmpnam(pbuffer) version.
+ */
+ if (NULL == tmpnam(filename)) {
+ exit(0);
+ }
+ if (mkfifo(filename, S_IRWXU) != 0) {
+ if (unlink(filename) != 0) {
+ exit(0);
+ }
+ if (mkfifo(filename, S_IRWXU) != 0) {
+ exit(0);
+ }
+ }
+ fd = open(filename, O_RDWR | O_NONBLOCK);
+ if (fd == -1) {
+ exit(0);
+ }
+
+ FD_ZERO(&readFDs);
+ FD_ZERO(&writeFDs);
+ FD_ZERO(&exceptFDs);
+ FD_SET(fd, &readFDs);
+ numFDs = select(fd + 1, &readFDs, &writeFDs, &exceptFDs, &time);
+
+ close(fd);
+ unlink(filename);
+
+ /* numFDs is zero if select() works correctly */
+ exit(numFD==0);
+}" HAVE_BROKEN_FIFO_SELECT)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+int main(void)
+{
+ int ikq;
+ int iRet;
+ int fd;
+ struct kevent ke, keChangeList;
+ struct timespec ts = { 0, 0 };
+
+ char * filename = NULL;
+
+ filename = (char *)malloc(L_tmpnam * sizeof(char)); /* ok to leak this at exit */
+ if (NULL == filename)
+ {
+ exit(1);
+ }
+
+ /* On some platforms (e.g. HP-UX) the multithreading c-runtime does not
+ support the tmpnam(NULL) semantics, and it returns NULL. Therefore
+ we need to use the tmpnam(pbuffer) version.
+ */
+ if (NULL == tmpnam(filename)) {
+ exit(0);
+ }
+ if (mkfifo(filename, S_IRWXU) != 0) {
+ if (unlink(filename) != 0) {
+ exit(0);
+ }
+ if (mkfifo(filename, S_IRWXU) != 0) {
+ exit(0);
+ }
+ }
+ fd = open(filename, O_RDWR | O_NONBLOCK);
+ if (fd == -1) {
+ exit(0);
+ }
+
+ EV_SET(&keChangeList, fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL);
+ ikq = kqueue();
+ iRet = kevent(ikq, &keChangeList, 1, &ke, 1, &ts);
+
+ close(fd);
+ unlink(filename);
+
+ /* iRet is zero is kevent() works correctly */
+ return(iRet==0);
+}" HAVE_BROKEN_FIFO_KEVENT)
+set(CMAKE_REQUIRED_LIBRARIES pthread)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sched.h>
+
+int main(void)
+{
+ int policy;
+ struct sched_param schedParam;
+ int max_priority;
+ int min_priority;
+
+ if (0 != pthread_getschedparam(pthread_self(), &policy, &schedParam))
+ {
+ exit(1);
+ }
+
+ max_priority = sched_get_priority_max(policy);
+ min_priority = sched_get_priority_min(policy);
+
+ exit(-1 == max_priority || -1 == min_priority);
+}" HAVE_SCHED_GET_PRIORITY)
+set(CMAKE_REQUIRED_LIBRARIES pthread)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <sched.h>
+
+int main(void)
+{
+ if (sched_getcpu() >= 0)
+ {
+ exit(0);
+ }
+ exit(1);
+}" HAVE_SCHED_GETCPU)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+int main()
+{
+ int ret;
+ struct timeval tv;
+ ret = gettimeofday(&tv, NULL);
+
+ exit(ret);
+}" HAVE_WORKING_GETTIMEOFDAY)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+int main()
+{
+ int ret;
+ struct timespec ts;
+ ret = clock_gettime(CLOCK_REALTIME, &ts);
+
+ exit(ret);
+}" HAVE_WORKING_CLOCK_GETTIME)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+int main()
+{
+ int ret;
+ struct timespec ts;
+ ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ exit(ret);
+}" HAVE_CLOCK_MONOTONIC)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+int main()
+{
+ int ret;
+ struct timespec ts;
+ ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+
+ exit(ret);
+}" HAVE_CLOCK_MONOTONIC_COARSE)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <mach/mach_time.h>
+
+int main()
+{
+ int ret;
+ mach_timebase_info_data_t timebaseInfo;
+ ret = mach_timebase_info(&timebaseInfo);
+ mach_absolute_time();
+ exit(ret);
+}" HAVE_MACH_ABSOLUTE_TIME)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+int main()
+{
+ int ret;
+ struct timespec ts;
+ ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
+
+ exit(ret);
+}" HAVE_CLOCK_THREAD_CPUTIME)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+int main(void) {
+ int devzero;
+ void *retval;
+
+ devzero = open(\"/dev/zero\", O_RDWR);
+ if (-1 == devzero) {
+ exit(1);
+ }
+ retval = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, devzero, 0);
+ if (retval == (void *)-1) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_MMAP_DEV_ZERO)
+check_cxx_source_runs("
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifndef MAP_ANON
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+
+void *handle_signal(int signal) {
+ /* If we reach this, we've crashed due to mmap honoring
+ PROT_NONE. */
+ _exit(1);
+}
+
+int main(void) {
+ int *ptr;
+ struct sigaction action;
+
+ ptr = (int *) mmap(NULL, getpagesize(), PROT_NONE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (ptr == (int *) MAP_FAILED) {
+ exit(0);
+ }
+ action.sa_handler = &handle_signal;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ if (sigaction(SIGBUS, &action, NULL) != 0) {
+ exit(0);
+ }
+ if (sigaction(SIGSEGV, &action, NULL) != 0) {
+ exit(0);
+ }
+ /* This will drop us into the signal handler if PROT_NONE
+ is honored. */
+ *ptr = 123;
+ exit(0);
+}" MMAP_ANON_IGNORES_PROTECTION)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#define MEM_SIZE 1024
+
+int main(void)
+{
+ char * fname;
+ int fd;
+ int ret;
+ void * pAddr0, * pAddr1;
+
+ fname = (char *)malloc(MEM_SIZE);
+ if (!fname)
+ exit(1);
+ strcpy(fname, \"/tmp/name/multiplemaptestXXXXXX\");
+
+ fd = mkstemp(fname);
+ if (fd < 0)
+ exit(1);
+
+ ret = write (fd, (void *)fname, MEM_SIZE);
+ if (ret < 0)
+ exit(1);
+
+ pAddr0 = mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ pAddr1 = mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+ /* In theory we should look for (pAddr1 == MAP_FAILED) && (pAddr1 != MAP_FAILED)
+ but in case the first test also failed, i.e. we failed to run the test,
+ let's assume that the system might not allow multiple shared mapping of the
+ same file region in the same process. The code enabled in this case is
+ only a fall-back code path. In case the double mmap actually works, virtually
+ nothing will change and the normal code path will be executed */
+ if (pAddr1 == MAP_FAILED)
+ ret = 1;
+ else
+ ret = 0;
+
+ if (pAddr0)
+ munmap (pAddr0, MEM_SIZE);
+ if (pAddr1)
+ munmap (pAddr1, MEM_SIZE);
+ close(fd);
+ unlink(fname);
+ free(fname);
+
+ exit(ret != 1);
+}" ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS)
+set(CMAKE_REQUIRED_LIBRARIES pthread)
+check_cxx_source_runs("
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+void *start_routine(void *param) { return NULL; }
+
+int main() {
+ int result;
+ pthread_t tid;
+
+ errno = 0;
+ result = pthread_create(&tid, NULL, start_routine, NULL);
+ if (result != 0) {
+ exit(1);
+ }
+ if (errno != 0) {
+ exit(0);
+ }
+ exit(1);
+}" PTHREAD_CREATE_MODIFIES_ERRNO)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES pthread)
+check_cxx_source_runs("
+#include <errno.h>
+#include <semaphore.h>
+#include <stdlib.h>
+
+int main() {
+ int result;
+ sem_t sema;
+
+ errno = 50;
+ result = sem_init(&sema, 0, 0);
+ if (result != 0)
+ {
+ exit(1);
+ }
+ if (errno != 50)
+ {
+ exit(0);
+ }
+ exit(1);
+}" SEM_INIT_MODIFIES_ERRNO)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd;
+#ifdef PATH_MAX
+ char path[PATH_MAX];
+#elif defined(MAXPATHLEN)
+ char path[MAXPATHLEN];
+#else
+ char path[1024];
+#endif
+
+ sprintf(path, \"/proc/%u/ctl\", getpid());
+ fd = open(path, O_WRONLY);
+ if (fd == -1) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_PROCFS_CTL)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd;
+#ifdef PATH_MAX
+ char path[PATH_MAX];
+#elif defined(MAXPATHLEN)
+ char path[MAXPATHLEN];
+#else
+ char path[1024];
+#endif
+
+ sprintf(path, \"/proc/%u/maps\", getpid());
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_PROCFS_MAPS)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd;
+#ifdef PATH_MAX
+ char path[PATH_MAX];
+#elif defined(MAXPATHLEN)
+ char path[MAXPATHLEN];
+#else
+ char path[1024];
+#endif
+
+ sprintf(path, \"/proc/%u/stat\", getpid());
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_PROCFS_STAT)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void) {
+ int fd;
+#ifdef PATH_MAX
+ char path[PATH_MAX];
+#elif defined(MAXPATHLEN)
+ char path[MAXPATHLEN];
+#else
+ char path[1024];
+#endif
+
+ sprintf(path, \"/proc/%u/status\", getpid());
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_PROCFS_STATUS)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ if (!isnan(acos(10))) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_COMPATIBLE_ACOS)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ if (!isnan(asin(10))) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_COMPATIBLE_ASIN)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ double infinity = 1.0 / 0.0;
+ if (pow(1.0, infinity) != 1.0 || pow(1.0, -infinity) != 1.0) {
+ exit(1)
+ }
+ if (!isnan(pow(-1.0, infinity)) || !isnan(pow(-1.0, -infinity))) {
+ exit(1);
+ }
+ if (pow(0.0, infinity) != 0.0) {
+ exit(1);
+ }
+ if (pow(0.0, -infinity) != infinity) {
+ exit(1);
+ }
+ if (pow(-1.1, infinity) != infinity || pow(1.1, infinity) != infinity) {
+ exit(1);
+ }
+ if (pow(-1.1, -infinity) != 0.0 || pow(1.1, infinity) != 0.0) {
+ exit(1);
+ }
+ if (pow(-0.0, -1) != -infinity) {
+ exit(1);
+ }
+ if (pow(0.0, -1) != infinity) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_COMPATIBLE_POW)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+ double result;
+
+ result = pow(-3.2e-10, -5e14 + 1);
+ if (result != -1.0 / 0.0) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_VALID_NEGATIVE_INF_POW)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+ double result;
+
+ result = pow(-3.5, 3e100);
+ if (result != 1.0 / 0.0) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_VALID_POSITIVE_INF_POW)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ double pi = 3.14159265358979323846;
+ double result;
+
+ result = atan2(0.0, -0.0);
+ if (fabs(pi - result) > 0.0000001) {
+ exit(1);
+ }
+
+ result = atan2(-0.0, -0.0);
+ if (fabs(-pi - result) > 0.0000001) {
+ exit(1);
+ }
+
+ result = atan2 (-0.0, 0.0);
+ if (result != 0.0 || copysign (1.0, result) > 0) {
+ exit(1);
+ }
+
+ result = atan2 (0.0, 0.0);
+ if (result != 0.0 || copysign (1.0, result) < 0) {
+ exit(1);
+ }
+
+ exit (0);
+}" HAVE_COMPATIBLE_ATAN2)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ double d = exp(1.0), e = M_E;
+
+ /* Used memcmp rather than == to test that the doubles are equal to
+ prevent gcc's optimizer from using its 80 bit internal long
+ doubles. If you use ==, then on BSD you get a false negative since
+ exp(1.0) == M_E to 64 bits, but not 80.
+ */
+
+ if (memcmp (&d, &e, sizeof (double)) == 0) {
+ exit(0);
+ }
+ exit(1);
+}" HAVE_COMPATIBLE_EXP)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ if (!isnan(log(-10000))) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_COMPATIBLE_LOG)
+set(CMAKE_REQUIRED_LIBRARIES)
+set(CMAKE_REQUIRED_LIBRARIES m)
+check_cxx_source_runs("
+#include <math.h>
+#include <stdlib.h>
+
+int main(void) {
+ if (!isnan(log10(-10000))) {
+ exit(1);
+ }
+ exit(0);
+}" HAVE_COMPATIBLE_LOG10)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(void)
+{
+ char* szFileName;
+ FILE* pFile = NULL;
+ int ret = 1;
+
+ szFileName = tempnam(\".\", \"tmp\");
+
+ /* open the file write-only */
+ pFile = fopen(szFileName, \"a\");
+ if (pFile == NULL)
+ {
+ exit(0);
+ }
+ if (ungetc('A', pFile) != EOF)
+ {
+ ret = 0;
+ }
+ unlink(szFileName);
+ exit(ret);
+}" UNGETC_NOT_RETURN_EOF)
+set(CMAKE_REQUIRED_LIBRARIES pthread)
+check_cxx_source_runs("
+#include <stdlib.h>
+#include <errno.h>
+#include <semaphore.h>
+
+int main() {
+ sem_t sema;
+ if (sem_init(&sema, 0, 0) == -1){
+ exit(1);
+ }
+ exit(0);
+}" HAS_POSIX_SEMAPHORES)
+set(CMAKE_REQUIRED_LIBRARIES)
+check_cxx_source_runs("
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int main(void)
+{
+ struct passwd sPasswd;
+ struct passwd *pPasswd;
+ char buf[1];
+ int bufLen = sizeof(buf)/sizeof(buf[0]);
+ int euid = geteuid();
+ int ret = 0;
+
+ errno = 0; // clear errno
+ ret = getpwuid_r(euid, &sPasswd, buf, bufLen, &pPasswd);
+ if (0 != ret)
+ {
+ if (ERANGE == errno)
+ {
+ return 0;
+ }
+ }
+
+ return 1; // assume errno is NOT set for all other cases
+}" GETPWUID_R_SETS_ERRNO)
+check_cxx_source_runs("
+#include <stdio.h>
+#include <stdlib.h>
+
+int main()
+{
+ FILE *fp = NULL;
+ char *fileName = \"/dev/zero\";
+ char buf[10];
+
+ /*
+ * Open the file in append mode and try to read some text.
+ * And, make sure ferror() is set.
+ */
+ fp = fopen (fileName, \"a\");
+ if ( (NULL == fp) ||
+ (fread (buf, sizeof(buf), 1, fp) > 0) ||
+ (!ferror(fp))
+ )
+ {
+ return 0;
+ }
+
+ /*
+ * Now that ferror() is set, try to close the file.
+ * If we get an error, we can conclude that this
+ * fgets() depended on the previous ferror().
+ */
+ if ( fclose(fp) != 0 )
+ {
+ return 0;
+ }
+
+ return 1;
+}" FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL)
+set(CMAKE_REQUIRED_DEFINITIONS)
+
+set(SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING 1)
+set(ERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS 1)
+
+check_cxx_source_compiles("
+#include <libunwind.h>
+#include <ucontext.h>
+
+int main(int argc, char **argv)
+{
+ unw_context_t libUnwindContext;
+ ucontext_t uContext;
+
+ libUnwindContext = uContext;
+ return 0;
+}" UNWIND_CONTEXT_IS_UCONTEXT_T)
+
+set(CMAKE_REQUIRED_LIBRARIES pthread)
+check_cxx_source_compiles("
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+int main()
+{
+ pthread_mutexattr_t mutexAttributes;
+ pthread_mutexattr_init(&mutexAttributes);
+ pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED);
+ pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutexattr_setrobust(&mutexAttributes, PTHREAD_MUTEX_ROBUST);
+
+ pthread_mutex_t mutex;
+ pthread_mutex_init(&mutex, &mutexAttributes);
+
+ pthread_mutexattr_destroy(&mutexAttributes);
+
+ struct timespec timeoutTime;
+ timeoutTime.tv_sec = 1; // not the right way to specify absolute time, but just checking availability of timed lock
+ timeoutTime.tv_nsec = 0;
+ pthread_mutex_timedlock(&mutex, &timeoutTime);
+ pthread_mutex_consistent(&mutex);
+
+ pthread_mutex_destroy(&mutex);
+
+ int error = EOWNERDEAD;
+ error = ENOTRECOVERABLE;
+ error = ETIMEDOUT;
+ error = 0;
+ return error;
+}" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
+set(CMAKE_REQUIRED_LIBRARIES)
+
+if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM AND NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
+ set(CMAKE_REQUIRED_LIBRARIES pthread)
+ check_cxx_source_runs("
+ // This test case verifies the pthread process-shared robust mutex's cross-process abandon detection. The parent process starts
+ // a child process that locks the mutex, the process process then waits to acquire the lock, and the child process abandons the
+ // mutex by exiting the process while holding the lock. The parent process should then be released from its wait, be assigned
+ // ownership of the lock, and be notified that the mutex was abandoned.
+
+ #include <sys/mman.h>
+ #include <sys/time.h>
+
+ #include <errno.h>
+ #include <pthread.h>
+ #include <stdio.h>
+ #include <unistd.h>
+
+ #include <new>
+ using namespace std;
+
+ struct Shm
+ {
+ pthread_mutex_t syncMutex;
+ pthread_cond_t syncCondition;
+ pthread_mutex_t robustMutex;
+ int conditionValue;
+
+ Shm() : conditionValue(0)
+ {
+ }
+ } *shm;
+
+ int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
+ {
+ int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
+ if (getTimeResult != 0)
+ {
+ struct timeval tv;
+ getTimeResult = gettimeofday(&tv, NULL);
+ if (getTimeResult != 0)
+ return 1;
+ timeoutTimeRef->tv_sec = tv.tv_sec;
+ timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
+ }
+ timeoutTimeRef->tv_sec += 30;
+ return 0;
+ }
+
+ int WaitForConditionValue(int desiredConditionValue)
+ {
+ struct timespec timeoutTime;
+ if (GetFailTimeoutTime(&timeoutTime) != 0)
+ return 1;
+ if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
+ return 1;
+
+ if (shm->conditionValue != desiredConditionValue)
+ {
+ if (GetFailTimeoutTime(&timeoutTime) != 0)
+ return 1;
+ if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
+ return 1;
+ if (shm->conditionValue != desiredConditionValue)
+ return 1;
+ }
+
+ if (pthread_mutex_unlock(&shm->syncMutex) != 0)
+ return 1;
+ return 0;
+ }
+
+ int SetConditionValue(int newConditionValue)
+ {
+ struct timespec timeoutTime;
+ if (GetFailTimeoutTime(&timeoutTime) != 0)
+ return 1;
+ if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
+ return 1;
+
+ shm->conditionValue = newConditionValue;
+ if (pthread_cond_signal(&shm->syncCondition) != 0)
+ return 1;
+
+ if (pthread_mutex_unlock(&shm->syncMutex) != 0)
+ return 1;
+ return 0;
+ }
+
+ void DoTest_Child();
+
+ int DoTest()
+ {
+ // Map some shared memory
+ void *shmBuffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+ if (shmBuffer == MAP_FAILED)
+ return 1;
+ shm = new(shmBuffer) Shm;
+
+ // Create sync mutex
+ pthread_mutexattr_t syncMutexAttributes;
+ if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
+ return 1;
+ if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
+ return 1;
+ if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
+ return 1;
+ if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
+ return 1;
+
+ // Create sync condition
+ pthread_condattr_t syncConditionAttributes;
+ if (pthread_condattr_init(&syncConditionAttributes) != 0)
+ return 1;
+ if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
+ return 1;
+ if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
+ return 1;
+ if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
+ return 1;
+
+ // Create the robust mutex that will be tested
+ pthread_mutexattr_t robustMutexAttributes;
+ if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
+ return 1;
+ if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
+ return 1;
+ if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
+ return 1;
+ if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
+ return 1;
+ if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
+ return 1;
+
+ // Start child test process
+ int error = fork();
+ if (error == -1)
+ return 1;
+ if (error == 0)
+ {
+ DoTest_Child();
+ return -1;
+ }
+
+ // Wait for child to take a lock
+ WaitForConditionValue(1);
+
+ // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
+ struct timespec timeoutTime;
+ if (GetFailTimeoutTime(&timeoutTime) != 0)
+ return 1;
+ error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
+ if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
+ return 1;
+ if (pthread_mutex_consistent(&shm->robustMutex) != 0)
+ return 1;
+
+ if (pthread_mutex_unlock(&shm->robustMutex) != 0)
+ return 1;
+ if (pthread_mutex_destroy(&shm->robustMutex) != 0)
+ return 1;
+ return 0;
+ }
+
+ void DoTest_Child()
+ {
+ // Lock the robust mutex
+ struct timespec timeoutTime;
+ if (GetFailTimeoutTime(&timeoutTime) != 0)
+ return;
+ if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
+ return;
+
+ // Notify parent that robust mutex is locked
+ if (SetConditionValue(1) != 0)
+ return;
+
+ // Wait a short period to let the parent block on waiting for a lock
+ sleep(1);
+
+ // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
+ }
+
+ int main()
+ {
+ int result = DoTest();
+ return result >= 0 ? result : 0;
+ }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
+ set(CMAKE_REQUIRED_LIBRARIES)
+endif()
+
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ if(NOT HAVE_LIBUUID_H)
+ unset(HAVE_LIBUUID_H CACHE)
+ message(FATAL_ERROR "Cannot find libuuid. Try installing uuid-dev or the appropriate packages for your platform")
+ endif()
+ set(HAVE_COREFOUNDATION 1)
+ set(HAVE__NSGETENVIRON 1)
+ set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 1)
+ set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
+ set(PAL_PT_ATTACH PT_ATTACH)
+ set(PAL_PT_DETACH PT_DETACH)
+ set(PAL_PT_READ_D PT_READ_D)
+ set(PAL_PT_WRITE_D PT_WRITE_D)
+ set(HAS_FTRUNCATE_LENGTH_ISSUE 1)
+ set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ if(NOT HAVE_LIBUNWIND_H)
+ unset(HAVE_LIBUNWIND_H CACHE)
+ message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8 and libunwind8-dev (or the appropriate packages for your platform)")
+ endif()
+ if(NOT HAVE_BSD_UUID_H)
+ unset(HAVE_BSD_UUID_H CACHE)
+ message(FATAL_ERROR "Cannot find uuid.h")
+ endif()
+ set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
+ set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
+ set(PAL_PT_ATTACH PT_ATTACH)
+ set(PAL_PT_DETACH PT_DETACH)
+ set(PAL_PT_READ_D PT_READ_D)
+ set(PAL_PT_WRITE_D PT_WRITE_D)
+ set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
+ set(BSD_REGS_STYLE "((reg).r_##rr)")
+ set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
+elseif(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ if(NOT HAVE_LIBUNWIND_H)
+ unset(HAVE_LIBUNWIND_H CACHE)
+ message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8 and libunwind8-dev (or the appropriate packages for your platform)")
+ endif()
+ if(NOT HAVE_BSD_UUID_H)
+ unset(HAVE_BSD_UUID_H CACHE)
+ message(FATAL_ERROR "Cannot find uuid.h")
+ endif()
+ set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
+ set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
+ set(PAL_PT_ATTACH PT_ATTACH)
+ set(PAL_PT_DETACH PT_DETACH)
+ set(PAL_PT_READ_D PT_READ_D)
+ set(PAL_PT_WRITE_D PT_WRITE_D)
+ set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
+ set(BSD_REGS_STYLE "((reg).regs[_REG_##RR])")
+ set(HAVE_SCHED_OTHER_ASSIGNABLE 0)
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
+ if(NOT HAVE_LIBUNWIND_H)
+ unset(HAVE_LIBUNWIND_H CACHE)
+ message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8 and libunwind8-dev (or the appropriate packages for your platform)")
+ endif()
+ if(NOT HAVE_LIBUUID_H)
+ unset(HAVE_LIBUUID_H CACHE)
+ message(FATAL_ERROR "Cannot find libuuid. Try installing uuid-dev or the appropriate packages for your platform")
+ endif()
+ set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
+ set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
+ set(PAL_PT_ATTACH PT_ATTACH)
+ set(PAL_PT_DETACH PT_DETACH)
+ set(PAL_PT_READ_D PT_READ_D)
+ set(PAL_PT_WRITE_D PT_WRITE_D)
+ set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
+else() # Anything else is Linux
+ if(NOT HAVE_LIBUNWIND_H)
+ unset(HAVE_LIBUNWIND_H CACHE)
+ message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8 and libunwind8-dev (or the appropriate packages for your platform)")
+ endif()
+ if(NOT HAVE_LTTNG_TRACEPOINT_H AND FEATURE_EVENT_TRACE)
+ unset(HAVE_LTTNG_TRACEPOINT_H CACHE)
+ message(FATAL_ERROR "Cannot find liblttng-ust-dev. Try installing liblttng-ust-dev (or the appropriate packages for your platform)")
+ endif()
+ if(NOT HAVE_LIBUUID_H)
+ unset(HAVE_LIBUUID_H CACHE)
+ message(FATAL_ERROR "Cannot find libuuid. Try installing uuid-dev or the appropriate packages for your platform")
+ endif()
+ set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
+ set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
+ set(PAL_PT_ATTACH PTRACE_ATTACH)
+ set(PAL_PT_DETACH PTRACE_DETACH)
+ set(PAL_PT_READ_D PTRACE_PEEKDATA)
+ set(PAL_PT_WRITE_D PTRACE_POKEDATA)
+ set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
+ set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
+endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)