|
5 | 5 | #include <stdio.h> |
6 | 6 | #include <stdbool.h> |
7 | 7 | #include <assert.h> |
| 8 | +#include <math.h> |
| 9 | +#include <fenv.h> |
8 | 10 | #include <gasnetex.h> |
9 | 11 | #include <gasnet_coll.h> |
10 | 12 | #include <gasnet_vis.h> |
@@ -34,6 +36,22 @@ typedef uint8_t byte; |
34 | 36 | static void event_init(void); |
35 | 37 | static void atomic_init(void); |
36 | 38 |
|
| 39 | +// --------------------------------------------------- |
| 40 | +// Floating-point exception support |
| 41 | + |
| 42 | +#ifndef IEEE_FE_MASK |
| 43 | +#define IEEE_FE_MASK FE_INEXACT |
| 44 | +#endif |
| 45 | +static fexcept_t fe_flag_save; |
| 46 | +void caf_fe_save(void) { |
| 47 | + fegetexceptflag(&fe_flag_save, IEEE_FE_MASK); |
| 48 | +} |
| 49 | +void caf_fe_restore(void) { |
| 50 | + fesetexceptflag(&fe_flag_save, IEEE_FE_MASK); |
| 51 | +} |
| 52 | +#define CHECK_INEXACT() \ |
| 53 | + printf("%3i: inexact flag = %s\n",__LINE__,fetestexcept(FE_INEXACT) & FE_INEXACT ? "YES" : "no") |
| 54 | + |
37 | 55 | // --------------------------------------------------- |
38 | 56 | int caf_this_image(gex_TM_t tm) { |
39 | 57 | return gex_TM_QueryRank(tm) + 1; |
@@ -142,7 +160,14 @@ void caf_allocate_remaining(mspace heap, void** allocated_space, size_t* allocat |
142 | 160 | // nor necessarily the largest open space, but in practice is likely |
143 | 161 | // to work out that way |
144 | 162 | struct mallinfo heap_info = mspace_mallinfo(heap); |
145 | | - *allocated_size = heap_info.keepcost * 0.9f; |
| 163 | + |
| 164 | + // clang's implementation of nearbyint() raises FE_INEXACT, |
| 165 | + // in direct contradiction to its specified purpose. |
| 166 | + // Workaround this defect by saving and restoring the FE flags |
| 167 | + caf_fe_save(); |
| 168 | + *allocated_size = (size_t)nearbyint(heap_info.keepcost * 0.9f); |
| 169 | + caf_fe_restore(); |
| 170 | + |
146 | 171 | *allocated_space = mspace_memalign(heap, 8, *allocated_size); |
147 | 172 | if (!*allocated_space) // uh-oh, something went wrong.. |
148 | 173 | gasnett_fatalerror("caf_allocate_remaining failed to mspace_memalign(%"PRIuSZ")", |
|
0 commit comments