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>
544 #define MEM_SIZE 1024
545 #define TEMP_FILE_TEMPLATE \"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/multiplemaptestXXXXXX\"
551 void * pAddr0, * pAddr1;
553 fname = (char *)malloc(std::max((size_t)MEM_SIZE, sizeof(TEMP_FILE_TEMPLATE)));
556 strcpy(fname, TEMP_FILE_TEMPLATE);
562 ret = write (fd, (void *)fname, MEM_SIZE);
566 pAddr0 = mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
567 pAddr1 = mmap(0, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
569 /* In theory we should look for (pAddr1 == MAP_FAILED) && (pAddr1 != MAP_FAILED)
570 but in case the first test also failed, i.e. we failed to run the test,
571 let's assume that the system might not allow multiple shared mapping of the
572 same file region in the same process. The code enabled in this case is
573 only a fall-back code path. In case the double mmap actually works, virtually
574 nothing will change and the normal code path will be executed */
575 if (pAddr1 == MAP_FAILED)
581 munmap (pAddr0, MEM_SIZE);
583 munmap (pAddr1, MEM_SIZE);
589 }" ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS)
590 set(CMAKE_REQUIRED_LIBRARIES pthread)
591 check_cxx_source_runs("
596 void *start_routine(void *param) { return NULL; }
603 result = pthread_create(&tid, NULL, start_routine, NULL);
611 }" PTHREAD_CREATE_MODIFIES_ERRNO)
612 set(CMAKE_REQUIRED_LIBRARIES)
613 set(CMAKE_REQUIRED_LIBRARIES pthread)
614 check_cxx_source_runs("
616 #include <semaphore.h>
624 result = sem_init(&sema, 0, 0);
634 }" SEM_INIT_MODIFIES_ERRNO)
635 set(CMAKE_REQUIRED_LIBRARIES)
636 check_cxx_source_runs("
646 #elif defined(MAXPATHLEN)
647 char path[MAXPATHLEN];
652 sprintf(path, \"/proc/%u/ctl\", getpid());
653 fd = open(path, O_WRONLY);
659 set(CMAKE_REQUIRED_LIBRARIES)
660 check_cxx_source_runs("
670 #elif defined(MAXPATHLEN)
671 char path[MAXPATHLEN];
676 sprintf(path, \"/proc/%u/maps\", getpid());
677 fd = open(path, O_RDONLY);
683 set(CMAKE_REQUIRED_LIBRARIES)
684 check_cxx_source_runs("
694 #elif defined(MAXPATHLEN)
695 char path[MAXPATHLEN];
700 sprintf(path, \"/proc/%u/stat\", getpid());
701 fd = open(path, O_RDONLY);
707 set(CMAKE_REQUIRED_LIBRARIES)
708 check_cxx_source_runs("
718 #elif defined(MAXPATHLEN)
719 char path[MAXPATHLEN];
724 sprintf(path, \"/proc/%u/status\", getpid());
725 fd = open(path, O_RDONLY);
730 }" HAVE_PROCFS_STATUS)
731 set(CMAKE_REQUIRED_LIBRARIES m)
732 check_cxx_source_runs("
737 if (!isnan(acos(10))) {
741 }" HAVE_COMPATIBLE_ACOS)
742 set(CMAKE_REQUIRED_LIBRARIES)
743 set(CMAKE_REQUIRED_LIBRARIES m)
744 check_cxx_source_runs("
749 if (!isnan(asin(10))) {
753 }" HAVE_COMPATIBLE_ASIN)
754 set(CMAKE_REQUIRED_LIBRARIES)
755 set(CMAKE_REQUIRED_LIBRARIES m)
756 check_cxx_source_runs("
761 double infinity = 1.0 / 0.0;
762 if (pow(1.0, infinity) != 1.0 || pow(1.0, -infinity) != 1.0) {
765 if (pow(-1.0, infinity) != 1.0 || pow(-1.0, -infinity) != 1.0) {
768 if (pow(0.0, infinity) != 0.0) {
771 if (pow(0.0, -infinity) != infinity) {
774 if (pow(-1.1, infinity) != infinity || pow(1.1, infinity) != infinity) {
777 if (pow(-1.1, -infinity) != 0.0 || pow(1.1, -infinity) != 0.0) {
780 if (pow(-0.0, -1) != -infinity) {
783 if (pow(0.0, -1) != infinity) {
787 }" HAVE_COMPATIBLE_POW)
788 set(CMAKE_REQUIRED_LIBRARIES)
789 set(CMAKE_REQUIRED_LIBRARIES m)
790 check_cxx_source_runs("
794 int main(int argc, char **argv) {
797 result = pow(-3.2e-10, -5e14 + 1);
798 if (result != -1.0 / 0.0) {
802 }" HAVE_VALID_NEGATIVE_INF_POW)
803 set(CMAKE_REQUIRED_LIBRARIES)
804 set(CMAKE_REQUIRED_LIBRARIES m)
805 check_cxx_source_runs("
809 int main(int argc, char **argv) {
812 result = pow(-3.5, 3e100);
813 if (result != 1.0 / 0.0) {
817 }" HAVE_VALID_POSITIVE_INF_POW)
818 set(CMAKE_REQUIRED_LIBRARIES)
819 set(CMAKE_REQUIRED_LIBRARIES m)
820 check_cxx_source_runs("
825 double pi = 3.14159265358979323846;
828 result = atan2(0.0, -0.0);
829 if (fabs(pi - result) > 0.0000001) {
833 result = atan2(-0.0, -0.0);
834 if (fabs(-pi - result) > 0.0000001) {
838 result = atan2 (-0.0, 0.0);
839 if (result != 0.0 || copysign (1.0, result) > 0) {
843 result = atan2 (0.0, 0.0);
844 if (result != 0.0 || copysign (1.0, result) < 0) {
849 }" HAVE_COMPATIBLE_ATAN2)
850 set(CMAKE_REQUIRED_LIBRARIES)
851 set(CMAKE_REQUIRED_LIBRARIES m)
852 check_cxx_source_runs("
857 double d = exp(1.0), e = M_E;
859 /* Used memcmp rather than == to test that the doubles are equal to
860 prevent gcc's optimizer from using its 80 bit internal long
861 doubles. If you use ==, then on BSD you get a false negative since
862 exp(1.0) == M_E to 64 bits, but not 80.
865 if (memcmp (&d, &e, sizeof (double)) == 0) {
869 }" HAVE_COMPATIBLE_EXP)
870 set(CMAKE_REQUIRED_LIBRARIES)
871 set(CMAKE_REQUIRED_LIBRARIES m)
872 check_cxx_source_runs("
877 if (FP_ILOGB0 != -2147483648) {
882 }" HAVE_COMPATIBLE_ILOGB0)
883 set(CMAKE_REQUIRED_LIBRARIES)
884 set(CMAKE_REQUIRED_LIBRARIES m)
885 check_cxx_source_runs("
890 if (FP_ILOGBNAN != 2147483647) {
895 }" HAVE_COMPATIBLE_ILOGBNAN)
896 set(CMAKE_REQUIRED_LIBRARIES)
897 set(CMAKE_REQUIRED_LIBRARIES m)
898 check_cxx_source_runs("
903 if (!isnan(log(-10000))) {
907 }" HAVE_COMPATIBLE_LOG)
908 set(CMAKE_REQUIRED_LIBRARIES)
909 set(CMAKE_REQUIRED_LIBRARIES m)
910 check_cxx_source_runs("
915 if (!isnan(log10(-10000))) {
919 }" HAVE_COMPATIBLE_LOG10)
920 set(CMAKE_REQUIRED_LIBRARIES)
921 check_cxx_source_runs("
932 szFileName = tempnam(\".\", \"tmp\");
934 /* open the file write-only */
935 pFile = fopen(szFileName, \"a\");
940 if (ungetc('A', pFile) != EOF)
946 }" UNGETC_NOT_RETURN_EOF)
948 set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARY})
949 check_cxx_source_runs("
952 #include <semaphore.h>
956 if (sem_init(&sema, 0, 0) == -1){
960 }" HAS_POSIX_SEMAPHORES)
961 set(CMAKE_REQUIRED_LIBRARIES)
962 check_cxx_source_runs("
963 #include <sys/types.h>
971 struct passwd sPasswd;
972 struct passwd *pPasswd;
974 int bufLen = sizeof(buf)/sizeof(buf[0]);
975 int euid = geteuid();
978 errno = 0; // clear errno
979 ret = getpwuid_r(euid, &sPasswd, buf, bufLen, &pPasswd);
988 return 1; // assume errno is NOT set for all other cases
989 }" GETPWUID_R_SETS_ERRNO)
990 check_cxx_source_runs("
997 char *fileName = \"/dev/zero\";
1001 * Open the file in append mode and try to read some text.
1002 * And, make sure ferror() is set.
1004 fp = fopen (fileName, \"a\");
1005 if ( (NULL == fp) ||
1006 (fread (buf, sizeof(buf), 1, fp) > 0) ||
1014 * Now that ferror() is set, try to close the file.
1015 * If we get an error, we can conclude that this
1016 * fgets() depended on the previous ferror().
1018 if ( fclose(fp) != 0 )
1024 }" FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL)
1026 set(SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING 1)
1027 set(ERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS 1)
1029 if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
1030 list(INSERT CMAKE_REQUIRED_INCLUDES 0 ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include)
1033 set(CMAKE_REQUIRED_FLAGS "-c -Werror=implicit-function-declaration")
1035 check_c_source_compiles("
1036 #include <libunwind.h>
1037 #include <ucontext.h>
1038 int main(int argc, char **argv)
1040 unw_context_t libUnwindContext;
1041 ucontext_t uContext;
1042 libUnwindContext = uContext;
1044 }" UNWIND_CONTEXT_IS_UCONTEXT_T)
1046 check_c_source_compiles("
1047 #include <libunwind.h>
1049 int main(int argc, char **argv) {
1050 unw_cursor_t cursor;
1051 unw_save_loc_t saveLoc;
1052 int reg = UNW_REG_IP;
1053 unw_get_save_loc(&cursor, reg, &saveLoc);
1056 }" HAVE_UNW_GET_SAVE_LOC)
1058 check_c_source_compiles("
1059 #include <libunwind.h>
1061 int main(int argc, char **argv) {
1062 unw_addr_space_t as;
1063 unw_get_accessors(as);
1066 }" HAVE_UNW_GET_ACCESSORS)
1068 set(CMAKE_REQUIRED_FLAGS)
1069 if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
1070 list(REMOVE_AT CMAKE_REQUIRED_INCLUDES 0 1)
1073 check_cxx_source_compiles("
1074 #include <sys/param.h>
1075 #include <sys/sysctl.h>
1076 #include <vm/vm_param.h>
1078 int main(int argc, char **argv)
1085 check_cxx_source_compiles("
1086 #include <sys/param.h>
1087 #include <sys/sysctl.h>
1089 int main(int argc, char **argv)
1091 struct xsw_usage xsu;
1096 check_cxx_source_compiles("
1099 int main(int argc, char **argv)
1101 struct _xstate xstate;
1102 struct _fpx_sw_bytes bytes;
1104 }" HAVE_PUBLIC_XSTATE_STRUCT)
1106 check_cxx_source_compiles("
1107 #include <sys/prctl.h>
1109 int main(int argc, char **argv)
1111 int flag = (int)PR_SET_PTRACER;
1113 }" HAVE_PR_SET_PTRACER)
1115 set(CMAKE_REQUIRED_LIBRARIES pthread)
1116 check_cxx_source_compiles("
1118 #include <pthread.h>
1123 pthread_mutexattr_t mutexAttributes;
1124 pthread_mutexattr_init(&mutexAttributes);
1125 pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED);
1126 pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
1127 pthread_mutexattr_setrobust(&mutexAttributes, PTHREAD_MUTEX_ROBUST);
1129 pthread_mutex_t mutex;
1130 pthread_mutex_init(&mutex, &mutexAttributes);
1132 pthread_mutexattr_destroy(&mutexAttributes);
1134 struct timespec timeoutTime;
1135 timeoutTime.tv_sec = 1; // not the right way to specify absolute time, but just checking availability of timed lock
1136 timeoutTime.tv_nsec = 0;
1137 pthread_mutex_timedlock(&mutex, &timeoutTime);
1138 pthread_mutex_consistent(&mutex);
1140 pthread_mutex_destroy(&mutex);
1142 int error = EOWNERDEAD;
1143 error = ENOTRECOVERABLE;
1147 }" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
1148 set(CMAKE_REQUIRED_LIBRARIES)
1150 if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM AND NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
1151 set(CMAKE_REQUIRED_LIBRARIES pthread)
1152 check_cxx_source_runs("
1153 // This test case verifies the pthread process-shared robust mutex's cross-process abandon detection. The parent process starts
1154 // a child process that locks the mutex, the process process then waits to acquire the lock, and the child process abandons the
1155 // mutex by exiting the process while holding the lock. The parent process should then be released from its wait, be assigned
1156 // ownership of the lock, and be notified that the mutex was abandoned.
1158 #include <sys/mman.h>
1159 #include <sys/time.h>
1162 #include <pthread.h>
1167 using namespace std;
1171 pthread_mutex_t syncMutex;
1172 pthread_cond_t syncCondition;
1173 pthread_mutex_t robustMutex;
1176 Shm() : conditionValue(0)
1181 int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
1183 int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
1184 if (getTimeResult != 0)
1187 getTimeResult = gettimeofday(&tv, NULL);
1188 if (getTimeResult != 0)
1190 timeoutTimeRef->tv_sec = tv.tv_sec;
1191 timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
1193 timeoutTimeRef->tv_sec += 30;
1197 int WaitForConditionValue(int desiredConditionValue)
1199 struct timespec timeoutTime;
1200 if (GetFailTimeoutTime(&timeoutTime) != 0)
1202 if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1205 if (shm->conditionValue != desiredConditionValue)
1207 if (GetFailTimeoutTime(&timeoutTime) != 0)
1209 if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
1211 if (shm->conditionValue != desiredConditionValue)
1215 if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1220 int SetConditionValue(int newConditionValue)
1222 struct timespec timeoutTime;
1223 if (GetFailTimeoutTime(&timeoutTime) != 0)
1225 if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1228 shm->conditionValue = newConditionValue;
1229 if (pthread_cond_signal(&shm->syncCondition) != 0)
1232 if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1237 void DoTest_Child();
1241 // Map some shared memory
1242 void *shmBuffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
1243 if (shmBuffer == MAP_FAILED)
1245 shm = new(shmBuffer) Shm;
1247 // Create sync mutex
1248 pthread_mutexattr_t syncMutexAttributes;
1249 if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
1251 if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1253 if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
1255 if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
1258 // Create sync condition
1259 pthread_condattr_t syncConditionAttributes;
1260 if (pthread_condattr_init(&syncConditionAttributes) != 0)
1262 if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
1264 if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
1266 if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
1269 // Create the robust mutex that will be tested
1270 pthread_mutexattr_t robustMutexAttributes;
1271 if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
1273 if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1275 if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
1277 if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
1279 if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
1282 // Start child test process
1292 // Wait for child to take a lock
1293 WaitForConditionValue(1);
1295 // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
1296 struct timespec timeoutTime;
1297 if (GetFailTimeoutTime(&timeoutTime) != 0)
1299 error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
1300 if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
1302 if (pthread_mutex_consistent(&shm->robustMutex) != 0)
1305 if (pthread_mutex_unlock(&shm->robustMutex) != 0)
1307 if (pthread_mutex_destroy(&shm->robustMutex) != 0)
1314 // Lock the robust mutex
1315 struct timespec timeoutTime;
1316 if (GetFailTimeoutTime(&timeoutTime) != 0)
1318 if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
1321 // Notify parent that robust mutex is locked
1322 if (SetConditionValue(1) != 0)
1325 // Wait a short period to let the parent block on waiting for a lock
1328 // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
1333 int result = DoTest();
1334 return result >= 0 ? result : 0;
1335 }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
1336 set(CMAKE_REQUIRED_LIBRARIES)
1339 if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
1340 set(HAVE_COREFOUNDATION 1)
1341 set(HAVE__NSGETENVIRON 1)
1342 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 1)
1343 set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
1344 set(PAL_PT_ATTACH PT_ATTACH)
1345 set(PAL_PT_DETACH PT_DETACH)
1346 set(PAL_PT_READ_D PT_READ_D)
1347 set(PAL_PT_WRITE_D PT_WRITE_D)
1348 set(HAS_FTRUNCATE_LENGTH_ISSUE 1)
1349 set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
1351 elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
1352 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1353 set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
1354 set(PAL_PT_ATTACH PT_ATTACH)
1355 set(PAL_PT_DETACH PT_DETACH)
1356 set(PAL_PT_READ_D PT_READ_D)
1357 set(PAL_PT_WRITE_D PT_WRITE_D)
1358 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1359 set(BSD_REGS_STYLE "((reg).r_##rr)")
1360 set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
1361 elseif(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
1362 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1363 set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
1364 set(PAL_PT_ATTACH PT_ATTACH)
1365 set(PAL_PT_DETACH PT_DETACH)
1366 set(PAL_PT_READ_D PT_READ_D)
1367 set(PAL_PT_WRITE_D PT_WRITE_D)
1368 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1369 set(BSD_REGS_STYLE "((reg).regs[_REG_##RR])")
1370 set(HAVE_SCHED_OTHER_ASSIGNABLE 0)
1372 elseif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
1373 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1374 set(PAL_PTRACE "ptrace((cmd), (pid), (caddr_t)(addr), (data))")
1375 set(PAL_PT_ATTACH PT_ATTACH)
1376 set(PAL_PT_DETACH PT_DETACH)
1377 set(PAL_PT_READ_D PT_READ_D)
1378 set(PAL_PT_WRITE_D PT_WRITE_D)
1379 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1380 else() # Anything else is Linux
1381 if(NOT HAVE_LTTNG_TRACEPOINT_H AND FEATURE_EVENT_TRACE)
1382 unset(HAVE_LTTNG_TRACEPOINT_H CACHE)
1383 message(FATAL_ERROR "Cannot find liblttng-ust-dev. Try installing liblttng-ust-dev (or the appropriate packages for your platform)")
1385 set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
1386 set(PAL_PTRACE "ptrace((cmd), (pid), (void*)(addr), (data))")
1387 set(PAL_PT_ATTACH PTRACE_ATTACH)
1388 set(PAL_PT_DETACH PTRACE_DETACH)
1389 set(PAL_PT_READ_D PTRACE_PEEKDATA)
1390 set(PAL_PT_WRITE_D PTRACE_POKEDATA)
1391 set(HAS_FTRUNCATE_LENGTH_ISSUE 0)
1392 set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
1393 endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
1395 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)