066bd52097697643ad5d731349e1b0296cd7fe5b
[platform/upstream/coreclr.git] / src / pal / src / configure.cmake
1 include(CheckCXXSourceCompiles)
2 include(CheckCXXSourceRuns)
3 include(CheckCXXSymbolExists)
4 include(CheckFunctionExists)
5 include(CheckIncludeFiles)
6 include(CheckStructHasMember)
7 include(CheckTypeSize)
8 include(CheckLibraryExists)
9
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)
14 endif()
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")
17 endif()
18
19 if(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ANDROID)
20   set(CMAKE_RT_LIBS rt)
21 elseif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
22   set(CMAKE_RT_LIBS rt)
23 else()
24   set(CMAKE_RT_LIBS "")
25 endif()
26
27 list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64)
28
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)
48
49 if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
50   check_include_files("libintl.h" HAVE_LIBINTL_H)
51 endif()
52
53 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
54
55 check_cxx_source_compiles("
56 #include <sys/mman.h>
57 int main()
58 {
59   return VM_FLAGS_SUPERPAGE_SIZE_ANY;
60 }
61 " HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY)
62
63 check_cxx_source_compiles("
64 #include <sys/mman.h>
65 int main()
66 {
67   return MAP_HUGETLB;
68 }
69 " HAVE_MAP_HUGETLB)
70
71 check_cxx_source_compiles("
72 #include <lttng/tracepoint.h>
73 int main(int argc, char **argv) {
74   return 0;
75 }" HAVE_LTTNG_TRACEPOINT_H)
76
77 set(CMAKE_REQUIRED_LIBRARIES)
78
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)
82
83 check_function_exists(kqueue HAVE_KQUEUE)
84
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)
88
89 if (HAVE_LIBPTHREAD)
90   set(PTHREAD_LIBRARY pthread)
91 elseif (HAVE_PTHREAD_IN_LIBC)
92   set(PTHREAD_LIBRARY c)
93 endif()
94
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)
106
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)
134
135 check_cxx_source_compiles("
136 #include <pthread_np.h>
137 int main(int argc, char **argv) {
138   cpuset_t cpuSet;
139
140   return 0;
141 }" HAVE_CPUSET_T)
142
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)
151
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)
170
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)
177
178 check_cxx_source_runs("
179 #include <sys/param.h>
180 #include <stdlib.h>
181
182 int main(void) {
183   char *path;
184 #ifdef PATH_MAX
185   char resolvedPath[PATH_MAX];
186 #elif defined(MAXPATHLEN)
187   char resolvedPath[MAXPATHLEN];
188 #else
189   char resolvedPath[1024];
190 #endif
191   path = realpath(\"a_nonexistent_file\", resolvedPath);
192   if (path == NULL) {
193     exit(1);
194   }
195   exit(0);
196 }" REALPATH_SUPPORTS_NONEXISTENT_FILES)
197 check_cxx_source_runs("
198 #include <stdio.h>
199 #include <stdlib.h>
200 int main(void)
201 {
202   long long n = 0;
203   sscanf(\"5000000000\", \"%qu\", &n);
204   exit (n != 5000000000);
205   }" SSCANF_SUPPORT_ll)
206 check_cxx_source_runs("
207 #include <stdio.h>
208 #include <stdlib.h>
209
210 int main()
211 {
212   int ret;
213   float f = 0;
214   char * strin = \"12.34e\";
215
216   ret = sscanf (strin, \"%e\", &f);
217   if (ret <= 0)
218     exit (0);
219   exit(1);
220 }" SSCANF_CANNOT_HANDLE_MISSING_EXPONENT)
221 check_cxx_source_runs("
222 #include <stdio.h>
223 #include <stdlib.h>
224
225 int main(void) {
226   char buf[256] = { 0 };
227   snprintf(buf, 0x7fffffff, \"%#x\", 0x12345678);
228   if (buf[0] == 0x0) {
229     exit(1);
230   }
231   exit(0);
232 }" HAVE_LARGE_SNPRINTF_SUPPORT)
233 check_cxx_source_runs("
234 #include <stdio.h>
235 #include <stdlib.h>
236 #include <fcntl.h>
237 #include <string.h>
238 #include <sys/stat.h>
239 #include <sys/types.h>
240 #include <sys/time.h>
241 #include <unistd.h>
242
243 int main(void) {
244     int fd, numFDs;
245     fd_set readFDs, writeFDs, exceptFDs;
246     struct timeval time = { 0 };
247     char * filename = NULL;
248
249     filename = (char *)malloc(L_tmpnam * sizeof(char)); /* ok to leak this at exit */
250     if (NULL == filename) {
251       exit(0);
252     }
253
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.
257     */
258     if (NULL == tmpnam(filename)) {
259       exit(0);
260     }
261     if (mkfifo(filename, S_IRWXU) != 0) {
262       if (unlink(filename) != 0) {
263         exit(0);
264       }
265       if (mkfifo(filename, S_IRWXU) != 0) {
266         exit(0);
267       }
268     }
269     fd = open(filename, O_RDWR | O_NONBLOCK);
270     if (fd == -1) {
271       exit(0);
272     }
273
274     FD_ZERO(&readFDs);
275     FD_ZERO(&writeFDs);
276     FD_ZERO(&exceptFDs);
277     FD_SET(fd, &readFDs);
278     numFDs = select(fd + 1, &readFDs, &writeFDs, &exceptFDs, &time);
279
280     close(fd);
281     unlink(filename);
282
283     /* numFDs is zero if select() works correctly */
284     exit(numFD==0);
285 }" HAVE_BROKEN_FIFO_SELECT)
286 check_cxx_source_runs("
287 #include <stdio.h>
288 #include <stdlib.h>
289 #include <unistd.h>
290 #include <fcntl.h>
291 #include <string.h>
292 #include <errno.h>
293 #include <sys/types.h>
294 #include <sys/event.h>
295 #include <sys/time.h>
296 #include <sys/stat.h>
297
298 int main(void)
299 {
300   int ikq;
301   int iRet;
302   int fd;
303   struct kevent ke, keChangeList;
304   struct timespec ts = { 0, 0 };
305
306   char * filename = NULL;
307
308   filename = (char *)malloc(L_tmpnam * sizeof(char)); /* ok to leak this at exit */
309   if (NULL == filename)
310   {
311     exit(1);
312   }
313
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.
317   */
318   if (NULL == tmpnam(filename)) {
319     exit(0);
320   }
321   if (mkfifo(filename, S_IRWXU) != 0) {
322     if (unlink(filename) != 0) {
323       exit(0);
324     }
325     if (mkfifo(filename, S_IRWXU) != 0) {
326       exit(0);
327     }
328   }
329   fd = open(filename, O_RDWR | O_NONBLOCK);
330   if (fd == -1) {
331     exit(0);
332   }
333
334   EV_SET(&keChangeList, fd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL);
335   ikq = kqueue();
336   iRet = kevent(ikq, &keChangeList, 1, &ke, 1, &ts);
337
338   close(fd);
339   unlink(filename);
340
341   /* iRet is zero is kevent() works correctly */
342   return(iRet==0);
343 }" HAVE_BROKEN_FIFO_KEVENT)
344 set(CMAKE_REQUIRED_LIBRARIES pthread)
345 check_cxx_source_runs("
346 #include <stdio.h>
347 #include <stdlib.h>
348 #include <pthread.h>
349 #include <sched.h>
350
351 int main(void)
352 {
353   int policy;
354   struct sched_param schedParam;
355   int max_priority;
356   int min_priority;
357
358   if (0 != pthread_getschedparam(pthread_self(), &policy, &schedParam))
359   {
360     exit(1);
361   }
362
363   max_priority = sched_get_priority_max(policy);
364   min_priority = sched_get_priority_min(policy);
365
366   exit(-1 == max_priority || -1 == min_priority);
367 }" HAVE_SCHED_GET_PRIORITY)
368 set(CMAKE_REQUIRED_LIBRARIES pthread)
369 check_cxx_source_runs("
370 #include <stdlib.h>
371 #include <sched.h>
372
373 int main(void)
374 {
375   if (sched_getcpu() >= 0)
376   {
377     exit(0);
378   }
379   exit(1);
380 }" HAVE_SCHED_GETCPU)
381 set(CMAKE_REQUIRED_LIBRARIES)
382 check_cxx_source_runs("
383 #include <stdlib.h>
384 #include <time.h>
385 #include <sys/time.h>
386
387 int main()
388 {
389   int ret;
390   struct timeval tv;
391   ret = gettimeofday(&tv, NULL);
392
393   exit(ret);
394 }" HAVE_WORKING_GETTIMEOFDAY)
395
396 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
397 check_cxx_source_runs("
398 #include <stdlib.h>
399 #include <time.h>
400 #include <sys/time.h>
401
402 int main()
403 {
404   int ret;
405   struct timespec ts;
406   ret = clock_gettime(CLOCK_REALTIME, &ts);
407
408   exit(ret);
409 }" HAVE_WORKING_CLOCK_GETTIME)
410 set(CMAKE_REQUIRED_LIBRARIES)
411
412 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
413 check_cxx_source_runs("
414 #include <stdlib.h>
415 #include <time.h>
416 #include <sys/time.h>
417
418 int main()
419 {
420   int ret;
421   struct timespec ts;
422   ret = clock_gettime(CLOCK_MONOTONIC, &ts);
423
424   exit(ret);
425 }" HAVE_CLOCK_MONOTONIC)
426 set(CMAKE_REQUIRED_LIBRARIES)
427
428 check_library_exists(${PTHREAD_LIBRARY} pthread_condattr_setclock "" HAVE_PTHREAD_CONDATTR_SETCLOCK)
429
430 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
431 check_cxx_source_runs("
432 #include <stdlib.h>
433 #include <time.h>
434 #include <sys/time.h>
435
436 int main()
437 {
438   int ret;
439   struct timespec ts;
440   ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
441
442   exit(ret);
443 }" HAVE_CLOCK_MONOTONIC_COARSE)
444 set(CMAKE_REQUIRED_LIBRARIES)
445
446 check_cxx_source_runs("
447 #include <stdlib.h>
448 #include <mach/mach_time.h>
449
450 int main()
451 {
452   int ret;
453   mach_timebase_info_data_t timebaseInfo;
454   ret = mach_timebase_info(&timebaseInfo);
455   mach_absolute_time();
456   exit(ret);
457 }" HAVE_MACH_ABSOLUTE_TIME)
458
459 set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS})
460 check_cxx_source_runs("
461 #include <stdlib.h>
462 #include <time.h>
463 #include <sys/time.h>
464
465 int main()
466 {
467   int ret;
468   struct timespec ts;
469   ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
470
471   exit(ret);
472 }" HAVE_CLOCK_THREAD_CPUTIME)
473 set(CMAKE_REQUIRED_LIBRARIES)
474
475 check_cxx_source_runs("
476 #include <stdlib.h>
477 #include <sys/types.h>
478 #include <sys/mman.h>
479 #include <fcntl.h>
480
481 int main(void) {
482   int devzero;
483   void *retval;
484
485   devzero = open(\"/dev/zero\", O_RDWR);
486   if (-1 == devzero) {
487     exit(1);
488   }
489   retval = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, devzero, 0);
490   if (retval == (void *)-1) {
491     exit(1);
492   }
493   exit(0);
494 }" HAVE_MMAP_DEV_ZERO)
495 check_cxx_source_runs("
496 #include <sys/types.h>
497 #include <sys/mman.h>
498 #include <signal.h>
499 #include <stdlib.h>
500 #include <unistd.h>
501
502 #ifndef MAP_ANON
503 #define MAP_ANON MAP_ANONYMOUS
504 #endif
505
506 void *handle_signal(int signal) {
507   /* If we reach this, we've crashed due to mmap honoring
508   PROT_NONE. */
509   _exit(1);
510 }
511
512 int main(void) {
513   int *ptr;
514   struct sigaction action;
515
516   ptr = (int *) mmap(NULL, getpagesize(), PROT_NONE,
517                      MAP_ANON | MAP_PRIVATE, -1, 0);
518   if (ptr == (int *) MAP_FAILED) {
519     exit(0);
520   }
521   action.sa_handler = &handle_signal;
522   action.sa_flags = 0;
523   sigemptyset(&action.sa_mask);
524   if (sigaction(SIGBUS, &action, NULL) != 0) {
525     exit(0);
526   }
527   if (sigaction(SIGSEGV, &action, NULL) != 0) {
528     exit(0);
529   }
530   /* This will drop us into the signal handler if PROT_NONE
531      is honored. */
532   *ptr = 123;
533   exit(0);
534 }" MMAP_ANON_IGNORES_PROTECTION)
535 check_cxx_source_runs("
536 #include <stdio.h>
537 #include <unistd.h>
538 #include <stdlib.h>
539 #include <string.h>
540 #include <sys/types.h>
541 #include <sys/mman.h>
542
543 #define MEM_SIZE 1024
544
545 int main(void)
546 {
547   char * fname;
548   int fd;
549   int ret;
550   void * pAddr0, * pAddr1;
551
552   fname = (char *)malloc(MEM_SIZE);
553   if (!fname)
554     exit(1);
555   strcpy(fname, \"/tmp/name/multiplemaptestXXXXXX\");
556
557   fd = mkstemp(fname);
558   if (fd < 0)
559     exit(1);
560
561   ret = write (fd, (void *)fname, MEM_SIZE);
562   if (ret < 0)
563     exit(1);
564
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);
567
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)
575     ret = 1;
576   else
577     ret = 0;
578
579   if (pAddr0)
580     munmap (pAddr0, MEM_SIZE);
581   if (pAddr1)
582     munmap (pAddr1, MEM_SIZE);
583   close(fd);
584   unlink(fname);
585   free(fname);
586
587   exit(ret != 1);
588 }" ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS)
589 set(CMAKE_REQUIRED_LIBRARIES pthread)
590 check_cxx_source_runs("
591 #include <errno.h>
592 #include <pthread.h>
593 #include <stdlib.h>
594
595 void *start_routine(void *param) { return NULL; }
596
597 int main() {
598   int result;
599   pthread_t tid;
600
601   errno = 0;
602   result = pthread_create(&tid, NULL, start_routine, NULL);
603   if (result != 0) {
604     exit(1);
605   }
606   if (errno != 0) {
607     exit(0);
608   }
609   exit(1);
610 }" PTHREAD_CREATE_MODIFIES_ERRNO)
611 set(CMAKE_REQUIRED_LIBRARIES)
612 set(CMAKE_REQUIRED_LIBRARIES pthread)
613 check_cxx_source_runs("
614 #include <errno.h>
615 #include <semaphore.h>
616 #include <stdlib.h>
617
618 int main() {
619   int result;
620   sem_t sema;
621
622   errno = 50;
623   result = sem_init(&sema, 0, 0);
624   if (result != 0)
625   {
626     exit(1);
627   }
628   if (errno != 50)
629   {
630     exit(0);
631   }
632   exit(1);
633 }" SEM_INIT_MODIFIES_ERRNO)
634 set(CMAKE_REQUIRED_LIBRARIES)
635 check_cxx_source_runs("
636 #include <fcntl.h>
637 #include <stdlib.h>
638 #include <stdio.h>
639 #include <unistd.h>
640
641 int main(void) {
642   int fd;
643 #ifdef PATH_MAX
644   char path[PATH_MAX];
645 #elif defined(MAXPATHLEN)
646   char path[MAXPATHLEN];
647 #else
648   char path[1024];
649 #endif
650
651   sprintf(path, \"/proc/%u/ctl\", getpid());
652   fd = open(path, O_WRONLY);
653   if (fd == -1) {
654     exit(1);
655   }
656   exit(0);
657 }" HAVE_PROCFS_CTL)
658 set(CMAKE_REQUIRED_LIBRARIES)
659 check_cxx_source_runs("
660 #include <fcntl.h>
661 #include <stdlib.h>
662 #include <stdio.h>
663 #include <unistd.h>
664
665 int main(void) {
666   int fd;
667 #ifdef PATH_MAX
668   char path[PATH_MAX];
669 #elif defined(MAXPATHLEN)
670   char path[MAXPATHLEN];
671 #else
672   char path[1024];
673 #endif
674
675   sprintf(path, \"/proc/%u/maps\", getpid());
676   fd = open(path, O_RDONLY);
677   if (fd == -1) {
678     exit(1);
679   }
680   exit(0);
681 }" HAVE_PROCFS_MAPS)
682 set(CMAKE_REQUIRED_LIBRARIES)
683 check_cxx_source_runs("
684 #include <fcntl.h>
685 #include <stdlib.h>
686 #include <stdio.h>
687 #include <unistd.h>
688
689 int main(void) {
690   int fd;
691 #ifdef PATH_MAX
692   char path[PATH_MAX];
693 #elif defined(MAXPATHLEN)
694   char path[MAXPATHLEN];
695 #else
696   char path[1024];
697 #endif
698
699   sprintf(path, \"/proc/%u/stat\", getpid());
700   fd = open(path, O_RDONLY);
701   if (fd == -1) {
702     exit(1);
703   }
704   exit(0);
705 }" HAVE_PROCFS_STAT)
706 set(CMAKE_REQUIRED_LIBRARIES)
707 check_cxx_source_runs("
708 #include <fcntl.h>
709 #include <stdlib.h>
710 #include <stdio.h>
711 #include <unistd.h>
712
713 int main(void) {
714   int fd;
715 #ifdef PATH_MAX
716   char path[PATH_MAX];
717 #elif defined(MAXPATHLEN)
718   char path[MAXPATHLEN];
719 #else
720   char path[1024];
721 #endif
722
723   sprintf(path, \"/proc/%u/status\", getpid());
724   fd = open(path, O_RDONLY);
725   if (fd == -1) {
726     exit(1);
727   }
728   exit(0);
729 }" HAVE_PROCFS_STATUS)
730 set(CMAKE_REQUIRED_LIBRARIES m)
731 check_cxx_source_runs("
732 #include <math.h>
733 #include <stdlib.h>
734
735 int main(void) {
736   if (!isnan(acos(10))) {
737     exit(1);
738   }
739   exit(0);
740 }" HAVE_COMPATIBLE_ACOS)
741 set(CMAKE_REQUIRED_LIBRARIES)
742 set(CMAKE_REQUIRED_LIBRARIES m)
743 check_cxx_source_runs("
744 #include <math.h>
745 #include <stdlib.h>
746
747 int main(void) {
748   if (!isnan(asin(10))) {
749     exit(1);
750   }
751   exit(0);
752 }" HAVE_COMPATIBLE_ASIN)
753 set(CMAKE_REQUIRED_LIBRARIES)
754 set(CMAKE_REQUIRED_LIBRARIES m)
755 check_cxx_source_runs("
756 #include <math.h>
757 #include <stdlib.h>
758
759 int main(void) {
760   double infinity = 1.0 / 0.0;
761   if (pow(1.0, infinity) != 1.0 || pow(1.0, -infinity) != 1.0) {
762     exit(1);
763   }
764   if (pow(-1.0, infinity) != 1.0 || pow(-1.0, -infinity) != 1.0) {
765     exit(1);
766   }
767   if (pow(0.0, infinity) != 0.0) {
768     exit(1);
769   }
770   if (pow(0.0, -infinity) != infinity) {
771     exit(1);
772   }
773   if (pow(-1.1, infinity) != infinity || pow(1.1, infinity) != infinity) {
774     exit(1);
775   }
776   if (pow(-1.1, -infinity) != 0.0 || pow(1.1, -infinity) != 0.0) {
777     exit(1);
778   }
779   if (pow(-0.0, -1) != -infinity) {
780     exit(1);
781   }
782   if (pow(0.0, -1) != infinity) {
783     exit(1);
784   }
785   exit(0);
786 }" HAVE_COMPATIBLE_POW)
787 set(CMAKE_REQUIRED_LIBRARIES)
788 set(CMAKE_REQUIRED_LIBRARIES m)
789 check_cxx_source_runs("
790 #include <math.h>
791 #include <stdlib.h>
792
793 int main(int argc, char **argv) {
794   double result;
795
796   result = pow(-3.2e-10, -5e14 + 1);
797   if (result != -1.0 / 0.0) {
798     exit(1);
799   }
800   exit(0);
801 }" HAVE_VALID_NEGATIVE_INF_POW)
802 set(CMAKE_REQUIRED_LIBRARIES)
803 set(CMAKE_REQUIRED_LIBRARIES m)
804 check_cxx_source_runs("
805 #include <math.h>
806 #include <stdlib.h>
807
808 int main(int argc, char **argv) {
809     double result;
810
811     result = pow(-3.5, 3e100);
812     if (result != 1.0 / 0.0) {
813         exit(1);
814     }
815     exit(0);
816 }" HAVE_VALID_POSITIVE_INF_POW)
817 set(CMAKE_REQUIRED_LIBRARIES)
818 set(CMAKE_REQUIRED_LIBRARIES m)
819 check_cxx_source_runs("
820 #include <math.h>
821 #include <stdlib.h>
822
823 int main(void) {
824   double pi = 3.14159265358979323846;
825   double result;
826
827   result = atan2(0.0, -0.0);
828   if (fabs(pi - result) > 0.0000001) {
829     exit(1);
830   }
831
832   result = atan2(-0.0, -0.0);
833   if (fabs(-pi - result) > 0.0000001) {
834     exit(1);
835   }
836
837   result = atan2 (-0.0, 0.0);
838   if (result != 0.0 || copysign (1.0, result) > 0) {
839     exit(1);
840   }
841
842   result = atan2 (0.0, 0.0);
843   if (result != 0.0 || copysign (1.0, result) < 0) {
844     exit(1);
845   }
846
847   exit (0);
848 }" HAVE_COMPATIBLE_ATAN2)
849 set(CMAKE_REQUIRED_LIBRARIES)
850 set(CMAKE_REQUIRED_LIBRARIES m)
851 check_cxx_source_runs("
852 #include <math.h>
853 #include <stdlib.h>
854
855 int main(void) {
856   double d = exp(1.0), e = M_E;
857
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.
862   */
863
864   if (memcmp (&d, &e, sizeof (double)) == 0) {
865     exit(0);
866   }
867   exit(1);
868 }" HAVE_COMPATIBLE_EXP)
869 set(CMAKE_REQUIRED_LIBRARIES)
870 set(CMAKE_REQUIRED_LIBRARIES m)
871 check_cxx_source_runs("
872 #include <math.h>
873 #include <stdlib.h>
874
875 int main(void) {
876   if (FP_ILOGB0 != -2147483648) {
877     exit(1);
878   }
879
880   exit(0);
881 }" HAVE_COMPATIBLE_ILOGB0)
882 set(CMAKE_REQUIRED_LIBRARIES)
883 set(CMAKE_REQUIRED_LIBRARIES m)
884 check_cxx_source_runs("
885 #include <math.h>
886 #include <stdlib.h>
887
888 int main(void) {
889   if (FP_ILOGBNAN != 2147483647) {
890     exit(1);
891   }
892
893   exit(0);
894 }" HAVE_COMPATIBLE_ILOGBNAN)
895 set(CMAKE_REQUIRED_LIBRARIES)
896 set(CMAKE_REQUIRED_LIBRARIES m)
897 check_cxx_source_runs("
898 #include <math.h>
899 #include <stdlib.h>
900
901 int main(void) {
902   if (!isnan(log(-10000))) {
903     exit(1);
904   }
905   exit(0);
906 }" HAVE_COMPATIBLE_LOG)
907 set(CMAKE_REQUIRED_LIBRARIES)
908 set(CMAKE_REQUIRED_LIBRARIES m)
909 check_cxx_source_runs("
910 #include <math.h>
911 #include <stdlib.h>
912
913 int main(void) {
914   if (!isnan(log10(-10000))) {
915     exit(1);
916   }
917   exit(0);
918 }" HAVE_COMPATIBLE_LOG10)
919 set(CMAKE_REQUIRED_LIBRARIES)
920 check_cxx_source_runs("
921 #include <stdio.h>
922 #include <stdlib.h>
923 #include <unistd.h>
924
925 int main(void)
926 {
927   char* szFileName;
928   FILE* pFile = NULL;
929   int ret = 1;
930
931   szFileName = tempnam(\".\", \"tmp\");
932
933   /* open the file write-only */
934   pFile = fopen(szFileName, \"a\");
935   if (pFile == NULL)
936   {
937     exit(0);
938   }
939   if (ungetc('A', pFile) != EOF)
940   {
941     ret = 0;
942   }
943   unlink(szFileName);
944   exit(ret);
945 }" UNGETC_NOT_RETURN_EOF)
946
947 set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARY})
948 check_cxx_source_runs("
949 #include <stdlib.h>
950 #include <errno.h>
951 #include <semaphore.h>
952
953 int main() {
954   sem_t sema;
955   if (sem_init(&sema, 0, 0) == -1){
956     exit(1);
957   }
958   exit(0);
959 }" HAS_POSIX_SEMAPHORES)
960 set(CMAKE_REQUIRED_LIBRARIES)
961 check_cxx_source_runs("
962 #include <sys/types.h>
963 #include <pwd.h>
964 #include <errno.h>
965 #include <unistd.h>
966 #include <stdlib.h>
967
968 int main(void)
969 {
970   struct passwd sPasswd;
971   struct passwd *pPasswd;
972   char buf[1];
973   int bufLen = sizeof(buf)/sizeof(buf[0]);
974   int euid = geteuid();
975   int ret = 0;
976
977   errno = 0; // clear errno
978   ret = getpwuid_r(euid, &sPasswd, buf, bufLen, &pPasswd);
979   if (0 != ret)
980   {
981     if (ERANGE == errno)
982     {
983       return 0;
984     }
985   }
986
987   return 1; // assume errno is NOT set for all other cases
988 }" GETPWUID_R_SETS_ERRNO)
989 check_cxx_source_runs("
990 #include <stdio.h>
991 #include <stdlib.h>
992
993 int main()
994 {
995   FILE *fp = NULL;
996   char *fileName = \"/dev/zero\";
997   char buf[10];
998
999   /*
1000    * Open the file in append mode and try to read some text.
1001    * And, make sure ferror() is set.
1002    */
1003   fp = fopen (fileName, \"a\");
1004   if ( (NULL == fp) ||
1005        (fread (buf, sizeof(buf), 1, fp) > 0) ||
1006        (!ferror(fp))
1007      )
1008   {
1009     return 0;
1010   }
1011
1012   /*
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().
1016    */
1017   if ( fclose(fp) != 0 )
1018   {
1019     return 0;
1020   }
1021
1022   return 1;
1023 }" FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL)
1024
1025 set(SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING 1)
1026 set(ERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS 1)
1027
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)
1030 endif()
1031
1032 set(CMAKE_REQUIRED_FLAGS "-c -Werror=implicit-function-declaration")
1033
1034 check_c_source_compiles("
1035 #include <libunwind.h>
1036 #include <ucontext.h>
1037 int main(int argc, char **argv)
1038 {
1039         unw_context_t libUnwindContext;
1040         ucontext_t uContext;
1041         libUnwindContext = uContext;
1042         return 0;
1043 }" UNWIND_CONTEXT_IS_UCONTEXT_T)
1044
1045 check_c_source_compiles("
1046 #include <libunwind.h>
1047
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);
1053
1054   return 0;
1055 }" HAVE_UNW_GET_SAVE_LOC)
1056
1057 check_c_source_compiles("
1058 #include <libunwind.h>
1059
1060 int main(int argc, char **argv) {
1061   unw_addr_space_t as;
1062   unw_get_accessors(as);
1063
1064   return 0;
1065 }" HAVE_UNW_GET_ACCESSORS)
1066
1067 set(CMAKE_REQUIRED_FLAGS)
1068 if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
1069   list(REMOVE_AT CMAKE_REQUIRED_INCLUDES 0 1)
1070 endif()
1071
1072 check_cxx_source_compiles("
1073 #include <sys/param.h>
1074 #include <sys/sysctl.h>
1075 #include <vm/vm_param.h>
1076
1077 int main(int argc, char **argv)
1078 {
1079     struct xswdev xsw;
1080
1081     return 0;
1082 }" HAVE_XSWDEV)
1083
1084 check_cxx_source_compiles("
1085 #include <sys/param.h>
1086 #include <sys/sysctl.h>
1087
1088 int main(int argc, char **argv)
1089 {
1090     struct xsw_usage xsu;
1091
1092     return 0;
1093 }" HAVE_XSW_USAGE)
1094
1095 check_cxx_source_compiles("
1096 #include <signal.h>
1097
1098 int main(int argc, char **argv)
1099 {
1100     struct _xstate xstate;
1101     struct _fpx_sw_bytes bytes;
1102     return 0;
1103 }" HAVE_PUBLIC_XSTATE_STRUCT)
1104
1105 check_cxx_source_compiles("
1106 #include <sys/prctl.h>
1107
1108 int main(int argc, char **argv)
1109 {
1110     int flag = (int)PR_SET_PTRACER;
1111     return 0;
1112 }" HAVE_PR_SET_PTRACER)
1113
1114 set(CMAKE_REQUIRED_LIBRARIES pthread)
1115 check_cxx_source_compiles("
1116 #include <errno.h>
1117 #include <pthread.h>
1118 #include <time.h>
1119
1120 int main()
1121 {
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);
1127
1128     pthread_mutex_t mutex;
1129     pthread_mutex_init(&mutex, &mutexAttributes);
1130
1131     pthread_mutexattr_destroy(&mutexAttributes);
1132
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);
1138
1139     pthread_mutex_destroy(&mutex);
1140
1141     int error = EOWNERDEAD;
1142     error = ENOTRECOVERABLE;
1143     error = ETIMEDOUT;
1144     error = 0;
1145     return error;
1146 }" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
1147 set(CMAKE_REQUIRED_LIBRARIES)
1148
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.
1156   
1157   #include <sys/mman.h>
1158   #include <sys/time.h>
1159   
1160   #include <errno.h>
1161   #include <pthread.h>
1162   #include <stdio.h>
1163   #include <unistd.h>
1164   
1165   #include <new>
1166   using namespace std;
1167   
1168   struct Shm
1169   {
1170       pthread_mutex_t syncMutex;
1171       pthread_cond_t syncCondition;
1172       pthread_mutex_t robustMutex;
1173       int conditionValue;
1174   
1175       Shm() : conditionValue(0)
1176       {
1177       }
1178   } *shm;
1179   
1180   int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
1181   {
1182       int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
1183       if (getTimeResult != 0)
1184       {
1185           struct timeval tv;
1186           getTimeResult = gettimeofday(&tv, NULL);
1187           if (getTimeResult != 0)
1188               return 1;
1189           timeoutTimeRef->tv_sec = tv.tv_sec;
1190           timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
1191       }
1192       timeoutTimeRef->tv_sec += 30;
1193       return 0;
1194   }
1195   
1196   int WaitForConditionValue(int desiredConditionValue)
1197   {
1198       struct timespec timeoutTime;
1199       if (GetFailTimeoutTime(&timeoutTime) != 0)
1200           return 1;
1201       if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1202           return 1;
1203   
1204       if (shm->conditionValue != desiredConditionValue)
1205       {
1206           if (GetFailTimeoutTime(&timeoutTime) != 0)
1207               return 1;
1208           if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
1209               return 1;
1210           if (shm->conditionValue != desiredConditionValue)
1211               return 1;
1212       }
1213   
1214       if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1215           return 1;
1216       return 0;
1217   }
1218   
1219   int SetConditionValue(int newConditionValue)
1220   {
1221       struct timespec timeoutTime;
1222       if (GetFailTimeoutTime(&timeoutTime) != 0)
1223           return 1;
1224       if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1225           return 1;
1226   
1227       shm->conditionValue = newConditionValue;
1228       if (pthread_cond_signal(&shm->syncCondition) != 0)
1229           return 1;
1230   
1231       if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1232           return 1;
1233       return 0;
1234   }
1235   
1236   void DoTest_Child();
1237   
1238   int DoTest()
1239   {
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)
1243           return 1;
1244       shm = new(shmBuffer) Shm;
1245   
1246       // Create sync mutex
1247       pthread_mutexattr_t syncMutexAttributes;
1248       if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
1249           return 1;
1250       if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1251           return 1;
1252       if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
1253           return 1;
1254       if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
1255           return 1;
1256   
1257       // Create sync condition
1258       pthread_condattr_t syncConditionAttributes;
1259       if (pthread_condattr_init(&syncConditionAttributes) != 0)
1260           return 1;
1261       if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
1262           return 1;
1263       if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
1264           return 1;
1265       if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
1266           return 1;
1267   
1268       // Create the robust mutex that will be tested
1269       pthread_mutexattr_t robustMutexAttributes;
1270       if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
1271           return 1;
1272       if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1273           return 1;
1274       if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
1275           return 1;
1276       if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
1277           return 1;
1278       if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
1279           return 1;
1280   
1281       // Start child test process
1282       int error = fork();
1283       if (error == -1)
1284           return 1;
1285       if (error == 0)
1286       {
1287           DoTest_Child();
1288           return -1;
1289       }
1290   
1291       // Wait for child to take a lock
1292       WaitForConditionValue(1);
1293   
1294       // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
1295       struct timespec timeoutTime;
1296       if (GetFailTimeoutTime(&timeoutTime) != 0)
1297           return 1;
1298       error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
1299       if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
1300           return 1;
1301       if (pthread_mutex_consistent(&shm->robustMutex) != 0)
1302           return 1;
1303   
1304       if (pthread_mutex_unlock(&shm->robustMutex) != 0)
1305           return 1;
1306       if (pthread_mutex_destroy(&shm->robustMutex) != 0)
1307           return 1;
1308       return 0;
1309   }
1310   
1311   void DoTest_Child()
1312   {
1313       // Lock the robust mutex
1314       struct timespec timeoutTime;
1315       if (GetFailTimeoutTime(&timeoutTime) != 0)
1316           return;
1317       if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
1318           return;
1319   
1320       // Notify parent that robust mutex is locked
1321       if (SetConditionValue(1) != 0)
1322           return;
1323   
1324       // Wait a short period to let the parent block on waiting for a lock
1325       sleep(1);
1326   
1327       // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
1328   }
1329   
1330   int main()
1331   {
1332       int result = DoTest();
1333       return result >= 0 ? result : 0;
1334   }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
1335   set(CMAKE_REQUIRED_LIBRARIES)
1336 endif()
1337
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)
1349
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)
1370
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)")
1383   endif()
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)
1393
1394 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)