Fix tmp dir in configure.cmake (#25003)
[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 #include <algorithm>
543
544 #define MEM_SIZE 1024
545 #define TEMP_FILE_TEMPLATE \"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/multiplemaptestXXXXXX\"
546 int main(void)
547 {
548   char * fname;
549   int fd;
550   int ret;
551   void * pAddr0, * pAddr1;
552
553   fname = (char *)malloc(std::max((size_t)MEM_SIZE, sizeof(TEMP_FILE_TEMPLATE)));
554   if (!fname)
555     exit(1);
556   strcpy(fname, TEMP_FILE_TEMPLATE);
557
558   fd = mkstemp(fname);
559   if (fd < 0)
560     exit(1);
561
562   ret = write (fd, (void *)fname, MEM_SIZE);
563   if (ret < 0)
564     exit(1);
565
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);
568
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)
576     ret = 1;
577   else
578     ret = 0;
579
580   if (pAddr0)
581     munmap (pAddr0, MEM_SIZE);
582   if (pAddr1)
583     munmap (pAddr1, MEM_SIZE);
584   close(fd);
585   unlink(fname);
586   free(fname);
587
588   exit(ret != 1);
589 }" ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS)
590 set(CMAKE_REQUIRED_LIBRARIES pthread)
591 check_cxx_source_runs("
592 #include <errno.h>
593 #include <pthread.h>
594 #include <stdlib.h>
595
596 void *start_routine(void *param) { return NULL; }
597
598 int main() {
599   int result;
600   pthread_t tid;
601
602   errno = 0;
603   result = pthread_create(&tid, NULL, start_routine, NULL);
604   if (result != 0) {
605     exit(1);
606   }
607   if (errno != 0) {
608     exit(0);
609   }
610   exit(1);
611 }" PTHREAD_CREATE_MODIFIES_ERRNO)
612 set(CMAKE_REQUIRED_LIBRARIES)
613 set(CMAKE_REQUIRED_LIBRARIES pthread)
614 check_cxx_source_runs("
615 #include <errno.h>
616 #include <semaphore.h>
617 #include <stdlib.h>
618
619 int main() {
620   int result;
621   sem_t sema;
622
623   errno = 50;
624   result = sem_init(&sema, 0, 0);
625   if (result != 0)
626   {
627     exit(1);
628   }
629   if (errno != 50)
630   {
631     exit(0);
632   }
633   exit(1);
634 }" SEM_INIT_MODIFIES_ERRNO)
635 set(CMAKE_REQUIRED_LIBRARIES)
636 check_cxx_source_runs("
637 #include <fcntl.h>
638 #include <stdlib.h>
639 #include <stdio.h>
640 #include <unistd.h>
641
642 int main(void) {
643   int fd;
644 #ifdef PATH_MAX
645   char path[PATH_MAX];
646 #elif defined(MAXPATHLEN)
647   char path[MAXPATHLEN];
648 #else
649   char path[1024];
650 #endif
651
652   sprintf(path, \"/proc/%u/ctl\", getpid());
653   fd = open(path, O_WRONLY);
654   if (fd == -1) {
655     exit(1);
656   }
657   exit(0);
658 }" HAVE_PROCFS_CTL)
659 set(CMAKE_REQUIRED_LIBRARIES)
660 check_cxx_source_runs("
661 #include <fcntl.h>
662 #include <stdlib.h>
663 #include <stdio.h>
664 #include <unistd.h>
665
666 int main(void) {
667   int fd;
668 #ifdef PATH_MAX
669   char path[PATH_MAX];
670 #elif defined(MAXPATHLEN)
671   char path[MAXPATHLEN];
672 #else
673   char path[1024];
674 #endif
675
676   sprintf(path, \"/proc/%u/maps\", getpid());
677   fd = open(path, O_RDONLY);
678   if (fd == -1) {
679     exit(1);
680   }
681   exit(0);
682 }" HAVE_PROCFS_MAPS)
683 set(CMAKE_REQUIRED_LIBRARIES)
684 check_cxx_source_runs("
685 #include <fcntl.h>
686 #include <stdlib.h>
687 #include <stdio.h>
688 #include <unistd.h>
689
690 int main(void) {
691   int fd;
692 #ifdef PATH_MAX
693   char path[PATH_MAX];
694 #elif defined(MAXPATHLEN)
695   char path[MAXPATHLEN];
696 #else
697   char path[1024];
698 #endif
699
700   sprintf(path, \"/proc/%u/stat\", getpid());
701   fd = open(path, O_RDONLY);
702   if (fd == -1) {
703     exit(1);
704   }
705   exit(0);
706 }" HAVE_PROCFS_STAT)
707 set(CMAKE_REQUIRED_LIBRARIES)
708 check_cxx_source_runs("
709 #include <fcntl.h>
710 #include <stdlib.h>
711 #include <stdio.h>
712 #include <unistd.h>
713
714 int main(void) {
715   int fd;
716 #ifdef PATH_MAX
717   char path[PATH_MAX];
718 #elif defined(MAXPATHLEN)
719   char path[MAXPATHLEN];
720 #else
721   char path[1024];
722 #endif
723
724   sprintf(path, \"/proc/%u/status\", getpid());
725   fd = open(path, O_RDONLY);
726   if (fd == -1) {
727     exit(1);
728   }
729   exit(0);
730 }" HAVE_PROCFS_STATUS)
731 set(CMAKE_REQUIRED_LIBRARIES m)
732 check_cxx_source_runs("
733 #include <math.h>
734 #include <stdlib.h>
735
736 int main(void) {
737   if (!isnan(acos(10))) {
738     exit(1);
739   }
740   exit(0);
741 }" HAVE_COMPATIBLE_ACOS)
742 set(CMAKE_REQUIRED_LIBRARIES)
743 set(CMAKE_REQUIRED_LIBRARIES m)
744 check_cxx_source_runs("
745 #include <math.h>
746 #include <stdlib.h>
747
748 int main(void) {
749   if (!isnan(asin(10))) {
750     exit(1);
751   }
752   exit(0);
753 }" HAVE_COMPATIBLE_ASIN)
754 set(CMAKE_REQUIRED_LIBRARIES)
755 set(CMAKE_REQUIRED_LIBRARIES m)
756 check_cxx_source_runs("
757 #include <math.h>
758 #include <stdlib.h>
759
760 int main(void) {
761   double infinity = 1.0 / 0.0;
762   if (pow(1.0, infinity) != 1.0 || pow(1.0, -infinity) != 1.0) {
763     exit(1);
764   }
765   if (pow(-1.0, infinity) != 1.0 || pow(-1.0, -infinity) != 1.0) {
766     exit(1);
767   }
768   if (pow(0.0, infinity) != 0.0) {
769     exit(1);
770   }
771   if (pow(0.0, -infinity) != infinity) {
772     exit(1);
773   }
774   if (pow(-1.1, infinity) != infinity || pow(1.1, infinity) != infinity) {
775     exit(1);
776   }
777   if (pow(-1.1, -infinity) != 0.0 || pow(1.1, -infinity) != 0.0) {
778     exit(1);
779   }
780   if (pow(-0.0, -1) != -infinity) {
781     exit(1);
782   }
783   if (pow(0.0, -1) != infinity) {
784     exit(1);
785   }
786   exit(0);
787 }" HAVE_COMPATIBLE_POW)
788 set(CMAKE_REQUIRED_LIBRARIES)
789 set(CMAKE_REQUIRED_LIBRARIES m)
790 check_cxx_source_runs("
791 #include <math.h>
792 #include <stdlib.h>
793
794 int main(int argc, char **argv) {
795   double result;
796
797   result = pow(-3.2e-10, -5e14 + 1);
798   if (result != -1.0 / 0.0) {
799     exit(1);
800   }
801   exit(0);
802 }" HAVE_VALID_NEGATIVE_INF_POW)
803 set(CMAKE_REQUIRED_LIBRARIES)
804 set(CMAKE_REQUIRED_LIBRARIES m)
805 check_cxx_source_runs("
806 #include <math.h>
807 #include <stdlib.h>
808
809 int main(int argc, char **argv) {
810     double result;
811
812     result = pow(-3.5, 3e100);
813     if (result != 1.0 / 0.0) {
814         exit(1);
815     }
816     exit(0);
817 }" HAVE_VALID_POSITIVE_INF_POW)
818 set(CMAKE_REQUIRED_LIBRARIES)
819 set(CMAKE_REQUIRED_LIBRARIES m)
820 check_cxx_source_runs("
821 #include <math.h>
822 #include <stdlib.h>
823
824 int main(void) {
825   double pi = 3.14159265358979323846;
826   double result;
827
828   result = atan2(0.0, -0.0);
829   if (fabs(pi - result) > 0.0000001) {
830     exit(1);
831   }
832
833   result = atan2(-0.0, -0.0);
834   if (fabs(-pi - result) > 0.0000001) {
835     exit(1);
836   }
837
838   result = atan2 (-0.0, 0.0);
839   if (result != 0.0 || copysign (1.0, result) > 0) {
840     exit(1);
841   }
842
843   result = atan2 (0.0, 0.0);
844   if (result != 0.0 || copysign (1.0, result) < 0) {
845     exit(1);
846   }
847
848   exit (0);
849 }" HAVE_COMPATIBLE_ATAN2)
850 set(CMAKE_REQUIRED_LIBRARIES)
851 set(CMAKE_REQUIRED_LIBRARIES m)
852 check_cxx_source_runs("
853 #include <math.h>
854 #include <stdlib.h>
855
856 int main(void) {
857   double d = exp(1.0), e = M_E;
858
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.
863   */
864
865   if (memcmp (&d, &e, sizeof (double)) == 0) {
866     exit(0);
867   }
868   exit(1);
869 }" HAVE_COMPATIBLE_EXP)
870 set(CMAKE_REQUIRED_LIBRARIES)
871 set(CMAKE_REQUIRED_LIBRARIES m)
872 check_cxx_source_runs("
873 #include <math.h>
874 #include <stdlib.h>
875
876 int main(void) {
877   if (FP_ILOGB0 != -2147483648) {
878     exit(1);
879   }
880
881   exit(0);
882 }" HAVE_COMPATIBLE_ILOGB0)
883 set(CMAKE_REQUIRED_LIBRARIES)
884 set(CMAKE_REQUIRED_LIBRARIES m)
885 check_cxx_source_runs("
886 #include <math.h>
887 #include <stdlib.h>
888
889 int main(void) {
890   if (FP_ILOGBNAN != 2147483647) {
891     exit(1);
892   }
893
894   exit(0);
895 }" HAVE_COMPATIBLE_ILOGBNAN)
896 set(CMAKE_REQUIRED_LIBRARIES)
897 set(CMAKE_REQUIRED_LIBRARIES m)
898 check_cxx_source_runs("
899 #include <math.h>
900 #include <stdlib.h>
901
902 int main(void) {
903   if (!isnan(log(-10000))) {
904     exit(1);
905   }
906   exit(0);
907 }" HAVE_COMPATIBLE_LOG)
908 set(CMAKE_REQUIRED_LIBRARIES)
909 set(CMAKE_REQUIRED_LIBRARIES m)
910 check_cxx_source_runs("
911 #include <math.h>
912 #include <stdlib.h>
913
914 int main(void) {
915   if (!isnan(log10(-10000))) {
916     exit(1);
917   }
918   exit(0);
919 }" HAVE_COMPATIBLE_LOG10)
920 set(CMAKE_REQUIRED_LIBRARIES)
921 check_cxx_source_runs("
922 #include <stdio.h>
923 #include <stdlib.h>
924 #include <unistd.h>
925
926 int main(void)
927 {
928   char* szFileName;
929   FILE* pFile = NULL;
930   int ret = 1;
931
932   szFileName = tempnam(\".\", \"tmp\");
933
934   /* open the file write-only */
935   pFile = fopen(szFileName, \"a\");
936   if (pFile == NULL)
937   {
938     exit(0);
939   }
940   if (ungetc('A', pFile) != EOF)
941   {
942     ret = 0;
943   }
944   unlink(szFileName);
945   exit(ret);
946 }" UNGETC_NOT_RETURN_EOF)
947
948 set(CMAKE_REQUIRED_LIBRARIES ${PTHREAD_LIBRARY})
949 check_cxx_source_runs("
950 #include <stdlib.h>
951 #include <errno.h>
952 #include <semaphore.h>
953
954 int main() {
955   sem_t sema;
956   if (sem_init(&sema, 0, 0) == -1){
957     exit(1);
958   }
959   exit(0);
960 }" HAS_POSIX_SEMAPHORES)
961 set(CMAKE_REQUIRED_LIBRARIES)
962 check_cxx_source_runs("
963 #include <sys/types.h>
964 #include <pwd.h>
965 #include <errno.h>
966 #include <unistd.h>
967 #include <stdlib.h>
968
969 int main(void)
970 {
971   struct passwd sPasswd;
972   struct passwd *pPasswd;
973   char buf[1];
974   int bufLen = sizeof(buf)/sizeof(buf[0]);
975   int euid = geteuid();
976   int ret = 0;
977
978   errno = 0; // clear errno
979   ret = getpwuid_r(euid, &sPasswd, buf, bufLen, &pPasswd);
980   if (0 != ret)
981   {
982     if (ERANGE == errno)
983     {
984       return 0;
985     }
986   }
987
988   return 1; // assume errno is NOT set for all other cases
989 }" GETPWUID_R_SETS_ERRNO)
990 check_cxx_source_runs("
991 #include <stdio.h>
992 #include <stdlib.h>
993
994 int main()
995 {
996   FILE *fp = NULL;
997   char *fileName = \"/dev/zero\";
998   char buf[10];
999
1000   /*
1001    * Open the file in append mode and try to read some text.
1002    * And, make sure ferror() is set.
1003    */
1004   fp = fopen (fileName, \"a\");
1005   if ( (NULL == fp) ||
1006        (fread (buf, sizeof(buf), 1, fp) > 0) ||
1007        (!ferror(fp))
1008      )
1009   {
1010     return 0;
1011   }
1012
1013   /*
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().
1017    */
1018   if ( fclose(fp) != 0 )
1019   {
1020     return 0;
1021   }
1022
1023   return 1;
1024 }" FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL)
1025
1026 set(SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING 1)
1027 set(ERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS 1)
1028
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)
1031 endif()
1032
1033 set(CMAKE_REQUIRED_FLAGS "-c -Werror=implicit-function-declaration")
1034
1035 check_c_source_compiles("
1036 #include <libunwind.h>
1037 #include <ucontext.h>
1038 int main(int argc, char **argv)
1039 {
1040         unw_context_t libUnwindContext;
1041         ucontext_t uContext;
1042         libUnwindContext = uContext;
1043         return 0;
1044 }" UNWIND_CONTEXT_IS_UCONTEXT_T)
1045
1046 check_c_source_compiles("
1047 #include <libunwind.h>
1048
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);
1054
1055   return 0;
1056 }" HAVE_UNW_GET_SAVE_LOC)
1057
1058 check_c_source_compiles("
1059 #include <libunwind.h>
1060
1061 int main(int argc, char **argv) {
1062   unw_addr_space_t as;
1063   unw_get_accessors(as);
1064
1065   return 0;
1066 }" HAVE_UNW_GET_ACCESSORS)
1067
1068 set(CMAKE_REQUIRED_FLAGS)
1069 if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
1070   list(REMOVE_AT CMAKE_REQUIRED_INCLUDES 0 1)
1071 endif()
1072
1073 check_cxx_source_compiles("
1074 #include <sys/param.h>
1075 #include <sys/sysctl.h>
1076 #include <vm/vm_param.h>
1077
1078 int main(int argc, char **argv)
1079 {
1080     struct xswdev xsw;
1081
1082     return 0;
1083 }" HAVE_XSWDEV)
1084
1085 check_cxx_source_compiles("
1086 #include <sys/param.h>
1087 #include <sys/sysctl.h>
1088
1089 int main(int argc, char **argv)
1090 {
1091     struct xsw_usage xsu;
1092
1093     return 0;
1094 }" HAVE_XSW_USAGE)
1095
1096 check_cxx_source_compiles("
1097 #include <signal.h>
1098
1099 int main(int argc, char **argv)
1100 {
1101     struct _xstate xstate;
1102     struct _fpx_sw_bytes bytes;
1103     return 0;
1104 }" HAVE_PUBLIC_XSTATE_STRUCT)
1105
1106 check_cxx_source_compiles("
1107 #include <sys/prctl.h>
1108
1109 int main(int argc, char **argv)
1110 {
1111     int flag = (int)PR_SET_PTRACER;
1112     return 0;
1113 }" HAVE_PR_SET_PTRACER)
1114
1115 set(CMAKE_REQUIRED_LIBRARIES pthread)
1116 check_cxx_source_compiles("
1117 #include <errno.h>
1118 #include <pthread.h>
1119 #include <time.h>
1120
1121 int main()
1122 {
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);
1128
1129     pthread_mutex_t mutex;
1130     pthread_mutex_init(&mutex, &mutexAttributes);
1131
1132     pthread_mutexattr_destroy(&mutexAttributes);
1133
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);
1139
1140     pthread_mutex_destroy(&mutex);
1141
1142     int error = EOWNERDEAD;
1143     error = ENOTRECOVERABLE;
1144     error = ETIMEDOUT;
1145     error = 0;
1146     return error;
1147 }" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
1148 set(CMAKE_REQUIRED_LIBRARIES)
1149
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.
1157   
1158   #include <sys/mman.h>
1159   #include <sys/time.h>
1160   
1161   #include <errno.h>
1162   #include <pthread.h>
1163   #include <stdio.h>
1164   #include <unistd.h>
1165   
1166   #include <new>
1167   using namespace std;
1168   
1169   struct Shm
1170   {
1171       pthread_mutex_t syncMutex;
1172       pthread_cond_t syncCondition;
1173       pthread_mutex_t robustMutex;
1174       int conditionValue;
1175   
1176       Shm() : conditionValue(0)
1177       {
1178       }
1179   } *shm;
1180   
1181   int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
1182   {
1183       int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
1184       if (getTimeResult != 0)
1185       {
1186           struct timeval tv;
1187           getTimeResult = gettimeofday(&tv, NULL);
1188           if (getTimeResult != 0)
1189               return 1;
1190           timeoutTimeRef->tv_sec = tv.tv_sec;
1191           timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
1192       }
1193       timeoutTimeRef->tv_sec += 30;
1194       return 0;
1195   }
1196   
1197   int WaitForConditionValue(int desiredConditionValue)
1198   {
1199       struct timespec timeoutTime;
1200       if (GetFailTimeoutTime(&timeoutTime) != 0)
1201           return 1;
1202       if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1203           return 1;
1204   
1205       if (shm->conditionValue != desiredConditionValue)
1206       {
1207           if (GetFailTimeoutTime(&timeoutTime) != 0)
1208               return 1;
1209           if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
1210               return 1;
1211           if (shm->conditionValue != desiredConditionValue)
1212               return 1;
1213       }
1214   
1215       if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1216           return 1;
1217       return 0;
1218   }
1219   
1220   int SetConditionValue(int newConditionValue)
1221   {
1222       struct timespec timeoutTime;
1223       if (GetFailTimeoutTime(&timeoutTime) != 0)
1224           return 1;
1225       if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
1226           return 1;
1227   
1228       shm->conditionValue = newConditionValue;
1229       if (pthread_cond_signal(&shm->syncCondition) != 0)
1230           return 1;
1231   
1232       if (pthread_mutex_unlock(&shm->syncMutex) != 0)
1233           return 1;
1234       return 0;
1235   }
1236   
1237   void DoTest_Child();
1238   
1239   int DoTest()
1240   {
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)
1244           return 1;
1245       shm = new(shmBuffer) Shm;
1246   
1247       // Create sync mutex
1248       pthread_mutexattr_t syncMutexAttributes;
1249       if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
1250           return 1;
1251       if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1252           return 1;
1253       if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
1254           return 1;
1255       if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
1256           return 1;
1257   
1258       // Create sync condition
1259       pthread_condattr_t syncConditionAttributes;
1260       if (pthread_condattr_init(&syncConditionAttributes) != 0)
1261           return 1;
1262       if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
1263           return 1;
1264       if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
1265           return 1;
1266       if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
1267           return 1;
1268   
1269       // Create the robust mutex that will be tested
1270       pthread_mutexattr_t robustMutexAttributes;
1271       if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
1272           return 1;
1273       if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
1274           return 1;
1275       if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
1276           return 1;
1277       if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
1278           return 1;
1279       if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
1280           return 1;
1281   
1282       // Start child test process
1283       int error = fork();
1284       if (error == -1)
1285           return 1;
1286       if (error == 0)
1287       {
1288           DoTest_Child();
1289           return -1;
1290       }
1291   
1292       // Wait for child to take a lock
1293       WaitForConditionValue(1);
1294   
1295       // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
1296       struct timespec timeoutTime;
1297       if (GetFailTimeoutTime(&timeoutTime) != 0)
1298           return 1;
1299       error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
1300       if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
1301           return 1;
1302       if (pthread_mutex_consistent(&shm->robustMutex) != 0)
1303           return 1;
1304   
1305       if (pthread_mutex_unlock(&shm->robustMutex) != 0)
1306           return 1;
1307       if (pthread_mutex_destroy(&shm->robustMutex) != 0)
1308           return 1;
1309       return 0;
1310   }
1311   
1312   void DoTest_Child()
1313   {
1314       // Lock the robust mutex
1315       struct timespec timeoutTime;
1316       if (GetFailTimeoutTime(&timeoutTime) != 0)
1317           return;
1318       if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
1319           return;
1320   
1321       // Notify parent that robust mutex is locked
1322       if (SetConditionValue(1) != 0)
1323           return;
1324   
1325       // Wait a short period to let the parent block on waiting for a lock
1326       sleep(1);
1327   
1328       // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
1329   }
1330   
1331   int main()
1332   {
1333       int result = DoTest();
1334       return result >= 0 ? result : 0;
1335   }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
1336   set(CMAKE_REQUIRED_LIBRARIES)
1337 endif()
1338
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)
1350
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)
1371
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)")
1384   endif()
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)
1394
1395 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)