1 include(CheckCXXSourceCompiles)
2 include(CheckCXXSourceRuns)
3 include(CheckCXXSymbolExists)
4 include(CheckFunctionExists)
5 include(CheckIncludeFiles)
6 include(CheckStructHasMember)
8 include(CheckLibraryExists)
10 if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
11 set(CMAKE_REQUIRED_INCLUDES /usr/local/include)
12 elseif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
13 set(CMAKE_REQUIRED_INCLUDES /opt/local/include)
15 if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin AND NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
16 set(CMAKE_REQUIRED_DEFINITIONS "-D_BSD_SOURCE -D_SVID_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L")
19 if(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ANDROID)
21 elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
27 list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64)
29 check_include_files(ieeefp.h HAVE_IEEEFP_H)
30 check_include_files(sys/vmparam.h HAVE_SYS_VMPARAM_H)
31 check_include_files(mach/vm_types.h HAVE_MACH_VM_TYPES_H)
32 check_include_files(mach/vm_param.h HAVE_MACH_VM_PARAM_H)
33 check_include_files("sys/param.h;sys/types.h;machine/npx.h" HAVE_MACHINE_NPX_H)
34 check_include_files("sys/param.h;sys/cdefs.h;machine/reg.h" HAVE_MACHINE_REG_H)
35 check_include_files(machine/vmparam.h HAVE_MACHINE_VMPARAM_H)
36 check_include_files(procfs.h HAVE_PROCFS_H)
37 check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H)
38 check_include_files(sys/time.h HAVE_SYS_TIME_H)
39 check_include_files(pthread_np.h HAVE_PTHREAD_NP_H)
40 check_include_files(sys/lwp.h HAVE_SYS_LWP_H)
41 check_include_files(lwp.h HAVE_LWP_H)
42 check_include_files(runetype.h HAVE_RUNETYPE_H)
43 check_include_files(semaphore.h HAVE_SEMAPHORE_H)
44 check_include_files(sys/prctl.h HAVE_PRCTL_H)
45 check_include_files(numa.h HAVE_NUMA_H)
46 check_include_files(pthread_np.h HAVE_PTHREAD_NP_H)
47 check_include_files("sys/auxv.h;asm/hwcap.h" HAVE_AUXV_HWCAP_H)
49 if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
50 check_include_files("libintl.h" HAVE_LIBINTL_H)
53 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
55 check_cxx_source_compiles("
59 return VM_FLAGS_SUPERPAGE_SIZE_ANY;
61 " HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY)
63 check_cxx_source_compiles("
71 check_cxx_source_compiles("
72 #include <lttng/tracepoint.h>
73 int main(int argc, char **argv) {
75 }" HAVE_LTTNG_TRACEPOINT_H)
77 set(CMAKE_REQUIRED_LIBRARIES)
79 check_include_files(sys/sysctl.h HAVE_SYS_SYSCTL_H)
80 check_function_exists(sysctlbyname HAVE_SYSCTLBYNAME)
81 check_include_files(gnu/lib-names.h HAVE_GNU_LIBNAMES_H)
83 check_function_exists(kqueue HAVE_KQUEUE)
85 check_library_exists(c sched_getaffinity "" HAVE_SCHED_GETAFFINITY)
86 check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)
87 check_library_exists(c pthread_create "" HAVE_PTHREAD_IN_LIBC)
90 set(PTHREAD_LIBRARY pthread)
91 elseif (HAVE_PTHREAD_IN_LIBC)
92 set(PTHREAD_LIBRARY c)
95 check_library_exists(${PTHREAD_LIBRARY} pthread_suspend "" HAVE_PTHREAD_SUSPEND)
96 check_library_exists(${PTHREAD_LIBRARY} pthread_suspend_np "" HAVE_PTHREAD_SUSPEND_NP)
97 check_library_exists(${PTHREAD_LIBRARY} pthread_continue "" HAVE_PTHREAD_CONTINUE)
98 check_library_exists(${PTHREAD_LIBRARY} pthread_continue_np "" HAVE_PTHREAD_CONTINUE_NP)
99 check_library_exists(${PTHREAD_LIBRARY} pthread_resume_np "" HAVE_PTHREAD_RESUME_NP)
100 check_library_exists(${PTHREAD_LIBRARY} pthread_attr_get_np "" HAVE_PTHREAD_ATTR_GET_NP)
101 check_library_exists(${PTHREAD_LIBRARY} pthread_getattr_np "" HAVE_PTHREAD_GETATTR_NP)
102 check_library_exists(${PTHREAD_LIBRARY} pthread_getcpuclockid "" HAVE_PTHREAD_GETCPUCLOCKID)
103 check_library_exists(${PTHREAD_LIBRARY} pthread_sigqueue "" HAVE_PTHREAD_SIGQUEUE)
104 check_library_exists(${PTHREAD_LIBRARY} pthread_getaffinity_np "" HAVE_PTHREAD_GETAFFINITY_NP)
105 check_library_exists(${PTHREAD_LIBRARY} pthread_attr_setaffinity_np "" HAVE_PTHREAD_ATTR_SETAFFINITY_NP)
107 check_function_exists(sigreturn HAVE_SIGRETURN)
108 check_function_exists(_thread_sys_sigreturn HAVE__THREAD_SYS_SIGRETURN)
109 set(CMAKE_REQUIRED_LIBRARIES m)
110 check_function_exists(copysign HAVE_COPYSIGN)
111 set(CMAKE_REQUIRED_LIBRARIES)
112 check_function_exists(fsync HAVE_FSYNC)
113 check_function_exists(futimes HAVE_FUTIMES)
114 check_function_exists(utimes HAVE_UTIMES)
115 check_function_exists(sysctl HAVE_SYSCTL)
116 check_function_exists(sysinfo HAVE_SYSINFO)
117 check_function_exists(sysconf HAVE_SYSCONF)
118 check_function_exists(localtime_r HAVE_LOCALTIME_R)
119 check_function_exists(gmtime_r HAVE_GMTIME_R)
120 check_function_exists(timegm HAVE_TIMEGM)
121 check_function_exists(poll HAVE_POLL)
122 check_function_exists(statvfs HAVE_STATVFS)
123 check_function_exists(thread_self HAVE_THREAD_SELF)
124 check_function_exists(_lwp_self HAVE__LWP_SELF)
125 check_function_exists(pthread_mach_thread_np HAVE_MACH_THREADS)
126 check_function_exists(thread_set_exception_ports HAVE_MACH_EXCEPTIONS)
127 check_function_exists(vm_allocate HAVE_VM_ALLOCATE)
128 check_function_exists(vm_read HAVE_VM_READ)
129 check_function_exists(directio HAVE_DIRECTIO)
130 check_function_exists(semget HAS_SYSV_SEMAPHORES)
131 check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES)
132 check_function_exists(ttrace HAVE_TTRACE)
133 check_function_exists(pipe2 HAVE_PIPE2)
135 check_cxx_source_compiles("
136 #include <pthread_np.h>
137 int main(int argc, char **argv) {
143 check_struct_has_member ("struct stat" st_atimespec "sys/types.h;sys/stat.h" HAVE_STAT_TIMESPEC)
144 check_struct_has_member ("struct stat" st_atim "sys/types.h;sys/stat.h" HAVE_STAT_TIM)
145 check_struct_has_member ("struct stat" st_atimensec "sys/types.h;sys/stat.h" HAVE_STAT_NSEC)
146 check_struct_has_member ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
147 check_struct_has_member ("ucontext_t" uc_mcontext.gregs[0] ucontext.h HAVE_GREGSET_T)
148 check_struct_has_member ("ucontext_t" uc_mcontext.__gregs[0] ucontext.h HAVE___GREGSET_T)
149 check_struct_has_member ("ucontext_t" uc_mcontext.fpregs->__glibc_reserved1[0] ucontext.h HAVE_FPSTATE_GLIBC_RESERVED1)
150 check_struct_has_member ("struct sysinfo" mem_unit "sys/sysinfo.h" HAVE_SYSINFO_WITH_MEM_UNIT)
152 set(CMAKE_EXTRA_INCLUDE_FILES machine/reg.h)
153 check_type_size("struct reg" BSD_REGS_T)
154 set(CMAKE_EXTRA_INCLUDE_FILES)
155 set(CMAKE_EXTRA_INCLUDE_FILES asm/ptrace.h)
156 check_type_size("struct pt_regs" PT_REGS)
157 set(CMAKE_EXTRA_INCLUDE_FILES)
158 set(CMAKE_EXTRA_INCLUDE_FILES signal.h)
159 set(CMAKE_EXTRA_INCLUDE_FILES)
160 set(CMAKE_EXTRA_INCLUDE_FILES ucontext.h)
161 check_type_size(ucontext_t UCONTEXT_T)
162 set(CMAKE_EXTRA_INCLUDE_FILES)
163 set(CMAKE_EXTRA_INCLUDE_FILES pthread.h)
164 check_type_size(pthread_rwlock_t PTHREAD_RWLOCK_T)
165 set(CMAKE_EXTRA_INCLUDE_FILES)
166 set(CMAKE_EXTRA_INCLUDE_FILE procfs.h)
167 check_type_size(prwatch_t PRWATCH_T)
168 set(CMAKE_EXTRA_INCLUDE_FILE)
169 check_type_size(off_t SIZEOF_OFF_T)
171 check_cxx_symbol_exists(SYS_yield sys/syscall.h HAVE_YIELD_SYSCALL)
172 check_cxx_symbol_exists(INFTIM poll.h HAVE_INFTIM)
173 check_cxx_symbol_exists(CHAR_BIT limits.h HAVE_CHAR_BIT)
174 check_cxx_symbol_exists(_DEBUG sys/user.h USER_H_DEFINES_DEBUG)
175 check_cxx_symbol_exists(_SC_PHYS_PAGES unistd.h HAVE__SC_PHYS_PAGES)
176 check_cxx_symbol_exists(_SC_AVPHYS_PAGES unistd.h HAVE__SC_AVPHYS_PAGES)
178 check_cxx_source_runs("
179 #include <sys/param.h>
185 char resolvedPath[PATH_MAX];
186 #elif defined(MAXPATHLEN)
187 char resolvedPath[MAXPATHLEN];
189 char resolvedPath[1024];
191 path = realpath(\"a_nonexistent_file\", resolvedPath);
196 }" REALPATH_SUPPORTS_NONEXISTENT_FILES)
197 check_cxx_source_runs("
203 sscanf(\"5000000000\", \"%qu\", &n);
204 exit (n != 5000000000);
205 }" SSCANF_SUPPORT_ll)
206 check_cxx_source_runs("
214 char * strin = \"12.34e\";
216 ret = sscanf (strin, \"%e\", &f);
220 }" SSCANF_CANNOT_HANDLE_MISSING_EXPONENT)
221 check_cxx_source_runs("
226 char buf[256] = { 0 };
227 snprintf(buf, 0x7fffffff, \"%#x\", 0x12345678);
232 }" HAVE_LARGE_SNPRINTF_SUPPORT)
233 check_cxx_source_runs("
238 #include <sys/stat.h>
239 #include <sys/types.h>
240 #include <sys/time.h>
245 fd_set readFDs, writeFDs, exceptFDs;
246 struct timeval time = { 0 };
247 char * filename = NULL;
249 filename = (char *)malloc(L_tmpnam * sizeof(char)); /* ok to leak this at exit */
250 if (NULL == filename) {
254 /* On some platforms (e.g. HP-UX) the multithreading c-runtime does not
255 support the tmpnam(NULL) semantics, and it returns NULL. Therefore
256 we need to use the tmpnam(pbuffer) version.
258 if (NULL == tmpnam(filename)) {
261 if (mkfifo(filename, S_IRWXU) != 0) {
262 if (unlink(filename) != 0) {
265 if (mkfifo(filename, S_IRWXU) != 0) {
269 fd = open(filename, O_RDWR | O_NONBLOCK);
277 FD_SET(fd, &readFDs);
278 numFDs = select(fd + 1, &readFDs, &writeFDs, &exceptFDs, &time);
283 /* numFDs is zero if select() works correctly */
285 }" HAVE_BROKEN_FIFO_SELECT)
286 check_cxx_source_runs("
293 #include <sys/types.h>
294 #include <sys/event.h>
295 #include <sys/time.h>
296 #include <sys/stat.h>
303 struct kevent ke, keChangeList;
304 struct timespec ts = { 0, 0 };
306 char * filename = NULL;
308 filename = (char *)malloc(L_tmpnam * sizeof(char)); /* ok to leak this at exit */
309 if (NULL == filename)
314 /* On some platforms (e.g. HP-UX) the multithreading c-runtime does not
315 support the tmpnam(NULL) semantics, and it returns NULL. Therefore
316 we need to use the tmpnam(pbuffer) version.
318 if (NULL == tmpnam(filename)) {
321 if (mkfifo(filename, S_IRWXU) != 0) {
322 if (unlink(filename) != 0) {
325 if (mkfifo(filename, S_IRWXU) != 0) {
329 fd = open(filename, O_RDWR | O_NONBLOCK);
334 EV_SET(&keChangeList, fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL);
336 iRet = kevent(ikq, &keChangeList, 1, &ke, 1, &ts);
341 /* iRet is zero is kevent() works correctly */
343 }" HAVE_BROKEN_FIFO_KEVENT)
344 set(CMAKE_REQUIRED_LIBRARIES pthread)
345 check_cxx_source_runs("
354 struct sched_param schedParam;
358 if (0 != pthread_getschedparam(pthread_self(), &policy, &schedParam))
363 max_priority = sched_get_priority_max(policy);
364 min_priority = sched_get_priority_min(policy);
366 exit(-1 == max_priority || -1 == min_priority);
367 }" HAVE_SCHED_GET_PRIORITY)
368 set(CMAKE_REQUIRED_LIBRARIES pthread)
369 check_cxx_source_runs("
375 if (sched_getcpu() >= 0)
380 }" HAVE_SCHED_GETCPU)
381 set(CMAKE_REQUIRED_LIBRARIES)
382 check_cxx_source_runs("
385 #include <sys/time.h>
391 ret = gettimeofday(&tv, NULL);
394 }" HAVE_WORKING_GETTIMEOFDAY)
396 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
397 check_cxx_source_runs("
400 #include <sys/time.h>
406 ret = clock_gettime(CLOCK_REALTIME, &ts);
409 }" HAVE_WORKING_CLOCK_GETTIME)
410 set(CMAKE_REQUIRED_LIBRARIES)
412 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
413 check_cxx_source_runs("
416 #include <sys/time.h>
422 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
425 }" HAVE_CLOCK_MONOTONIC)
426 set(CMAKE_REQUIRED_LIBRARIES)
428 check_library_exists(${PTHREAD_LIBRARY} pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK)
430 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
431 check_cxx_source_runs("
434 #include <sys/time.h>
440 ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
443 }" HAVE_CLOCK_MONOTONIC_COARSE)
444 set(CMAKE_REQUIRED_LIBRARIES)
446 check_cxx_source_runs("
448 #include <mach/mach_time.h>
453 mach_timebase_info_data_t timebaseInfo;
454 ret = mach_timebase_info(&timebaseInfo);
455 mach_absolute_time();
457 }" HAVE_MACH_ABSOLUTE_TIME)
459 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
460 check_cxx_source_runs("
463 #include <sys/time.h>
469 ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
472 }" HAVE_CLOCK_THREAD_CPUTIME)
473 set(CMAKE_REQUIRED_LIBRARIES)
475 check_cxx_source_runs("
477 #include <sys/types.h>
478 #include <sys/mman.h>
485 devzero = open(\"/dev/zero\", O_RDWR);
489 retval = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, devzero, 0);
490 if (retval == (void *)-1) {
494 }" HAVE_MMAP_DEV_ZERO)
495 check_cxx_source_runs("
496 #include <sys/types.h>
497 #include <sys/mman.h>
503 #define MAP_ANON MAP_ANONYMOUS
506 void *handle_signal(int signal) {
507 /* If we reach this, we've crashed due to mmap honoring
514 struct sigaction action;
516 ptr = (int *) mmap(NULL, getpagesize(), PROT_NONE,
517 MAP_ANON | MAP_PRIVATE, -1, 0);
518 if (ptr == (int *) MAP_FAILED) {
521 action.sa_handler = &handle_signal;
523 sigemptyset(&action.sa_mask);
524 if (sigaction(SIGBUS, &action, NULL) != 0) {
527 if (sigaction(SIGSEGV, &action, NULL) != 0) {
530 /* This will drop us into the signal handler if PROT_NONE
534 }" MMAP_ANON_IGNORES_PROTECTION)
535 check_cxx_source_runs("
540 #include <sys/types.h>
541 #include <sys/mman.h>
543 #define MEM_SIZE 1024
550 void * pAddr0, * pAddr1;
552 fname = (char *)malloc(MEM_SIZE);
555 strcpy(fname, \"/tmp/name/multiplemaptestXXXXXX\");
561 ret = write (fd, (void *)fname, MEM_SIZE);
565 pAddr0 = mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
566 pAddr1 = mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
568 /* In theory we should look for (pAddr1 == MAP_FAILED) && (pAddr1 != MAP_FAILED)
569 but in case the first test also failed, i.e. we failed to run the test,
570 let's assume that the system might not allow multiple shared mapping of the
571 same file region in the same process. The code enabled in this case is
572 only a fall-back code path. In case the double mmap actually works, virtually
573 nothing will change and the normal code path will be executed */
574 if (pAddr1 == MAP_FAILED)
580 munmap (pAddr0, MEM_SIZE);
582 munmap (pAddr1, MEM_SIZE);
588 }" ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS)
589 set(CMAKE_REQUIRED_LIBRARIES pthread)
590 check_cxx_source_runs("
595 void *start_routine(void *param) { return NULL; }
602 result = pthread_create(&tid, NULL, start_routine, NULL);
610 }" PTHREAD_CREATE_MODIFIES_ERRNO)
611 set(CMAKE_REQUIRED_LIBRARIES)
612 set(CMAKE_REQUIRED_LIBRARIES pthread)
613 check_cxx_source_runs("
615 #include <semaphore.h>
623 result = sem_init(&sema, 0, 0);
633 }" SEM_INIT_MODIFIES_ERRNO)
634 set(CMAKE_REQUIRED_LIBRARIES)
635 check_cxx_source_runs("
645 #elif defined(MAXPATHLEN)
646 char path[MAXPATHLEN];
651 sprintf(path, \"/proc/%u/ctl\", getpid());
652 fd = open(path, O_WRONLY);
658 set(CMAKE_REQUIRED_LIBRARIES)
659 check_cxx_source_runs("
669 #elif defined(MAXPATHLEN)
670 char path[MAXPATHLEN];
675 sprintf(path, \"/proc/%u/maps\", getpid());
676 fd = open(path, O_RDONLY);
682 set(CMAKE_REQUIRED_LIBRARIES)
683 check_cxx_source_runs("
693 #elif defined(MAXPATHLEN)
694 char path[MAXPATHLEN];
699 sprintf(path, \"/proc/%u/stat\", getpid());
700 fd = open(path, O_RDONLY);
706 set(CMAKE_REQUIRED_LIBRARIES)
707 check_cxx_source_runs("
717 #elif defined(MAXPATHLEN)
718 char path[MAXPATHLEN];
723 sprintf(path, \"/proc/%u/status\", getpid());
724 fd = open(path, O_RDONLY);
729 }" HAVE_PROCFS_STATUS)
730 set(CMAKE_REQUIRED_LIBRARIES m)
731 check_cxx_source_runs("
736 if (!isnan(acos(10))) {
740 }" HAVE_COMPATIBLE_ACOS)
741 set(CMAKE_REQUIRED_LIBRARIES)
742 set(CMAKE_REQUIRED_LIBRARIES m)
743 check_cxx_source_runs("
748 if (!isnan(asin(10))) {
752 }" HAVE_COMPATIBLE_ASIN)
753 set(CMAKE_REQUIRED_LIBRARIES)
754 set(CMAKE_REQUIRED_LIBRARIES m)
755 check_cxx_source_runs("
760 double infinity = 1.0 / 0.0;
761 if (pow(1.0, infinity) != 1.0 || pow(1.0, -infinity) != 1.0) {
764 if (pow(-1.0, infinity) != 1.0 || pow(-1.0, -infinity) != 1.0) {
767 if (pow(0.0, infinity) != 0.0) {
770 if (pow(0.0, -infinity) != infinity) {
773 if (pow(-1.1, infinity) != infinity || pow(1.1, infinity) != infinity) {
776 if (pow(-1.1, -infinity) != 0.0 || pow(1.1, -infinity) != 0.0) {
779 if (pow(-0.0, -1) != -infinity) {
782 if (pow(0.0, -1) != infinity) {
786 }" HAVE_COMPATIBLE_POW)
787 set(CMAKE_REQUIRED_LIBRARIES)
788 set(CMAKE_REQUIRED_LIBRARIES m)
789 check_cxx_source_runs("
793 int main(int argc, char **argv) {
796 result = pow(-3.2e-10, -5e14 + 1);
797 if (result != -1.0 / 0.0) {
801 }" HAVE_VALID_NEGATIVE_INF_POW)
802 set(CMAKE_REQUIRED_LIBRARIES)
803 set(CMAKE_REQUIRED_LIBRARIES m)
804 check_cxx_source_runs("
808 int main(int argc, char **argv) {
811 result = pow(-3.5, 3e100);
812 if (result != 1.0 / 0.0) {
816 }" HAVE_VALID_POSITIVE_INF_POW)
817 set(CMAKE_REQUIRED_LIBRARIES)
818 set(CMAKE_REQUIRED_LIBRARIES m)
819 check_cxx_source_runs("
824 double pi = 3.14159265358979323846;
827 result = atan2(0.0, -0.0);
828 if (fabs(pi - result) > 0.0000001) {
832 result = atan2(-0.0, -0.0);
833 if (fabs(-pi - result) > 0.0000001) {
837 result = atan2 (-0.0, 0.0);
838 if (result != 0.0 || copysign (1.0, result) > 0) {
842 result = atan2 (0.0, 0.0);
843 if (result != 0.0 || copysign (1.0, result) < 0) {
848 }" HAVE_COMPATIBLE_ATAN2)
849 set(CMAKE_REQUIRED_LIBRARIES)
850 set(CMAKE_REQUIRED_LIBRARIES m)
851 check_cxx_source_runs("
856 double d = exp(1.0), e = M_E;
858 /* Used memcmp rather than == to test that the doubles are equal to
859 prevent gcc's optimizer from using its 80 bit internal long
860 doubles. If you use ==, then on BSD you get a false negative since
861 exp(1.0) == M_E to 64 bits, but not 80.
864 if (memcmp (&d, &e, sizeof (double)) == 0) {
868 }" HAVE_COMPATIBLE_EXP)
869 set(CMAKE_REQUIRED_LIBRARIES)
870 set(CMAKE_REQUIRED_LIBRARIES m)
871 check_cxx_source_runs("
876 if (FP_ILOGB0 != -2147483648) {
881 }" HAVE_COMPATIBLE_ILOGB0)
882 set(CMAKE_REQUIRED_LIBRARIES)
883 set(CMAKE_REQUIRED_LIBRARIES m)
884 check_cxx_source_runs("
889 if (FP_ILOGBNAN != 2147483647) {
894 }" HAVE_COMPATIBLE_ILOGBNAN)
895 set(CMAKE_REQUIRED_LIBRARIES)
896 set(CMAKE_REQUIRED_LIBRARIES m)
897 check_cxx_source_runs("
902 if (!isnan(log(-10000))) {
906 }" HAVE_COMPATIBLE_LOG)
907 set(CMAKE_REQUIRED_LIBRARIES)
908 set(CMAKE_REQUIRED_LIBRARIES m)
909 check_cxx_source_runs("
914 if (!isnan(log10(-10000))) {
918 }" HAVE_COMPATIBLE_LOG10)
919 set(CMAKE_REQUIRED_LIBRARIES)
920 check_cxx_source_runs("
931 szFileName = tempnam(\".\", \"tmp\");
933 /* open the file write-only */
934 pFile = fopen(szFileName, \"a\");
939 if (ungetc('A', pFile) != EOF)
945 }" UNGETC_NOT_RETURN_EOF)
947 set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARY})
948 check_cxx_source_runs("
951 #include <semaphore.h>
955 if (sem_init(&sema, 0, 0) == -1){
959 }" HAS_POSIX_SEMAPHORES)
960 set(CMAKE_REQUIRED_LIBRARIES)
961 check_cxx_source_runs("
962 #include <sys/types.h>
970 struct passwd sPasswd;
971 struct passwd *pPasswd;
973 int bufLen = sizeof(buf)/sizeof(buf[0]);
974 int euid = geteuid();
977 errno = 0; // clear errno
978 ret = getpwuid_r(euid, &sPasswd, buf, bufLen, &pPasswd);
987 return 1; // assume errno is NOT set for all other cases
988 }" GETPWUID_R_SETS_ERRNO)
989 check_cxx_source_runs("
996 char *fileName = \"/dev/zero\";
1000 * Open the file in append mode and try to read some text.
1001 * And, make sure ferror() is set.
1003 fp = fopen (fileName, \"a\");
1004 if ( (NULL == fp) ||
1005 (fread (buf, sizeof(buf), 1, fp) > 0) ||
1013 * Now that ferror() is set, try to close the file.
1014 * If we get an error, we can conclude that this
1015 * fgets() depended on the previous ferror().
1017 if ( fclose(fp) != 0 )
1023 }" FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL)
1025 set(SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING 1)
1026 set(ERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS 1)
1028 if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
1029 list(INSERT CMAKE_REQUIRED_INCLUDES 0 ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include)
1032 set(CMAKE_REQUIRED_FLAGS "-c -Werror=implicit-function-declaration")
1034 check_c_source_compiles("
1035 #include <libunwind.h>
1036 #include <ucontext.h>
1037 int main(int argc, char **argv)
1039 unw_context_t libUnwindContext;
1040 ucontext_t uContext;
1041 libUnwindContext = uContext;
1043 }" UNWIND_CONTEXT_IS_UCONTEXT_T)
1045 check_c_source_compiles("
1046 #include <libunwind.h>
1048 int main(int argc, char **argv) {
1049 unw_cursor_t cursor;
1050 unw_save_loc_t saveLoc;
1051 int reg = UNW_REG_IP;
1052 unw_get_save_loc(&cursor, reg, &saveLoc);
1055 }" HAVE_UNW_GET_SAVE_LOC)
1057 check_c_source_compiles("
1058 #include <libunwind.h>
1060 int main(int argc, char **argv) {
1061 unw_addr_space_t as;
1062 unw_get_accessors(as);
1065 }" HAVE_UNW_GET_ACCESSORS)
1067 set(CMAKE_REQUIRED_FLAGS)
1068 if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
1069 list(REMOVE_AT CMAKE_REQUIRED_INCLUDES 0 1)
1072 check_cxx_source_compiles("
1073 #include <sys/param.h>
1074 #include <sys/sysctl.h>
1075 #include <vm/vm_param.h>
1077 int main(int argc, char **argv)
1084 check_cxx_source_compiles("
1085 #include <sys/param.h>
1086 #include <sys/sysctl.h>
1088 int main(int argc, char **argv)
1090 struct xsw_usage xsu;
1095 check_cxx_source_compiles("
1098 int main(int argc, char **argv)
1100 struct _xstate xstate;
1101 struct _fpx_sw_bytes bytes;
1103 }" HAVE_PUBLIC_XSTATE_STRUCT)
1105 check_cxx_source_compiles("
1106 #include <sys/prctl.h>
1108 int main(int argc, char **argv)
1110 int flag = (int)PR_SET_PTRACER;
1112 }" HAVE_PR_SET_PTRACER)
1114 set(CMAKE_REQUIRED_LIBRARIES pthread)
1115 check_cxx_source_compiles("
1117 #include <pthread.h>
1122 pthread_mutexattr_t mutexAttributes;
1123 pthread_mutexattr_init(&mutexAttributes);
1124 pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED);
1125 pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
1126 pthread_mutexattr_setrobust(&mutexAttributes, PTHREAD_MUTEX_ROBUST);
1128 pthread_mutex_t mutex;
1129 pthread_mutex_init(&mutex, &mutexAttributes);
1131 pthread_mutexattr_destroy(&mutexAttributes);
1133 struct timespec timeoutTime;
1134 timeoutTime.tv_sec = 1; // not the right way to specify absolute time, but just checking availability of timed lock
1135 timeoutTime.tv_nsec = 0;
1136 pthread_mutex_timedlock(&mutex, &timeoutTime);
1137 pthread_mutex_consistent(&mutex);
1139 pthread_mutex_destroy(&mutex);
1141 int error = EOWNERDEAD;
1142 error = ENOTRECOVERABLE;
1146 }" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
1147 set(CMAKE_REQUIRED_LIBRARIES)
1149 if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM AND NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
1150 set(CMAKE_REQUIRED_LIBRARIES pthread)
1151 check_cxx_source_runs("
1152 // This test case verifies the pthread process-shared robust mutex's cross-process abandon detection. The parent process starts
1153 // a child process that locks the mutex, the process process then waits to acquire the lock, and the child process abandons the
1154 // mutex by exiting the process while holding the lock. The parent process should then be released from its wait, be assigned
1155 // ownership of the lock, and be notified that the mutex was abandoned.
1157 #include <sys/mman.h>
1158 #include <sys/time.h>
1161 #include <pthread.h>
1166 using namespace std;
1170 pthread_mutex_t syncMutex;
1171 pthread_cond_t syncCondition;
1172 pthread_mutex_t robustMutex;
1175 Shm() : conditionValue(0)
1180 int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
1182 int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
1183 if (getTimeResult != 0)
1186 getTimeResult = gettimeofday(&tv, NULL);
1187 if (getTimeResult != 0)
1189 timeoutTimeRef->tv_sec = tv.tv_sec;
1190 timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
1192 timeoutTimeRef->tv_sec += 30;
1196 int WaitForConditionValue(int desiredConditionValue)
1198 struct timespec timeoutTime;
1199 if (GetFailTimeoutTime(&timeoutTime) != 0)
1201 if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1204 if (shm->conditionValue != desiredConditionValue)
1206 if (GetFailTimeoutTime(&timeoutTime) != 0)
1208 if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
1210 if (shm->conditionValue != desiredConditionValue)
1214 if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1219 int SetConditionValue(int newConditionValue)
1221 struct timespec timeoutTime;
1222 if (GetFailTimeoutTime(&timeoutTime) != 0)
1224 if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1227 shm->conditionValue = newConditionValue;
1228 if (pthread_cond_signal(&shm->syncCondition) != 0)
1231 if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1236 void DoTest_Child();
1240 // Map some shared memory
1241 void *shmBuffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
1242 if (shmBuffer == MAP_FAILED)
1244 shm = new(shmBuffer) Shm;
1246 // Create sync mutex
1247 pthread_mutexattr_t syncMutexAttributes;
1248 if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
1250 if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1252 if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
1254 if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
1257 // Create sync condition
1258 pthread_condattr_t syncConditionAttributes;
1259 if (pthread_condattr_init(&syncConditionAttributes) != 0)
1261 if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
1263 if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
1265 if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
1268 // Create the robust mutex that will be tested
1269 pthread_mutexattr_t robustMutexAttributes;
1270 if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
1272 if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1274 if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
1276 if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
1278 if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
1281 // Start child test process
1291 // Wait for child to take a lock
1292 WaitForConditionValue(1);
1294 // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
1295 struct timespec timeoutTime;
1296 if (GetFailTimeoutTime(&timeoutTime) != 0)
1298 error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
1299 if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
1301 if (pthread_mutex_consistent(&shm->robustMutex) != 0)
1304 if (pthread_mutex_unlock(&shm->robustMutex) != 0)
1306 if (pthread_mutex_destroy(&shm->robustMutex) != 0)
1313 // Lock the robust mutex
1314 struct timespec timeoutTime;
1315 if (GetFailTimeoutTime(&timeoutTime) != 0)
1317 if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
1320 // Notify parent that robust mutex is locked
1321 if (SetConditionValue(1) != 0)
1324 // Wait a short period to let the parent block on waiting for a lock
1327 // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
1332 int result = DoTest();
1333 return result >= 0 ? result : 0;
1334 }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
1335 set(CMAKE_REQUIRED_LIBRARIES)
1338 if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
1339 set(HAVE_COREFOUNDATION 1)
1340 set(HAVE__NSGETENVIRON 1)
1341 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 1)
1342 set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
1343 set(PAL_PT_ATTACH PT_ATTACH)
1344 set(PAL_PT_DETACH PT_DETACH)
1345 set(PAL_PT_READ_D PT_READ_D)
1346 set(PAL_PT_WRITE_D PT_WRITE_D)
1347 set(HAS_FTRUNCATE_LENGTH_ISSUE 1)
1348 set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
1350 elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
1351 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1352 set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
1353 set(PAL_PT_ATTACH PT_ATTACH)
1354 set(PAL_PT_DETACH PT_DETACH)
1355 set(PAL_PT_READ_D PT_READ_D)
1356 set(PAL_PT_WRITE_D PT_WRITE_D)
1357 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1358 set(BSD_REGS_STYLE "((reg).r_##rr)")
1359 set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
1360 elseif(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
1361 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1362 set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
1363 set(PAL_PT_ATTACH PT_ATTACH)
1364 set(PAL_PT_DETACH PT_DETACH)
1365 set(PAL_PT_READ_D PT_READ_D)
1366 set(PAL_PT_WRITE_D PT_WRITE_D)
1367 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1368 set(BSD_REGS_STYLE "((reg).regs[_REG_##RR])")
1369 set(HAVE_SCHED_OTHER_ASSIGNABLE 0)
1371 elseif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
1372 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1373 set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
1374 set(PAL_PT_ATTACH PT_ATTACH)
1375 set(PAL_PT_DETACH PT_DETACH)
1376 set(PAL_PT_READ_D PT_READ_D)
1377 set(PAL_PT_WRITE_D PT_WRITE_D)
1378 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1379 else() # Anything else is Linux
1380 if(NOT HAVE_LTTNG_TRACEPOINT_H AND FEATURE_EVENT_TRACE)
1381 unset(HAVE_LTTNG_TRACEPOINT_H CACHE)
1382 message(FATAL_ERROR "Cannot find liblttng-ust-dev. Try installing liblttng-ust-dev (or the appropriate packages for your platform)")
1384 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1385 set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
1386 set(PAL_PT_ATTACH PTRACE_ATTACH)
1387 set(PAL_PT_DETACH PTRACE_DETACH)
1388 set(PAL_PT_READ_D PTRACE_PEEKDATA)
1389 set(PAL_PT_WRITE_D PTRACE_POKEDATA)
1390 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1391 set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
1392 endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
1394 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)