passenger 5.0.30 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +30 -1
  3. data/CONTRIBUTING.md +1 -1
  4. data/CONTRIBUTORS +2 -0
  5. data/bin/passenger-install-nginx-module +18 -13
  6. data/build/agent.rb +1 -0
  7. data/build/basics.rb +1 -0
  8. data/build/cxx_tests.rb +6 -1
  9. data/build/misc.rb +3 -0
  10. data/build/packaging.rb +5 -17
  11. data/build/support/cxx_dependency_map.rb +100 -0
  12. data/build/support/vendor/cxxcodebuilder/lib/cxxcodebuilder/builder.rb +4 -1
  13. data/build/test_basics.rb +12 -2
  14. data/dev/ci/run_travis.sh +6 -2
  15. data/doc/Users guide Apache.html +7 -2
  16. data/doc/Users guide Apache.txt +4 -0
  17. data/resources/templates/error_layout.css +70 -84
  18. data/resources/templates/error_layout.html.template +84 -93
  19. data/resources/templates/standalone/http.erb +17 -13
  20. data/resources/templates/standalone/server.erb +2 -1
  21. data/resources/templates/undisclosed_error.html.template +52 -51
  22. data/resources/update_check_client_cert.p12 +0 -0
  23. data/resources/update_check_client_cert.pem +89 -0
  24. data/resources/update_check_server_pubkey.pem +14 -0
  25. data/src/agent/Core/ApplicationPool/ErrorRenderer.h +15 -1
  26. data/src/agent/Core/Controller.h +3 -2
  27. data/src/agent/Core/Controller/CheckoutSession.cpp +5 -4
  28. data/src/agent/Core/Controller/ForwardResponse.cpp +1 -1
  29. data/src/agent/Core/Controller/InitRequest.cpp +2 -0
  30. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +1 -0
  31. data/src/agent/Core/Controller/Request.h +1 -0
  32. data/src/agent/Core/CoreMain.cpp +99 -2
  33. data/src/agent/Core/OptionParser.h +18 -1
  34. data/src/agent/Core/SecurityUpdateChecker.h +559 -0
  35. data/src/agent/Shared/Base.cpp +6 -1
  36. data/src/agent/TempDirToucher/TempDirToucherMain.cpp +52 -0
  37. data/src/agent/Watchdog/InstanceDirToucher.cpp +1 -2
  38. data/src/agent/Watchdog/WatchdogMain.cpp +31 -40
  39. data/src/apache2_module/Configuration.cpp +12 -0
  40. data/src/apache2_module/Configuration.hpp +5 -0
  41. data/src/apache2_module/ConfigurationCommands.cpp +19 -19
  42. data/src/apache2_module/ConfigurationCommands.cpp.cxxcodebuilder +2 -2
  43. data/src/apache2_module/ConfigurationFields.hpp +19 -19
  44. data/src/apache2_module/ConfigurationFields.hpp.cxxcodebuilder +2 -2
  45. data/src/apache2_module/ConfigurationSetters.cpp +19 -19
  46. data/src/apache2_module/ConfigurationSetters.cpp.cxxcodebuilder +2 -2
  47. data/src/apache2_module/CreateDirConfig.cpp +19 -19
  48. data/src/apache2_module/CreateDirConfig.cpp.cxxcodebuilder +2 -2
  49. data/src/apache2_module/Hooks.cpp +10 -1
  50. data/src/apache2_module/MergeDirConfig.cpp +19 -19
  51. data/src/apache2_module/MergeDirConfig.cpp.cxxcodebuilder +2 -2
  52. data/src/apache2_module/SetHeaders.cpp +19 -19
  53. data/src/apache2_module/SetHeaders.cpp.cxxcodebuilder +2 -2
  54. data/src/cxx_supportlib/Constants.h +22 -22
  55. data/src/cxx_supportlib/Constants.h.cxxcodebuilder +4 -1
  56. data/src/cxx_supportlib/Crypto.cpp +977 -0
  57. data/src/cxx_supportlib/Crypto.h +147 -0
  58. data/src/cxx_supportlib/InstanceDirectory.h +55 -2
  59. data/src/cxx_supportlib/Utils/Curl.h +24 -10
  60. data/src/cxx_supportlib/Utils/JsonUtils.h +1 -1
  61. data/src/cxx_supportlib/oxt/detail/spin_lock_darwin.hpp +2 -0
  62. data/src/cxx_supportlib/vendor-modified/boost/system/error_code.hpp +3 -3
  63. data/src/cxx_supportlib/vendor-modified/jsoncpp/json-forwards.h +167 -92
  64. data/src/cxx_supportlib/vendor-modified/jsoncpp/json.h +1827 -1542
  65. data/src/cxx_supportlib/vendor-modified/jsoncpp/jsoncpp.cpp +4705 -3652
  66. data/src/cxx_supportlib/vendor-modified/libev/Changes +46 -15
  67. data/src/cxx_supportlib/vendor-modified/libev/LICENSE +1 -1
  68. data/src/cxx_supportlib/vendor-modified/libev/Makefile.in +215 -128
  69. data/src/cxx_supportlib/vendor-modified/libev/aclocal.m4 +466 -275
  70. data/src/cxx_supportlib/vendor-modified/libev/config.guess +312 -418
  71. data/src/cxx_supportlib/vendor-modified/libev/config.sub +246 -105
  72. data/src/cxx_supportlib/vendor-modified/libev/configure +276 -72
  73. data/src/cxx_supportlib/vendor-modified/libev/configure.ac +2 -1
  74. data/src/cxx_supportlib/vendor-modified/libev/depcomp +346 -185
  75. data/src/cxx_supportlib/vendor-modified/libev/ev++.h +1 -1
  76. data/src/cxx_supportlib/vendor-modified/libev/ev.c +530 -190
  77. data/src/cxx_supportlib/vendor-modified/libev/ev.h +23 -14
  78. data/src/cxx_supportlib/vendor-modified/libev/ev_epoll.c +12 -6
  79. data/src/cxx_supportlib/vendor-modified/libev/ev_kqueue.c +9 -5
  80. data/src/cxx_supportlib/vendor-modified/libev/ev_poll.c +6 -3
  81. data/src/cxx_supportlib/vendor-modified/libev/ev_port.c +8 -4
  82. data/src/cxx_supportlib/vendor-modified/libev/ev_select.c +4 -2
  83. data/src/cxx_supportlib/vendor-modified/libev/ev_vars.h +3 -2
  84. data/src/cxx_supportlib/vendor-modified/libev/ev_win32.c +3 -4
  85. data/src/cxx_supportlib/vendor-modified/libev/install-sh +433 -219
  86. data/src/cxx_supportlib/vendor-modified/libev/libev.m4 +6 -6
  87. data/src/cxx_supportlib/vendor-modified/libev/ltmain.sh +2 -2
  88. data/src/cxx_supportlib/vendor-modified/libev/missing +167 -288
  89. data/src/cxx_supportlib/vendor-modified/libev/mkinstalldirs +72 -21
  90. data/src/cxx_supportlib/vendor-modified/modp_b64.cpp +4 -106
  91. data/src/cxx_supportlib/vendor-modified/modp_b64_data.h +37 -1
  92. data/src/cxx_supportlib/vendor-modified/modp_b64_strict_aliasing.cpp +119 -0
  93. data/src/helper-scripts/node-loader.js +72 -1
  94. data/src/nginx_module/CacheLocationConfig.c +52 -19
  95. data/src/nginx_module/CacheLocationConfig.c.cxxcodebuilder +2 -2
  96. data/src/nginx_module/Configuration.c +26 -1
  97. data/src/nginx_module/Configuration.h +2 -0
  98. data/src/nginx_module/ConfigurationCommands.c +35 -19
  99. data/src/nginx_module/ConfigurationCommands.c.cxxcodebuilder +2 -2
  100. data/src/nginx_module/ContentHandler.c +1 -1
  101. data/src/nginx_module/CreateLocationConfig.c +22 -19
  102. data/src/nginx_module/CreateLocationConfig.c.cxxcodebuilder +2 -2
  103. data/src/nginx_module/LocationConfig.h +21 -19
  104. data/src/nginx_module/LocationConfig.h.cxxcodebuilder +2 -2
  105. data/src/nginx_module/MergeLocationConfig.c +25 -19
  106. data/src/nginx_module/MergeLocationConfig.c.cxxcodebuilder +2 -2
  107. data/src/nginx_module/ngx_http_passenger_module.c +8 -4
  108. data/src/ruby_supportlib/phusion_passenger.rb +9 -4
  109. data/src/ruby_supportlib/phusion_passenger/admin_tools/instance.rb +2 -2
  110. data/src/ruby_supportlib/phusion_passenger/admin_tools/instance_registry.rb +1 -1
  111. data/src/ruby_supportlib/phusion_passenger/common_library.rb +13 -0
  112. data/src/ruby_supportlib/phusion_passenger/config/nginx_engine_compiler.rb +5 -2
  113. data/src/ruby_supportlib/phusion_passenger/constants.rb +1 -1
  114. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +15 -3
  115. data/src/ruby_supportlib/phusion_passenger/platform_info/crypto.rb +51 -0
  116. data/src/ruby_supportlib/phusion_passenger/platform_info/depcheck_specs/apache2.rb +7 -0
  117. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +17 -0
  118. data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +4 -2
  119. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +4 -0
  120. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/nginx_engine.rb +5 -0
  121. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/app.rb +19 -10
  122. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/base.rb +25 -0
  123. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/gdb_controller.rb +38 -103
  124. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/lldb_controller.rb +178 -0
  125. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/utils.rb +94 -0
  126. data/src/ruby_supportlib/phusion_passenger/vendor/crash_watch/version.rb +2 -2
  127. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +2 -2
  128. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/version_data.rb +2 -2
  129. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis +5 -3
  130. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/ruby_versions.yml.travis-with-sudo +9 -7
  131. metadata +14 -4
@@ -575,7 +575,7 @@ namespace ev {
575
575
  }
576
576
  #endif
577
577
 
578
- /* using a template here would require quite a bit more lines,
578
+ /* using a template here would require quite a few more lines,
579
579
  * so a macro solution was chosen */
580
580
  #define EV_BEGIN_WATCHER(cppstem,cstem) \
581
581
  \
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev event processing core, watcher management
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
@@ -45,11 +45,11 @@
45
45
  # include "config.h"
46
46
  # endif
47
47
 
48
- #if HAVE_FLOOR
49
- # ifndef EV_USE_FLOOR
50
- # define EV_USE_FLOOR 1
48
+ # if HAVE_FLOOR
49
+ # ifndef EV_USE_FLOOR
50
+ # define EV_USE_FLOOR 1
51
+ # endif
51
52
  # endif
52
- #endif
53
53
 
54
54
  # if HAVE_CLOCK_SYSCALL
55
55
  # ifndef EV_USE_CLOCK_SYSCALL
@@ -243,10 +243,7 @@
243
243
  #elif defined _sys_nsig
244
244
  # define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
245
245
  #else
246
- # error "unable to find value for NSIG, please report"
247
- /* to make it compile regardless, just remove the above line, */
248
- /* but consider reporting it, too! :) */
249
- # define EV_NSIG 65
246
+ # define EV_NSIG (8 * sizeof (sigset_t) + 1)
250
247
  #endif
251
248
 
252
249
  #ifndef EV_USE_FLOOR
@@ -254,13 +251,22 @@
254
251
  #endif
255
252
 
256
253
  #ifndef EV_USE_CLOCK_SYSCALL
257
- # if __linux && __GLIBC__ >= 2
254
+ # if __linux && __GLIBC__ == 2 && __GLIBC_MINOR__ < 17
258
255
  # define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS
259
256
  # else
260
257
  # define EV_USE_CLOCK_SYSCALL 0
261
258
  # endif
262
259
  #endif
263
260
 
261
+ #if !(_POSIX_TIMERS > 0)
262
+ # ifndef EV_USE_MONOTONIC
263
+ # define EV_USE_MONOTONIC 0
264
+ # endif
265
+ # ifndef EV_USE_REALTIME
266
+ # define EV_USE_REALTIME 0
267
+ # endif
268
+ #endif
269
+
264
270
  #ifndef EV_USE_MONOTONIC
265
271
  # if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
266
272
  # define EV_USE_MONOTONIC EV_FEATURE_OS
@@ -487,7 +493,7 @@ struct signalfd_siginfo
487
493
  /*
488
494
  * libecb - http://software.schmorp.de/pkg/libecb
489
495
  *
490
- * Copyright (©) 2009-2012 Marc Alexander Lehmann <libecb@schmorp.de>
496
+ * Copyright (©) 2009-2015 Marc Alexander Lehmann <libecb@schmorp.de>
491
497
  * Copyright (©) 2011 Emanuele Giaquinta
492
498
  * All rights reserved.
493
499
  *
@@ -511,13 +517,24 @@ struct signalfd_siginfo
511
517
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
512
518
  * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
513
519
  * OF THE POSSIBILITY OF SUCH DAMAGE.
520
+ *
521
+ * Alternatively, the contents of this file may be used under the terms of
522
+ * the GNU General Public License ("GPL") version 2 or any later version,
523
+ * in which case the provisions of the GPL are applicable instead of
524
+ * the above. If you wish to allow the use of your version of this file
525
+ * only under the terms of the GPL and not to allow others to use your
526
+ * version of this file under the BSD license, indicate your decision
527
+ * by deleting the provisions above and replace them with the notice
528
+ * and other provisions required by the GPL. If you do not delete the
529
+ * provisions above, a recipient may use your version of this file under
530
+ * either the BSD or the GPL.
514
531
  */
515
532
 
516
533
  #ifndef ECB_H
517
534
  #define ECB_H
518
535
 
519
536
  /* 16 bits major, 16 bits minor */
520
- #define ECB_VERSION 0x00010003
537
+ #define ECB_VERSION 0x00010005
521
538
 
522
539
  #ifdef _WIN32
523
540
  typedef signed char int8_t;
@@ -544,16 +561,19 @@ struct signalfd_siginfo
544
561
  #endif
545
562
  #else
546
563
  #include <inttypes.h>
547
- #if UINTMAX_MAX > 0xffffffffU
564
+ #if (defined INTPTR_MAX ? INTPTR_MAX : ULONG_MAX) > 0xffffffffU
548
565
  #define ECB_PTRSIZE 8
549
566
  #else
550
567
  #define ECB_PTRSIZE 4
551
568
  #endif
552
569
  #endif
553
570
 
571
+ #define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__)
572
+ #define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64)
573
+
554
574
  /* work around x32 idiocy by defining proper macros */
555
- #if __x86_64 || _M_AMD64
556
- #if __ILP32
575
+ #if ECB_GCC_AMD64 || ECB_MSVC_AMD64
576
+ #if _ILP32
557
577
  #define ECB_AMD64_X32 1
558
578
  #else
559
579
  #define ECB_AMD64 1
@@ -567,20 +587,40 @@ struct signalfd_siginfo
567
587
  * we try to detect these and simply assume they are not gcc - if they have
568
588
  * an issue with that they should have done it right in the first place.
569
589
  */
570
- #ifndef ECB_GCC_VERSION
571
- #if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
572
- #define ECB_GCC_VERSION(major,minor) 0
573
- #else
574
- #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
575
- #endif
590
+ #if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
591
+ #define ECB_GCC_VERSION(major,minor) 0
592
+ #else
593
+ #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
594
+ #endif
595
+
596
+ #define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor)))
597
+
598
+ #if __clang__ && defined __has_builtin
599
+ #define ECB_CLANG_BUILTIN(x) __has_builtin (x)
600
+ #else
601
+ #define ECB_CLANG_BUILTIN(x) 0
602
+ #endif
603
+
604
+ #if __clang__ && defined __has_extension
605
+ #define ECB_CLANG_EXTENSION(x) __has_extension (x)
606
+ #else
607
+ #define ECB_CLANG_EXTENSION(x) 0
576
608
  #endif
577
609
 
578
- #define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */
579
- #define ECB_C99 (__STDC_VERSION__ >= 199901L)
580
- #define ECB_C11 (__STDC_VERSION__ >= 201112L)
581
610
  #define ECB_CPP (__cplusplus+0)
582
611
  #define ECB_CPP11 (__cplusplus >= 201103L)
583
612
 
613
+ #if ECB_CPP
614
+ #define ECB_C 0
615
+ #define ECB_STDC_VERSION 0
616
+ #else
617
+ #define ECB_C 1
618
+ #define ECB_STDC_VERSION __STDC_VERSION__
619
+ #endif
620
+
621
+ #define ECB_C99 (ECB_STDC_VERSION >= 199901L)
622
+ #define ECB_C11 (ECB_STDC_VERSION >= 201112L)
623
+
584
624
  #if ECB_CPP
585
625
  #define ECB_EXTERN_C extern "C"
586
626
  #define ECB_EXTERN_C_BEG ECB_EXTERN_C {
@@ -604,32 +644,53 @@ struct signalfd_siginfo
604
644
  #define ECB_MEMORY_FENCE do { } while (0)
605
645
  #endif
606
646
 
647
+ /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/compiler_ref/compiler_builtins.html */
648
+ #if __xlC__ && ECB_CPP
649
+ #include <builtins.h>
650
+ #endif
651
+
652
+ #if 1400 <= _MSC_VER
653
+ #include <intrin.h> /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */
654
+ #endif
655
+
607
656
  #ifndef ECB_MEMORY_FENCE
608
657
  #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
609
658
  #if __i386 || __i386__
610
659
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
611
660
  #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
612
661
  #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
613
- #elif __amd64 || __amd64__ || __x86_64 || __x86_64__
662
+ #elif ECB_GCC_AMD64
614
663
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
615
664
  #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
616
665
  #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
617
666
  #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
618
667
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
668
+ #elif defined __ARM_ARCH_2__ \
669
+ || defined __ARM_ARCH_3__ || defined __ARM_ARCH_3M__ \
670
+ || defined __ARM_ARCH_4__ || defined __ARM_ARCH_4T__ \
671
+ || defined __ARM_ARCH_5__ || defined __ARM_ARCH_5E__ \
672
+ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__ \
673
+ || defined __ARM_ARCH_5TEJ__
674
+ /* should not need any, unless running old code on newer cpu - arm doesn't support that */
619
675
  #elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \
620
- || defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__
676
+ || defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__ \
677
+ || defined __ARM_ARCH_6T2__
621
678
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
622
679
  #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
623
- || defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
680
+ || defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
624
681
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
625
- #elif __sparc || __sparc__
682
+ #elif __aarch64__
683
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory")
684
+ #elif (__sparc || __sparc__) && !(__sparc_v8__ || defined __sparcv8)
626
685
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
627
686
  #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
628
687
  #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
629
688
  #elif defined __s390__ || defined __s390x__
630
689
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
631
690
  #elif defined __mips__
632
- #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
691
+ /* GNU/Linux emulates sync on mips1 architectures, so we force its use */
692
+ /* anybody else who still uses mips1 is supposed to send in their version, with detection code. */
693
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory")
633
694
  #elif defined __alpha__
634
695
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory")
635
696
  #elif defined __hppa__
@@ -637,6 +698,12 @@ struct signalfd_siginfo
637
698
  #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
638
699
  #elif defined __ia64__
639
700
  #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory")
701
+ #elif defined __m68k__
702
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
703
+ #elif defined __m88k__
704
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory")
705
+ #elif defined __sh__
706
+ #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
640
707
  #endif
641
708
  #endif
642
709
  #endif
@@ -645,18 +712,23 @@ struct signalfd_siginfo
645
712
  #if ECB_GCC_VERSION(4,7)
646
713
  /* see comment below (stdatomic.h) about the C11 memory model. */
647
714
  #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
715
+ #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
716
+ #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
648
717
 
649
- /* The __has_feature syntax from clang is so misdesigned that we cannot use it
650
- * without risking compile time errors with other compilers. We *could*
651
- * define our own ecb_clang_has_feature, but I just can't be bothered to work
652
- * around this shit time and again.
653
- * #elif defined __clang && __has_feature (cxx_atomic)
654
- * // see comment below (stdatomic.h) about the C11 memory model.
655
- * #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
656
- */
718
+ #elif ECB_CLANG_EXTENSION(c_atomic)
719
+ /* see comment below (stdatomic.h) about the C11 memory model. */
720
+ #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
721
+ #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
722
+ #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
657
723
 
658
724
  #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
659
725
  #define ECB_MEMORY_FENCE __sync_synchronize ()
726
+ #elif _MSC_VER >= 1500 /* VC++ 2008 */
727
+ /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */
728
+ #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
729
+ #define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier()
730
+ #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */
731
+ #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier()
660
732
  #elif _MSC_VER >= 1400 /* VC++ 2005 */
661
733
  #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
662
734
  #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
@@ -686,6 +758,8 @@ struct signalfd_siginfo
686
758
  /* for most usages, or gcc and clang have a bug */
687
759
  /* I *currently* lean towards the latter, and inefficiently implement */
688
760
  /* all three of ecb's fences as a seq_cst fence */
761
+ /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
762
+ /* for all __atomic_thread_fence's except seq_cst */
689
763
  #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
690
764
  #endif
691
765
  #endif
@@ -718,7 +792,7 @@ struct signalfd_siginfo
718
792
 
719
793
  /*****************************************************************************/
720
794
 
721
- #if __cplusplus
795
+ #if ECB_CPP
722
796
  #define ecb_inline static inline
723
797
  #elif ECB_GCC_VERSION(2,5)
724
798
  #define ecb_inline static __inline__
@@ -742,35 +816,79 @@ typedef int ecb_bool;
742
816
  #define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
743
817
  #define ECB_STRINGIFY_(a) # a
744
818
  #define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
819
+ #define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr))
745
820
 
746
821
  #define ecb_function_ ecb_inline
747
822
 
748
- #if ECB_GCC_VERSION(3,1)
749
- #define ecb_attribute(attrlist) __attribute__(attrlist)
750
- #define ecb_is_constant(expr) __builtin_constant_p (expr)
751
- #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
752
- #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
823
+ #if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8)
824
+ #define ecb_attribute(attrlist) __attribute__ (attrlist)
753
825
  #else
754
826
  #define ecb_attribute(attrlist)
827
+ #endif
828
+
829
+ #if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p)
830
+ #define ecb_is_constant(expr) __builtin_constant_p (expr)
831
+ #else
832
+ /* possible C11 impl for integral types
833
+ typedef struct ecb_is_constant_struct ecb_is_constant_struct;
834
+ #define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */
835
+
755
836
  #define ecb_is_constant(expr) 0
837
+ #endif
838
+
839
+ #if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect)
840
+ #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
841
+ #else
756
842
  #define ecb_expect(expr,value) (expr)
843
+ #endif
844
+
845
+ #if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch)
846
+ #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
847
+ #else
757
848
  #define ecb_prefetch(addr,rw,locality)
758
849
  #endif
759
850
 
760
851
  /* no emulation for ecb_decltype */
761
- #if ECB_GCC_VERSION(4,5)
762
- #define ecb_decltype(x) __decltype(x)
763
- #elif ECB_GCC_VERSION(3,0)
764
- #define ecb_decltype(x) __typeof(x)
852
+ #if ECB_CPP11
853
+ // older implementations might have problems with decltype(x)::type, work around it
854
+ template<class T> struct ecb_decltype_t { typedef T type; };
855
+ #define ecb_decltype(x) ecb_decltype_t<decltype (x)>::type
856
+ #elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8)
857
+ #define ecb_decltype(x) __typeof__ (x)
858
+ #endif
859
+
860
+ #if _MSC_VER >= 1300
861
+ #define ecb_deprecated __declspec (deprecated)
862
+ #else
863
+ #define ecb_deprecated ecb_attribute ((__deprecated__))
864
+ #endif
865
+
866
+ #if _MSC_VER >= 1500
867
+ #define ecb_deprecated_message(msg) __declspec (deprecated (msg))
868
+ #elif ECB_GCC_VERSION(4,5)
869
+ #define ecb_deprecated_message(msg) ecb_attribute ((__deprecated__ (msg))
870
+ #else
871
+ #define ecb_deprecated_message(msg) ecb_deprecated
872
+ #endif
873
+
874
+ #if _MSC_VER >= 1400
875
+ #define ecb_noinline __declspec (noinline)
876
+ #else
877
+ #define ecb_noinline ecb_attribute ((__noinline__))
765
878
  #endif
766
879
 
767
- #define ecb_noinline ecb_attribute ((__noinline__))
768
880
  #define ecb_unused ecb_attribute ((__unused__))
769
881
  #define ecb_const ecb_attribute ((__const__))
770
882
  #define ecb_pure ecb_attribute ((__pure__))
771
883
 
772
- #if ECB_C11
884
+ #if ECB_C11 || __IBMC_NORETURN
885
+ /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/noreturn.html */
773
886
  #define ecb_noreturn _Noreturn
887
+ #elif ECB_CPP11
888
+ #define ecb_noreturn [[noreturn]]
889
+ #elif _MSC_VER >= 1200
890
+ /* http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx */
891
+ #define ecb_noreturn __declspec (noreturn)
774
892
  #else
775
893
  #define ecb_noreturn ecb_attribute ((__noreturn__))
776
894
  #endif
@@ -795,7 +913,10 @@ typedef int ecb_bool;
795
913
  #define ecb_unlikely(expr) ecb_expect_false (expr)
796
914
 
797
915
  /* count trailing zero bits and count # of one bits */
798
- #if ECB_GCC_VERSION(3,4)
916
+ #if ECB_GCC_VERSION(3,4) \
917
+ || (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \
918
+ && ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \
919
+ && ECB_CLANG_BUILTIN(__builtin_popcount))
799
920
  /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
800
921
  #define ecb_ld32(x) (__builtin_clz (x) ^ 31)
801
922
  #define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
@@ -804,10 +925,15 @@ typedef int ecb_bool;
804
925
  #define ecb_popcount32(x) __builtin_popcount (x)
805
926
  /* no popcountll */
806
927
  #else
807
- ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const;
808
- ecb_function_ int
928
+ ecb_function_ ecb_const int ecb_ctz32 (uint32_t x);
929
+ ecb_function_ ecb_const int
809
930
  ecb_ctz32 (uint32_t x)
810
931
  {
932
+ #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
933
+ unsigned long r;
934
+ _BitScanForward (&r, x);
935
+ return (int)r;
936
+ #else
811
937
  int r = 0;
812
938
 
813
939
  x &= ~x + 1; /* this isolates the lowest bit */
@@ -827,18 +953,25 @@ typedef int ecb_bool;
827
953
  #endif
828
954
 
829
955
  return r;
956
+ #endif
830
957
  }
831
958
 
832
- ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const;
833
- ecb_function_ int
959
+ ecb_function_ ecb_const int ecb_ctz64 (uint64_t x);
960
+ ecb_function_ ecb_const int
834
961
  ecb_ctz64 (uint64_t x)
835
962
  {
836
- int shift = x & 0xffffffffU ? 0 : 32;
963
+ #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
964
+ unsigned long r;
965
+ _BitScanForward64 (&r, x);
966
+ return (int)r;
967
+ #else
968
+ int shift = x & 0xffffffff ? 0 : 32;
837
969
  return ecb_ctz32 (x >> shift) + shift;
970
+ #endif
838
971
  }
839
972
 
840
- ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const;
841
- ecb_function_ int
973
+ ecb_function_ ecb_const int ecb_popcount32 (uint32_t x);
974
+ ecb_function_ ecb_const int
842
975
  ecb_popcount32 (uint32_t x)
843
976
  {
844
977
  x -= (x >> 1) & 0x55555555;
@@ -849,9 +982,14 @@ typedef int ecb_bool;
849
982
  return x >> 24;
850
983
  }
851
984
 
852
- ecb_function_ int ecb_ld32 (uint32_t x) ecb_const;
853
- ecb_function_ int ecb_ld32 (uint32_t x)
985
+ ecb_function_ ecb_const int ecb_ld32 (uint32_t x);
986
+ ecb_function_ ecb_const int ecb_ld32 (uint32_t x)
854
987
  {
988
+ #if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
989
+ unsigned long r;
990
+ _BitScanReverse (&r, x);
991
+ return (int)r;
992
+ #else
855
993
  int r = 0;
856
994
 
857
995
  if (x >> 16) { x >>= 16; r += 16; }
@@ -861,33 +999,40 @@ typedef int ecb_bool;
861
999
  if (x >> 1) { r += 1; }
862
1000
 
863
1001
  return r;
1002
+ #endif
864
1003
  }
865
1004
 
866
- ecb_function_ int ecb_ld64 (uint64_t x) ecb_const;
867
- ecb_function_ int ecb_ld64 (uint64_t x)
1005
+ ecb_function_ ecb_const int ecb_ld64 (uint64_t x);
1006
+ ecb_function_ ecb_const int ecb_ld64 (uint64_t x)
868
1007
  {
1008
+ #if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
1009
+ unsigned long r;
1010
+ _BitScanReverse64 (&r, x);
1011
+ return (int)r;
1012
+ #else
869
1013
  int r = 0;
870
1014
 
871
1015
  if (x >> 32) { x >>= 32; r += 32; }
872
1016
 
873
1017
  return r + ecb_ld32 (x);
1018
+ #endif
874
1019
  }
875
1020
  #endif
876
1021
 
877
- ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) ecb_const;
878
- ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
879
- ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) ecb_const;
880
- ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
1022
+ ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x);
1023
+ ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
1024
+ ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x);
1025
+ ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
881
1026
 
882
- ecb_function_ uint8_t ecb_bitrev8 (uint8_t x) ecb_const;
883
- ecb_function_ uint8_t ecb_bitrev8 (uint8_t x)
1027
+ ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x);
1028
+ ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x)
884
1029
  {
885
1030
  return ( (x * 0x0802U & 0x22110U)
886
- | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
1031
+ | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
887
1032
  }
888
1033
 
889
- ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) ecb_const;
890
- ecb_function_ uint16_t ecb_bitrev16 (uint16_t x)
1034
+ ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x);
1035
+ ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x)
891
1036
  {
892
1037
  x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
893
1038
  x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
@@ -897,8 +1042,8 @@ ecb_function_ uint16_t ecb_bitrev16 (uint16_t x)
897
1042
  return x;
898
1043
  }
899
1044
 
900
- ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) ecb_const;
901
- ecb_function_ uint32_t ecb_bitrev32 (uint32_t x)
1045
+ ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x);
1046
+ ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x)
902
1047
  {
903
1048
  x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
904
1049
  x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
@@ -911,71 +1056,80 @@ ecb_function_ uint32_t ecb_bitrev32 (uint32_t x)
911
1056
 
912
1057
  /* popcount64 is only available on 64 bit cpus as gcc builtin */
913
1058
  /* so for this version we are lazy */
914
- ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const;
915
- ecb_function_ int
1059
+ ecb_function_ ecb_const int ecb_popcount64 (uint64_t x);
1060
+ ecb_function_ ecb_const int
916
1061
  ecb_popcount64 (uint64_t x)
917
1062
  {
918
1063
  return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
919
1064
  }
920
1065
 
921
- ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) ecb_const;
922
- ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) ecb_const;
923
- ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const;
924
- ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const;
925
- ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const;
926
- ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const;
927
- ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const;
928
- ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const;
929
-
930
- ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
931
- ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
932
- ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
933
- ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
934
- ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
935
- ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
936
- ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
937
- ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
938
-
939
- #if ECB_GCC_VERSION(4,3)
1066
+ ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count);
1067
+ ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count);
1068
+ ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count);
1069
+ ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count);
1070
+ ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count);
1071
+ ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count);
1072
+ ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count);
1073
+ ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count);
1074
+
1075
+ ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
1076
+ ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
1077
+ ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
1078
+ ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
1079
+ ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
1080
+ ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
1081
+ ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
1082
+ ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
1083
+
1084
+ #if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64))
1085
+ #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16)
1086
+ #define ecb_bswap16(x) __builtin_bswap16 (x)
1087
+ #else
940
1088
  #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
1089
+ #endif
941
1090
  #define ecb_bswap32(x) __builtin_bswap32 (x)
942
1091
  #define ecb_bswap64(x) __builtin_bswap64 (x)
1092
+ #elif _MSC_VER
1093
+ #include <stdlib.h>
1094
+ #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x)))
1095
+ #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x)))
1096
+ #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x)))
943
1097
  #else
944
- ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const;
945
- ecb_function_ uint16_t
1098
+ ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x);
1099
+ ecb_function_ ecb_const uint16_t
946
1100
  ecb_bswap16 (uint16_t x)
947
1101
  {
948
1102
  return ecb_rotl16 (x, 8);
949
1103
  }
950
1104
 
951
- ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const;
952
- ecb_function_ uint32_t
1105
+ ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x);
1106
+ ecb_function_ ecb_const uint32_t
953
1107
  ecb_bswap32 (uint32_t x)
954
1108
  {
955
1109
  return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
956
1110
  }
957
1111
 
958
- ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const;
959
- ecb_function_ uint64_t
1112
+ ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x);
1113
+ ecb_function_ ecb_const uint64_t
960
1114
  ecb_bswap64 (uint64_t x)
961
1115
  {
962
1116
  return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
963
1117
  }
964
1118
  #endif
965
1119
 
966
- #if ECB_GCC_VERSION(4,5)
1120
+ #if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable)
967
1121
  #define ecb_unreachable() __builtin_unreachable ()
968
1122
  #else
969
1123
  /* this seems to work fine, but gcc always emits a warning for it :/ */
970
1124
  ecb_inline ecb_noreturn void ecb_unreachable (void);
971
- ecb_inline void ecb_unreachable (void) { }
1125
+ ecb_inline ecb_noreturn void ecb_unreachable (void) { }
972
1126
  #endif
973
1127
 
974
1128
  /* try to tell the compiler that some condition is definitely true */
975
1129
  #define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
976
1130
 
977
- ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const;
978
- ecb_inline unsigned char
1131
+ ecb_inline ecb_const uint32_t ecb_byteorder_helper (void);
1132
+ ecb_inline ecb_const uint32_t
979
1133
  ecb_byteorder_helper (void)
980
1134
  {
981
1135
  /* the union code still generates code under pressure in gcc, */
@@ -984,26 +1138,28 @@ ecb_byteorder_helper (void)
984
1138
  /* the reason why we have this horrible preprocessor mess */
985
1139
  /* is to avoid it in all cases, at least on common architectures */
986
1140
  /* or when using a recent enough gcc version (>= 4.6) */
987
- #if __i386 || __i386__ || _M_X86 || __amd64 || __amd64__ || _M_X64
988
- return 0x44;
989
- #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
990
- return 0x44;
991
- #elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
992
- return 0x11;
1141
+ #if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
1142
+ || ((__i386 || __i386__ || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64) && !__VOS__)
1143
+ #define ECB_LITTLE_ENDIAN 1
1144
+ return 0x44332211;
1145
+ #elif (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
1146
+ || ((__AARCH64EB__ || __MIPSEB__ || __ARMEB__) && !__VOS__)
1147
+ #define ECB_BIG_ENDIAN 1
1148
+ return 0x11223344;
993
1149
  #else
994
1150
  union
995
1151
  {
996
- uint32_t i;
997
- uint8_t c;
998
- } u = { 0x11223344 };
999
- return u.c;
1152
+ uint8_t c[4];
1153
+ uint32_t u;
1154
+ } u = { 0x11, 0x22, 0x33, 0x44 };
1155
+ return u.u;
1000
1156
  #endif
1001
1157
  }
1002
1158
 
1003
- ecb_inline ecb_bool ecb_big_endian (void) ecb_const;
1004
- ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
1005
- ecb_inline ecb_bool ecb_little_endian (void) ecb_const;
1006
- ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
1159
+ ecb_inline ecb_const ecb_bool ecb_big_endian (void);
1160
+ ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; }
1161
+ ecb_inline ecb_const ecb_bool ecb_little_endian (void);
1162
+ ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; }
1007
1163
 
1008
1164
  #if ECB_GCC_VERSION(3,0) || ECB_C99
1009
1165
  #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
@@ -1011,7 +1167,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1011
1167
  #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
1012
1168
  #endif
1013
1169
 
1014
- #if __cplusplus
1170
+ #if ECB_CPP
1015
1171
  template<typename T>
1016
1172
  static inline T ecb_div_rd (T val, T div)
1017
1173
  {
@@ -1038,6 +1194,102 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1038
1194
  #define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
1039
1195
  #endif
1040
1196
 
1197
+ ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x);
1198
+ ecb_function_ ecb_const uint32_t
1199
+ ecb_binary16_to_binary32 (uint32_t x)
1200
+ {
1201
+ unsigned int s = (x & 0x8000) << (31 - 15);
1202
+ int e = (x >> 10) & 0x001f;
1203
+ unsigned int m = x & 0x03ff;
1204
+
1205
+ if (ecb_expect_false (e == 31))
1206
+ /* infinity or NaN */
1207
+ e = 255 - (127 - 15);
1208
+ else if (ecb_expect_false (!e))
1209
+ {
1210
+ if (ecb_expect_true (!m))
1211
+ /* zero, handled by code below by forcing e to 0 */
1212
+ e = 0 - (127 - 15);
1213
+ else
1214
+ {
1215
+ /* subnormal, renormalise */
1216
+ unsigned int s = 10 - ecb_ld32 (m);
1217
+
1218
+ m = (m << s) & 0x3ff; /* mask implicit bit */
1219
+ e -= s - 1;
1220
+ }
1221
+ }
1222
+
1223
+ /* e and m now are normalised, or zero, (or inf or nan) */
1224
+ e += 127 - 15;
1225
+
1226
+ return s | (e << 23) | (m << (23 - 10));
1227
+ }
1228
+
1229
+ ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x);
1230
+ ecb_function_ ecb_const uint16_t
1231
+ ecb_binary32_to_binary16 (uint32_t x)
1232
+ {
1233
+ unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */
1234
+ unsigned int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */
1235
+ unsigned int m = x & 0x007fffff;
1236
+
1237
+ x &= 0x7fffffff;
1238
+
1239
+ /* if it's within range of binary16 normals, use fast path */
1240
+ if (ecb_expect_true (0x38800000 <= x && x <= 0x477fefff))
1241
+ {
1242
+ /* mantissa round-to-even */
1243
+ m += 0x00000fff + ((m >> (23 - 10)) & 1);
1244
+
1245
+ /* handle overflow */
1246
+ if (ecb_expect_false (m >= 0x00800000))
1247
+ {
1248
+ m >>= 1;
1249
+ e += 1;
1250
+ }
1251
+
1252
+ return s | (e << 10) | (m >> (23 - 10));
1253
+ }
1254
+
1255
+ /* handle large numbers and infinity */
1256
+ if (ecb_expect_true (0x477fefff < x && x <= 0x7f800000))
1257
+ return s | 0x7c00;
1258
+
1259
+ /* handle zero, subnormals and small numbers */
1260
+ if (ecb_expect_true (x < 0x38800000))
1261
+ {
1262
+ /* zero */
1263
+ if (ecb_expect_true (!x))
1264
+ return s;
1265
+
1266
+ /* handle subnormals */
1267
+
1268
+ /* too small, will be zero */
1269
+ if (e < (14 - 24)) /* might not be sharp, but is good enough */
1270
+ return s;
1271
+
1272
+ m |= 0x00800000; /* make implicit bit explicit */
1273
+
1274
+ /* very tricky - we need to round to the nearest e (+10) bit value */
1275
+ {
1276
+ unsigned int bits = 14 - e;
1277
+ unsigned int half = (1 << (bits - 1)) - 1;
1278
+ unsigned int even = (m >> bits) & 1;
1279
+
1280
+ /* if this overflows, we will end up with a normalised number */
1281
+ m = (m + half + even) >> bits;
1282
+ }
1283
+
1284
+ return s | m;
1285
+ }
1286
+
1287
+ /* handle NaNs, preserve leftmost nan bits, but make sure we don't turn them into infinities */
1288
+ m >>= 13;
1289
+
1290
+ return s | 0x7c00 | m | !m;
1291
+ }
1292
+
1041
1293
  /*******************************************************************************/
1042
1294
  /* floating point stuff, can be disabled by defining ECB_NO_LIBM */
1043
1295
 
@@ -1045,27 +1297,53 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1045
1297
  /* the only noteworthy exception is ancient armle, which uses order 43218765 */
1046
1298
  #if 0 \
1047
1299
  || __i386 || __i386__ \
1048
- || __amd64 || __amd64__ || __x86_64 || __x86_64__ \
1300
+ || ECB_GCC_AMD64 \
1049
1301
  || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
1050
- || defined __arm__ && defined __ARM_EABI__ \
1051
1302
  || defined __s390__ || defined __s390x__ \
1052
1303
  || defined __mips__ \
1053
1304
  || defined __alpha__ \
1054
1305
  || defined __hppa__ \
1055
1306
  || defined __ia64__ \
1056
- || defined _M_IX86 || defined _M_AMD64 || defined _M_IA64
1307
+ || defined __m68k__ \
1308
+ || defined __m88k__ \
1309
+ || defined __sh__ \
1310
+ || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \
1311
+ || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \
1312
+ || defined __aarch64__
1057
1313
  #define ECB_STDFP 1
1058
1314
  #include <string.h> /* for memcpy */
1059
1315
  #else
1060
1316
  #define ECB_STDFP 0
1061
- #include <math.h> /* for frexp*, ldexp* */
1062
1317
  #endif
1063
1318
 
1064
1319
  #ifndef ECB_NO_LIBM
1065
1320
 
1321
+ #include <math.h> /* for frexp*, ldexp*, INFINITY, NAN */
1322
+
1323
+ /* only the oldest of old doesn't have this one. solaris. */
1324
+ #ifdef INFINITY
1325
+ #define ECB_INFINITY INFINITY
1326
+ #else
1327
+ #define ECB_INFINITY HUGE_VAL
1328
+ #endif
1329
+
1330
+ #ifdef NAN
1331
+ #define ECB_NAN NAN
1332
+ #else
1333
+ #define ECB_NAN ECB_INFINITY
1334
+ #endif
1335
+
1336
+ #if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L
1337
+ #define ecb_ldexpf(x,e) ldexpf ((x), (e))
1338
+ #define ecb_frexpf(x,e) frexpf ((x), (e))
1339
+ #else
1340
+ #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e))
1341
+ #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e))
1342
+ #endif
1343
+
1066
1344
  /* convert a float to ieee single/binary32 */
1067
- ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const;
1068
- ecb_function_ uint32_t
1345
+ ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x);
1346
+ ecb_function_ ecb_const uint32_t
1069
1347
  ecb_float_to_binary32 (float x)
1070
1348
  {
1071
1349
  uint32_t r;
@@ -1082,7 +1360,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1082
1360
  if (x < -3.40282346638528860e+38f) return 0xff800000U;
1083
1361
  if (x != x ) return 0x7fbfffffU;
1084
1362
 
1085
- m = frexpf (x, &e) * 0x1000000U;
1363
+ m = ecb_frexpf (x, &e) * 0x1000000U;
1086
1364
 
1087
1365
  r = m & 0x80000000U;
1088
1366
 
@@ -1104,8 +1382,8 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1104
1382
  }
1105
1383
 
1106
1384
  /* converts an ieee single/binary32 to a float */
1107
- ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const;
1108
- ecb_function_ float
1385
+ ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x);
1386
+ ecb_function_ ecb_const float
1109
1387
  ecb_binary32_to_float (uint32_t x)
1110
1388
  {
1111
1389
  float r;
@@ -1125,7 +1403,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1125
1403
  e = 1;
1126
1404
 
1127
1405
  /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
1128
- r = ldexpf (x * (0.5f / 0x800000U), e - 126);
1406
+ r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126);
1129
1407
 
1130
1408
  r = neg ? -r : r;
1131
1409
  #endif
@@ -1134,8 +1412,8 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1134
1412
  }
1135
1413
 
1136
1414
  /* convert a double to ieee double/binary64 */
1137
- ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const;
1138
- ecb_function_ uint64_t
1415
+ ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x);
1416
+ ecb_function_ ecb_const uint64_t
1139
1417
  ecb_double_to_binary64 (double x)
1140
1418
  {
1141
1419
  uint64_t r;
@@ -1174,8 +1452,8 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1174
1452
  }
1175
1453
 
1176
1454
  /* converts an ieee double/binary64 to a double */
1177
- ecb_function_ double ecb_binary64_to_double (uint64_t x) ecb_const;
1178
- ecb_function_ double
1455
+ ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x);
1456
+ ecb_function_ ecb_const double
1179
1457
  ecb_binary64_to_double (uint64_t x)
1180
1458
  {
1181
1459
  double r;
@@ -1203,6 +1481,22 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1203
1481
  return r;
1204
1482
  }
1205
1483
 
1484
+ /* convert a float to ieee half/binary16 */
1485
+ ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x);
1486
+ ecb_function_ ecb_const uint16_t
1487
+ ecb_float_to_binary16 (float x)
1488
+ {
1489
+ return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x));
1490
+ }
1491
+
1492
+ /* convert an ieee half/binary16 to float */
1493
+ ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x);
1494
+ ecb_function_ ecb_const float
1495
+ ecb_binary16_to_float (uint16_t x)
1496
+ {
1497
+ return ecb_binary32_to_float (ecb_binary16_to_binary32 (x));
1498
+ }
1499
+
1206
1500
  #endif
1207
1501
 
1208
1502
  #endif
@@ -1235,7 +1529,7 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
1235
1529
  #if EV_FEATURE_CODE
1236
1530
  # define inline_speed ecb_inline
1237
1531
  #else
1238
- # define inline_speed static noinline
1532
+ # define inline_speed noinline static
1239
1533
  #endif
1240
1534
 
1241
1535
  #define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
@@ -1292,7 +1586,8 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
1292
1586
  #include <float.h>
1293
1587
 
1294
1588
  /* a floor() replacement function, should be independent of ev_tstamp type */
1295
- static ev_tstamp noinline
1589
+ noinline
1590
+ static ev_tstamp
1296
1591
  ev_floor (ev_tstamp v)
1297
1592
  {
1298
1593
  /* the choice of shift factor is not terribly important */
@@ -1334,7 +1629,8 @@ ev_floor (ev_tstamp v)
1334
1629
  # include <sys/utsname.h>
1335
1630
  #endif
1336
1631
 
1337
- static unsigned int noinline ecb_cold
1632
+ noinline ecb_cold
1633
+ static unsigned int
1338
1634
  ev_linux_version (void)
1339
1635
  {
1340
1636
  #ifdef __linux
@@ -1373,7 +1669,8 @@ ev_linux_version (void)
1373
1669
  /*****************************************************************************/
1374
1670
 
1375
1671
  #if EV_AVOID_STDIO
1376
- static void noinline ecb_cold
1672
+ noinline ecb_cold
1673
+ static void
1377
1674
  ev_printerr (const char *msg)
1378
1675
  {
1379
1676
  write (STDERR_FILENO, msg, strlen (msg));
@@ -1382,13 +1679,15 @@ ev_printerr (const char *msg)
1382
1679
 
1383
1680
  static void (*syserr_cb)(const char *msg) EV_THROW;
1384
1681
 
1385
- void ecb_cold
1682
+ ecb_cold
1683
+ void
1386
1684
  ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW
1387
1685
  {
1388
1686
  syserr_cb = cb;
1389
1687
  }
1390
1688
 
1391
- static void noinline ecb_cold
1689
+ noinline ecb_cold
1690
+ static void
1392
1691
  ev_syserr (const char *msg)
1393
1692
  {
1394
1693
  if (!msg)
@@ -1429,7 +1728,8 @@ ev_realloc_emul (void *ptr, long size) EV_THROW
1429
1728
 
1430
1729
  static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
1431
1730
 
1432
- void ecb_cold
1731
+ ecb_cold
1732
+ void
1433
1733
  ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW
1434
1734
  {
1435
1735
  alloc = cb;
@@ -1648,7 +1948,8 @@ array_nextsize (int elem, int cur, int cnt)
1648
1948
  return ncur;
1649
1949
  }
1650
1950
 
1651
- static void * noinline ecb_cold
1951
+ noinline ecb_cold
1952
+ static void *
1652
1953
  array_realloc (int elem, void *base, int *cur, int cnt)
1653
1954
  {
1654
1955
  *cur = array_nextsize (elem, *cur, cnt);
@@ -1661,7 +1962,7 @@ array_realloc (int elem, void *base, int *cur, int cnt)
1661
1962
  #define array_needsize(type,base,cur,cnt,init) \
1662
1963
  if (expect_false ((cnt) > (cur))) \
1663
1964
  { \
1664
- int ecb_unused ocur_ = (cur); \
1965
+ ecb_unused int ocur_ = (cur); \
1665
1966
  (base) = (type *)array_realloc \
1666
1967
  (sizeof (type), (base), &(cur), (cnt)); \
1667
1968
  init ((base) + (ocur_), (cur) - ocur_); \
@@ -1683,12 +1984,14 @@ array_realloc (int elem, void *base, int *cur, int cnt)
1683
1984
  /*****************************************************************************/
1684
1985
 
1685
1986
  /* dummy callback for pending events */
1686
- static void noinline
1987
+ noinline
1988
+ static void
1687
1989
  pendingcb (EV_P_ ev_prepare *w, int revents)
1688
1990
  {
1689
1991
  }
1690
1992
 
1691
- void noinline
1993
+ noinline
1994
+ void
1692
1995
  ev_feed_event (EV_P_ void *w, int revents) EV_THROW
1693
1996
  {
1694
1997
  W w_ = (W)w;
@@ -1828,7 +2131,8 @@ fd_reify (EV_P)
1828
2131
  }
1829
2132
 
1830
2133
  /* something about the given fd changed */
1831
- inline_size void
2134
+ inline_size
2135
+ void
1832
2136
  fd_change (EV_P_ int fd, int flags)
1833
2137
  {
1834
2138
  unsigned char reify = anfds [fd].reify;
@@ -1843,7 +2147,7 @@ fd_change (EV_P_ int fd, int flags)
1843
2147
  }
1844
2148
 
1845
2149
  /* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
1846
- inline_speed void ecb_cold
2150
+ inline_speed ecb_cold void
1847
2151
  fd_kill (EV_P_ int fd)
1848
2152
  {
1849
2153
  ev_io *w;
@@ -1856,7 +2160,7 @@ fd_kill (EV_P_ int fd)
1856
2160
  }
1857
2161
 
1858
2162
  /* check whether the given fd is actually valid, for error recovery */
1859
- inline_size int ecb_cold
2163
+ inline_size ecb_cold int
1860
2164
  fd_valid (int fd)
1861
2165
  {
1862
2166
  #ifdef _WIN32
@@ -1867,7 +2171,8 @@ fd_valid (int fd)
1867
2171
  }
1868
2172
 
1869
2173
  /* called on EBADF to verify fds */
1870
- static void noinline ecb_cold
2174
+ noinline ecb_cold
2175
+ static void
1871
2176
  fd_ebadf (EV_P)
1872
2177
  {
1873
2178
  int fd;
@@ -1879,7 +2184,8 @@ fd_ebadf (EV_P)
1879
2184
  }
1880
2185
 
1881
2186
  /* called on ENOMEM in select/poll to kill some fds and retry */
1882
- static void noinline ecb_cold
2187
+ noinline ecb_cold
2188
+ static void
1883
2189
  fd_enomem (EV_P)
1884
2190
  {
1885
2191
  int fd;
@@ -1893,7 +2199,8 @@ fd_enomem (EV_P)
1893
2199
  }
1894
2200
 
1895
2201
  /* usually called after fork if backend needs to re-arm all fds from scratch */
1896
- static void noinline
2202
+ noinline
2203
+ static void
1897
2204
  fd_rearm_all (EV_P)
1898
2205
  {
1899
2206
  int fd;
@@ -2084,7 +2391,8 @@ static ANSIG signals [EV_NSIG - 1];
2084
2391
 
2085
2392
  #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
2086
2393
 
2087
- static void noinline ecb_cold
2394
+ noinline ecb_cold
2395
+ static void
2088
2396
  evpipe_init (EV_P)
2089
2397
  {
2090
2398
  if (!ev_is_active (&pipe_w))
@@ -2106,8 +2414,6 @@ evpipe_init (EV_P)
2106
2414
  fd_intern (fds [0]);
2107
2415
  }
2108
2416
 
2109
- fd_intern (fds [1]);
2110
-
2111
2417
  evpipe [0] = fds [0];
2112
2418
 
2113
2419
  if (evpipe [1] < 0)
@@ -2123,6 +2429,8 @@ evpipe_init (EV_P)
2123
2429
  close (fds [1]);
2124
2430
  }
2125
2431
 
2432
+ fd_intern (evpipe [1]);
2433
+
2126
2434
  ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ);
2127
2435
  ev_io_start (EV_A_ &pipe_w);
2128
2436
  ev_unref (EV_A); /* watcher should not keep loop alive */
@@ -2272,7 +2580,8 @@ ev_sighandler (int signum)
2272
2580
  ev_feed_signal (signum);
2273
2581
  }
2274
2582
 
2275
- void noinline
2583
+ noinline
2584
+ void
2276
2585
  ev_feed_signal_event (EV_P_ int signum) EV_THROW
2277
2586
  {
2278
2587
  WL w;
@@ -2399,20 +2708,20 @@ childcb (EV_P_ ev_signal *sw, int revents)
2399
2708
  # include "ev_select.c"
2400
2709
  #endif
2401
2710
 
2402
- int ecb_cold
2711
+ ecb_cold int
2403
2712
  ev_version_major (void) EV_THROW
2404
2713
  {
2405
2714
  return EV_VERSION_MAJOR;
2406
2715
  }
2407
2716
 
2408
- int ecb_cold
2717
+ ecb_cold int
2409
2718
  ev_version_minor (void) EV_THROW
2410
2719
  {
2411
2720
  return EV_VERSION_MINOR;
2412
2721
  }
2413
2722
 
2414
2723
  /* return true if we are running with elevated privileges and should ignore env variables */
2415
- int inline_size ecb_cold
2724
+ inline_size ecb_cold int
2416
2725
  enable_secure (void)
2417
2726
  {
2418
2727
  #ifdef _WIN32
@@ -2423,7 +2732,8 @@ enable_secure (void)
2423
2732
  #endif
2424
2733
  }
2425
2734
 
2426
- unsigned int ecb_cold
2735
+ ecb_cold
2736
+ unsigned int
2427
2737
  ev_supported_backends (void) EV_THROW
2428
2738
  {
2429
2739
  unsigned int flags = 0;
@@ -2437,7 +2747,8 @@ ev_supported_backends (void) EV_THROW
2437
2747
  return flags;
2438
2748
  }
2439
2749
 
2440
- unsigned int ecb_cold
2750
+ ecb_cold
2751
+ unsigned int
2441
2752
  ev_recommended_backends (void) EV_THROW
2442
2753
  {
2443
2754
  unsigned int flags = ev_supported_backends ();
@@ -2459,7 +2770,8 @@ ev_recommended_backends (void) EV_THROW
2459
2770
  return flags;
2460
2771
  }
2461
2772
 
2462
- unsigned int ecb_cold
2773
+ ecb_cold
2774
+ unsigned int
2463
2775
  ev_embeddable_backends (void) EV_THROW
2464
2776
  {
2465
2777
  int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
@@ -2527,7 +2839,7 @@ ev_userdata (EV_P) EV_THROW
2527
2839
  }
2528
2840
 
2529
2841
  void
2530
- ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW
2842
+ ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW
2531
2843
  {
2532
2844
  invoke_cb = invoke_pending_cb;
2533
2845
  }
@@ -2541,7 +2853,8 @@ ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV
2541
2853
  #endif
2542
2854
 
2543
2855
  /* initialise a loop structure, must be zero-initialised */
2544
- static void noinline ecb_cold
2856
+ noinline ecb_cold
2857
+ static void
2545
2858
  loop_init (EV_P_ unsigned int flags) EV_THROW
2546
2859
  {
2547
2860
  if (!backend)
@@ -2638,7 +2951,8 @@ loop_init (EV_P_ unsigned int flags) EV_THROW
2638
2951
  }
2639
2952
 
2640
2953
  /* free up a loop structure */
2641
- void ecb_cold
2954
+ ecb_cold
2955
+ void
2642
2956
  ev_loop_destroy (EV_P)
2643
2957
  {
2644
2958
  int i;
@@ -2769,7 +3083,7 @@ loop_fork (EV_P)
2769
3083
  #endif
2770
3084
 
2771
3085
  #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
2772
- if (ev_is_active (&pipe_w))
3086
+ if (ev_is_active (&pipe_w) && postfork != 2)
2773
3087
  {
2774
3088
  /* pipe_write_wanted must be false now, so modifying fd vars should be safe */
2775
3089
 
@@ -2790,7 +3104,8 @@ loop_fork (EV_P)
2790
3104
 
2791
3105
  #if EV_MULTIPLICITY
2792
3106
 
2793
- struct ev_loop * ecb_cold
3107
+ ecb_cold
3108
+ struct ev_loop *
2794
3109
  ev_loop_new (unsigned int flags) EV_THROW
2795
3110
  {
2796
3111
  EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
@@ -2808,7 +3123,8 @@ ev_loop_new (unsigned int flags) EV_THROW
2808
3123
  #endif /* multiplicity */
2809
3124
 
2810
3125
  #if EV_VERIFY
2811
- static void noinline ecb_cold
3126
+ noinline ecb_cold
3127
+ static void
2812
3128
  verify_watcher (EV_P_ W w)
2813
3129
  {
2814
3130
  assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
@@ -2817,7 +3133,8 @@ verify_watcher (EV_P_ W w)
2817
3133
  assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
2818
3134
  }
2819
3135
 
2820
- static void noinline ecb_cold
3136
+ noinline ecb_cold
3137
+ static void
2821
3138
  verify_heap (EV_P_ ANHE *heap, int N)
2822
3139
  {
2823
3140
  int i;
@@ -2832,7 +3149,8 @@ verify_heap (EV_P_ ANHE *heap, int N)
2832
3149
  }
2833
3150
  }
2834
3151
 
2835
- static void noinline ecb_cold
3152
+ noinline ecb_cold
3153
+ static void
2836
3154
  array_verify (EV_P_ W *ws, int cnt)
2837
3155
  {
2838
3156
  while (cnt--)
@@ -2931,7 +3249,8 @@ ev_verify (EV_P) EV_THROW
2931
3249
  #endif
2932
3250
 
2933
3251
  #if EV_MULTIPLICITY
2934
- struct ev_loop * ecb_cold
3252
+ ecb_cold
3253
+ struct ev_loop *
2935
3254
  #else
2936
3255
  int
2937
3256
  #endif
@@ -2989,7 +3308,8 @@ ev_pending_count (EV_P) EV_THROW
2989
3308
  return count;
2990
3309
  }
2991
3310
 
2992
- void noinline
3311
+ noinline
3312
+ void
2993
3313
  ev_invoke_pending (EV_P)
2994
3314
  {
2995
3315
  pendingpri = NUMPRI;
@@ -3074,7 +3394,8 @@ timers_reify (EV_P)
3074
3394
 
3075
3395
  #if EV_PERIODIC_ENABLE
3076
3396
 
3077
- static void noinline
3397
+ noinline
3398
+ static void
3078
3399
  periodic_recalc (EV_P_ ev_periodic *w)
3079
3400
  {
3080
3401
  ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL;
@@ -3142,7 +3463,8 @@ periodics_reify (EV_P)
3142
3463
 
3143
3464
  /* simply recalculate all periodics */
3144
3465
  /* TODO: maybe ensure that at least one event happens when jumping forward? */
3145
- static void noinline ecb_cold
3466
+ noinline ecb_cold
3467
+ static void
3146
3468
  periodics_reschedule (EV_P)
3147
3469
  {
3148
3470
  int i;
@@ -3165,7 +3487,8 @@ periodics_reschedule (EV_P)
3165
3487
  #endif
3166
3488
 
3167
3489
  /* adjust all timers by a given offset */
3168
- static void noinline ecb_cold
3490
+ noinline ecb_cold
3491
+ static void
3169
3492
  timers_reschedule (EV_P_ ev_tstamp adjust)
3170
3493
  {
3171
3494
  int i;
@@ -3543,7 +3866,8 @@ ev_stop (EV_P_ W w)
3543
3866
 
3544
3867
  /*****************************************************************************/
3545
3868
 
3546
- void noinline
3869
+ noinline
3870
+ void
3547
3871
  ev_io_start (EV_P_ ev_io *w) EV_THROW
3548
3872
  {
3549
3873
  int fd = w->fd;
@@ -3569,7 +3893,8 @@ ev_io_start (EV_P_ ev_io *w) EV_THROW
3569
3893
  EV_FREQUENT_CHECK;
3570
3894
  }
3571
3895
 
3572
- void noinline
3896
+ noinline
3897
+ void
3573
3898
  ev_io_stop (EV_P_ ev_io *w) EV_THROW
3574
3899
  {
3575
3900
  clear_pending (EV_A_ (W)w);
@@ -3588,7 +3913,8 @@ ev_io_stop (EV_P_ ev_io *w) EV_THROW
3588
3913
  EV_FREQUENT_CHECK;
3589
3914
  }
3590
3915
 
3591
- void noinline
3916
+ noinline
3917
+ void
3592
3918
  ev_timer_start (EV_P_ ev_timer *w) EV_THROW
3593
3919
  {
3594
3920
  if (expect_false (ev_is_active (w)))
@@ -3612,7 +3938,8 @@ ev_timer_start (EV_P_ ev_timer *w) EV_THROW
3612
3938
  /*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
3613
3939
  }
3614
3940
 
3615
- void noinline
3941
+ noinline
3942
+ void
3616
3943
  ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
3617
3944
  {
3618
3945
  clear_pending (EV_A_ (W)w);
@@ -3642,7 +3969,8 @@ ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
3642
3969
  EV_FREQUENT_CHECK;
3643
3970
  }
3644
3971
 
3645
- void noinline
3972
+ noinline
3973
+ void
3646
3974
  ev_timer_again (EV_P_ ev_timer *w) EV_THROW
3647
3975
  {
3648
3976
  EV_FREQUENT_CHECK;
@@ -3676,7 +4004,8 @@ ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
3676
4004
  }
3677
4005
 
3678
4006
  #if EV_PERIODIC_ENABLE
3679
- void noinline
4007
+ noinline
4008
+ void
3680
4009
  ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
3681
4010
  {
3682
4011
  if (expect_false (ev_is_active (w)))
@@ -3706,7 +4035,8 @@ ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
3706
4035
  /*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
3707
4036
  }
3708
4037
 
3709
- void noinline
4038
+ noinline
4039
+ void
3710
4040
  ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
3711
4041
  {
3712
4042
  clear_pending (EV_A_ (W)w);
@@ -3734,7 +4064,8 @@ ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
3734
4064
  EV_FREQUENT_CHECK;
3735
4065
  }
3736
4066
 
3737
- void noinline
4067
+ noinline
4068
+ void
3738
4069
  ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
3739
4070
  {
3740
4071
  /* TODO: use adjustheap and recalculation */
@@ -3749,7 +4080,8 @@ ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
3749
4080
 
3750
4081
  #if EV_SIGNAL_ENABLE
3751
4082
 
3752
- void noinline
4083
+ noinline
4084
+ void
3753
4085
  ev_signal_start (EV_P_ ev_signal *w) EV_THROW
3754
4086
  {
3755
4087
  if (expect_false (ev_is_active (w)))
@@ -3831,7 +4163,8 @@ ev_signal_start (EV_P_ ev_signal *w) EV_THROW
3831
4163
  EV_FREQUENT_CHECK;
3832
4164
  }
3833
4165
 
3834
- void noinline
4166
+ noinline
4167
+ void
3835
4168
  ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
3836
4169
  {
3837
4170
  clear_pending (EV_A_ (W)w);
@@ -3917,14 +4250,15 @@ ev_child_stop (EV_P_ ev_child *w) EV_THROW
3917
4250
  #define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */
3918
4251
  #define MIN_STAT_INTERVAL 0.1074891
3919
4252
 
3920
- static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
4253
+ noinline static void stat_timer_cb (EV_P_ ev_timer *w_, int revents);
3921
4254
 
3922
4255
  #if EV_USE_INOTIFY
3923
4256
 
3924
4257
  /* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
3925
4258
  # define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX)
3926
4259
 
3927
- static void noinline
4260
+ noinline
4261
+ static void
3928
4262
  infy_add (EV_P_ ev_stat *w)
3929
4263
  {
3930
4264
  w->wd = inotify_add_watch (fs_fd, w->path,
@@ -3998,7 +4332,8 @@ infy_add (EV_P_ ev_stat *w)
3998
4332
  if (ev_is_active (&w->timer)) ev_unref (EV_A);
3999
4333
  }
4000
4334
 
4001
- static void noinline
4335
+ noinline
4336
+ static void
4002
4337
  infy_del (EV_P_ ev_stat *w)
4003
4338
  {
4004
4339
  int slot;
@@ -4015,7 +4350,8 @@ infy_del (EV_P_ ev_stat *w)
4015
4350
  inotify_rm_watch (fs_fd, wd);
4016
4351
  }
4017
4352
 
4018
- static void noinline
4353
+ noinline
4354
+ static void
4019
4355
  infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
4020
4356
  {
4021
4357
  if (slot < 0)
@@ -4061,7 +4397,8 @@ infy_cb (EV_P_ ev_io *w, int revents)
4061
4397
  }
4062
4398
  }
4063
4399
 
4064
- inline_size void ecb_cold
4400
+ inline_size ecb_cold
4401
+ void
4065
4402
  ev_check_2625 (EV_P)
4066
4403
  {
4067
4404
  /* kernels < 2.6.25 are borked
@@ -4169,7 +4506,8 @@ ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
4169
4506
  w->attr.st_nlink = 1;
4170
4507
  }
4171
4508
 
4172
- static void noinline
4509
+ noinline
4510
+ static void
4173
4511
  stat_timer_cb (EV_P_ ev_timer *w_, int revents)
4174
4512
  {
4175
4513
  ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));
@@ -4389,7 +4727,8 @@ ev_check_stop (EV_P_ ev_check *w) EV_THROW
4389
4727
  #endif
4390
4728
 
4391
4729
  #if EV_EMBED_ENABLE
4392
- void noinline
4730
+ noinline
4731
+ void
4393
4732
  ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW
4394
4733
  {
4395
4734
  ev_run (w->other, EVRUN_NOWAIT);
@@ -4696,7 +5035,8 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
4696
5035
  /*****************************************************************************/
4697
5036
 
4698
5037
  #if EV_WALK_ENABLE
4699
- void ecb_cold
5038
+ ecb_cold
5039
+ void
4700
5040
  ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW
4701
5041
  {
4702
5042
  int i, j;