-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgasnet_tools.c
More file actions
4334 lines (3970 loc) · 157 KB
/
Copy pathgasnet_tools.c
File metadata and controls
4334 lines (3970 loc) · 157 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* $Source: github.com:BerkeleyLab/gasnet.git/gasnet_tools.c $
* Description: GASNet implementation of internal helpers
* Copyright 2002, Dan Bonachea <bonachea@cs.berkeley.edu>
* Terms of use are as specified in license.txt
*/
#if defined(GASNETT_THREAD_SAFE) || defined(GASNETT_THREAD_SINGLE)
/* nothing */
#elif defined(GASNET_PAR)
#define GASNETT_THREAD_SAFE 1
#elif defined(GASNET_SEQ) || defined(GASNET_PARSYNC)
#define GASNETT_THREAD_SINGLE 1
#else
#error Missing threading definition
#endif
// this file is built for exactly one of libgasnet/tools or libgasnet/conduit
#if (GASNETI_BUILDING_TOOLS && GASNETI_BUILDING_CONDUIT) || (!GASNETI_BUILDING_TOOLS && !GASNETI_BUILDING_CONDUIT)
#error Invalid GASNETI_BUILDING_ macro
#endif
#undef GASNET_SEQ
#undef GASNET_PAR
#undef GASNET_PARSYNC
#include <gasnet_tools.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h> /* gasneti_system_redirected_coprocess */
#include <sys/select.h>
#include <fcntl.h>
#include <time.h> /* gasneti_gettimeofday_us, gasneti_nsleep */
#include <sys/time.h> /* gasneti_gettimeofday_us, gasneti_nsleep */
#include <signal.h>
#if HAVE_EXECINFO_H
#include <execinfo.h>
#endif
#ifdef HAVE_UCONTEXT_H
#include <ucontext.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#if PLATFORM_OS_CYGWIN
#include <cygwin/version.h>
#endif
#if HAVE_PR_SET_PTRACER
#include <sys/prctl.h>
#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61 /* 'Yama' */
#endif
#ifndef PR_SET_PTRACER_ANY
#define PR_SET_PTRACER_ANY ((unsigned long)(-1))
#endif
#endif
#if PLATFORM_OS_DARWIN
#include <sys/utsname.h> // uname()
#endif
#if PLATFORM_COMPILER_SUN_C
/* disable warnings triggerred by some macro idioms we use */
#pragma error_messages(off, E_END_OF_LOOP_CODE_NOT_REACHED)
#pragma error_messages(off, E_STATEMENT_NOT_REACHED)
#endif
int _gasneti_unused_result = -1;
/* ------------------------------------------------------------------------------------ */
/* generic atomics support */
#if GASNETI_BUILDING_TOOLS && \
(defined(GASNETI_BUILD_GENERIC_ATOMIC32) || defined(GASNETI_BUILD_GENERIC_ATOMIC64))
#ifdef GASNETI_ATOMIC_LOCK_TBL_DEFNS
GASNETI_ATOMIC_LOCK_TBL_DEFNS(malloc)
#endif
#ifdef GASNETI_GENATOMIC32_DEFN
GASNETI_GENATOMIC32_DEFN
#endif
#ifdef GASNETI_GENATOMIC64_DEFN
GASNETI_GENATOMIC64_DEFN
#endif
#endif
#if GASNETI_MUTEX_CAUTIOUS_INIT
#if GASNETI_ATOMIC32_NOT_SIGNALSAFE
#error GASNETI_MUTEX_CAUTIOUS_INIT requires !GASNETI_ATOMIC32_NOT_SIGNALSAFE
#endif
/* initstep values: 0 = initial value for a new mutex
1 = initialization of mutex in progress by some thread
2 = mutex is fully initialized and ready for use
*/
extern void gasneti_mutex_cautious_init(/*gasneti_mutex_t*/void *_pl) {
gasneti_mutex_t *pl = _pl;
gasneti_atomic32_t *initstep = (gasneti_atomic32_t *)&(pl->initstep);
while (1) {
/* check if initialization is complete */
if_pt (gasneti_atomic32_read(initstep,GASNETI_ATOMIC_RMB_POST) == 2) return;
/* mutex needs initialization, try to acquire that job */
if (gasneti_atomic32_compare_and_swap(initstep, 0, 1,
GASNETI_ATOMIC_ACQ_IF_TRUE)) break;
/* some other thread beat us to it */
gasneti_sched_yield();
}
/* perform an uncontended lock/unlock cycle on the new mutex,
to ensure pthread library data structures are correctly created */
gasneti_assert_zeroret(pthread_mutex_lock(&(pl->lock)));
gasneti_assert_zeroret(pthread_mutex_unlock(&(pl->lock)));
/* init complete, release */
gasneti_atomic32_set(initstep, 2, GASNETI_ATOMIC_WMB_PRE);
return;
}
#endif
#if GASNETI_BUG3430_WORKAROUND
// Only used subject to GASNETI_USE_TRUE_MUTEXES, but that is not always available
gasneti_mutex_t gasneti_bug3430_lock = GASNETI_MUTEX_INITIALIZER;
gasneti_cond_t gasneti_bug3430_cond = GASNETI_COND_INITIALIZER;
volatile int gasneti_bug3430_creating = 0;
#endif
/* ------------------------------------------------------------------------------------ */
/* rwlock support */
#if GASNET_DEBUG || GASNETI_BUILDING_TOOLS
/* Use a thread-specific list of locks held, to avoid the need for extra synchronization.
* If a thread exits with locks held we currently leak this list, although if it ever matters
* this could be fixed using a destructor function in pthread_key_create.
*/
GASNETI_THREADKEY_DEFINE(_gasneti_rwlock_list);
typedef struct _S_gasnet_rwlocklist {
gasneti_rwlock_t const *l;
struct _S_gasnet_rwlocklist *next;
_gasneti_rwlock_state state;
} _gasneti_rwlocklist_t;
extern _gasneti_rwlock_state _gasneti_rwlock_query(gasneti_rwlock_t const *l) {
_gasneti_rwlocklist_t const *list = gasneti_threadkey_get(_gasneti_rwlock_list);
gasneti_assert(l);
while (list) {
if (list->l == l) return list->state;
list = list->next;
}
return _GASNETI_RWLOCK_UNLOCKED;
}
extern void _gasneti_rwlock_insert(gasneti_rwlock_t const *l, _gasneti_rwlock_state state) {
_gasneti_rwlocklist_t *list = gasneti_threadkey_get(_gasneti_rwlock_list);
_gasneti_rwlocklist_t *elem = malloc(sizeof(_gasneti_rwlocklist_t));
gasneti_assert(l);
gasneti_assert(state);
elem->l = l;
elem->state = state;
elem->next = list;
gasneti_threadkey_set(_gasneti_rwlock_list, elem);
}
extern void _gasneti_rwlock_remove(gasneti_rwlock_t const *l) {
_gasneti_rwlocklist_t *list = gasneti_threadkey_get(_gasneti_rwlock_list);
_gasneti_rwlocklist_t **p = &list;
gasneti_assert(l);
while (*p) {
if ((*p)->l == l) {
_gasneti_rwlocklist_t *elem = *p;
*p = elem->next;
free(elem);
break;
}
p = &(*p)->next;
}
gasneti_threadkey_set(_gasneti_rwlock_list, list);
}
#endif
/* ------------------------------------------------------------------------------------ */
/* call-based atomic support for C compilers with limited inline assembly */
#ifdef GASNETI_ATOMIC32_SPECIALS
GASNETI_ATOMIC32_SPECIALS
#endif
#ifdef GASNETI_ATOMIC64_SPECIALS
GASNETI_ATOMIC64_SPECIALS
#endif
/* ------------------------------------------------------------------------------------ */
/* call-based membar/atomic support for compilers which lack inline assembly of configured CC */
#if defined(GASNETI_USING_SLOW_ATOMICOPS) || \
defined(GASNETI_USING_SLOW_ATOMIC32) || \
defined(GASNETI_USING_SLOW_ATOMIC64) || \
defined(GASNETI_USING_SLOW_MEMBARS)
#error gasnet_tools.c must be compiled with support for inline assembly
#endif
#ifdef GASNETI_TICKS_NOW_BODY
GASNETI_SPECIAL_ASM_DEFN(gasneti_slow_ticks_now, GASNETI_TICKS_NOW_BODY)
#else
extern gasneti_tick_t gasneti_slow_ticks_now(void) {
return gasneti_ticks_now();
}
#endif
#ifdef GASNETI_COMPILER_FENCE_BODY
GASNETI_SPECIAL_ASM_DEFN(gasneti_slow_compiler_fence, GASNETI_COMPILER_FENCE_BODY)
#else
extern void gasneti_slow_compiler_fence(void) {
gasneti_compiler_fence();
}
#endif
#ifdef GASNETI_LOCAL_WMB_BODY
GASNETI_SPECIAL_ASM_DEFN(gasneti_slow_local_wmb, GASNETI_LOCAL_WMB_BODY)
#else
extern void gasneti_slow_local_wmb(void) {
gasneti_local_wmb();
}
#endif
#ifdef GASNETI_LOCAL_RMB_BODY
GASNETI_SPECIAL_ASM_DEFN(gasneti_slow_local_rmb, GASNETI_LOCAL_RMB_BODY)
#else
extern void gasneti_slow_local_rmb(void) {
gasneti_local_rmb();
}
#endif
#ifdef GASNETI_LOCAL_MB_BODY
GASNETI_SPECIAL_ASM_DEFN(gasneti_slow_local_mb, GASNETI_LOCAL_MB_BODY)
#else
extern void gasneti_slow_local_mb(void) {
gasneti_local_mb();
}
#endif
/* Warn (once) if slow atomics are reached */
static int gasneti_slow_atomic_warning_issued = 0;
GASNETI_NEVER_INLINE(gasneti_slow_atomic_warn,
static void gasneti_slow_atomic_warn(void)) {
gasneti_slow_atomic_warning_issued = 1;
gasneti_console_message("WARNING",
"using slow atomics due to use of a compiler not probed by GASNet at configure time");
}
#define GASNETI_SLOW_ATOMIC_WARNING() do { \
if_pf (! gasneti_slow_atomic_warning_issued) gasneti_slow_atomic_warn(); \
} while (0)
#ifdef GASNETI_USE_GENERIC_ATOMICOPS
/* We don't need or want slow versions of generics (they use no ASM) */
#else
extern gasneti_atomic_val_t gasneti_slow_atomic_read(gasneti_atomic_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic_read(p,flags);
}
extern void gasneti_slow_atomic_set(gasneti_atomic_t *p, gasneti_atomic_val_t v, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic_set(p, v, flags);
}
extern void gasneti_slow_atomic_increment(gasneti_atomic_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic_increment(p, flags);
}
extern void gasneti_slow_atomic_decrement(gasneti_atomic_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic_decrement(p, flags);
}
extern int gasneti_slow_atomic_decrement_and_test(gasneti_atomic_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic_decrement_and_test(p, flags);
}
#if defined(GASNETI_HAVE_ATOMIC_CAS)
extern int gasneti_slow_atomic_compare_and_swap(gasneti_atomic_t *p, gasneti_atomic_val_t oldval, gasneti_atomic_val_t newval, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic_compare_and_swap(p,oldval,newval,flags);
}
extern gasneti_atomic_val_t gasneti_slow_atomic_swap(gasneti_atomic_t *p, gasneti_atomic_val_t val, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic_swap(p,val,flags);
}
#endif
#if defined(GASNETI_HAVE_ATOMIC_ADD_SUB)
extern gasneti_atomic_val_t gasneti_slow_atomic_add(gasneti_atomic_t *p, gasneti_atomic_val_t op, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic_add(p,op,flags);
}
extern gasneti_atomic_val_t gasneti_slow_atomic_subtract(gasneti_atomic_t *p, gasneti_atomic_val_t op, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic_subtract(p,op,flags);
}
#endif
#endif
#ifdef GASNETI_USE_GENERIC_ATOMIC32
/* We don't need or want slow versions of generics (they use no ASM) */
#else
extern uint32_t gasneti_slow_atomic32_read(gasneti_atomic32_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic32_read(p,flags);
}
extern void gasneti_slow_atomic32_set(gasneti_atomic32_t *p, uint32_t v, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic32_set(p, v, flags);
}
extern void gasneti_slow_atomic32_increment(gasneti_atomic32_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic32_increment(p, flags);
}
extern void gasneti_slow_atomic32_decrement(gasneti_atomic32_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic32_decrement(p, flags);
}
extern int gasneti_slow_atomic32_decrement_and_test(gasneti_atomic32_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic32_decrement_and_test(p, flags);
}
extern int gasneti_slow_atomic32_compare_and_swap(gasneti_atomic32_t *p, uint32_t oldval, uint32_t newval, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic32_compare_and_swap(p,oldval,newval,flags);
}
extern uint32_t gasneti_slow_atomic32_swap(gasneti_atomic32_t *p, uint32_t val, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic32_swap(p,val,flags);
}
extern uint32_t gasneti_slow_atomic32_add(gasneti_atomic32_t *p, uint32_t op, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic32_add(p,op,flags);
}
extern uint32_t gasneti_slow_atomic32_subtract(gasneti_atomic32_t *p, uint32_t op, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic32_subtract(p,op,flags);
}
#endif
#ifdef GASNETI_USE_GENERIC_ATOMIC64
/* We don't need or want slow versions of generics (they use no ASM) */
#else
extern uint64_t gasneti_slow_atomic64_read(gasneti_atomic64_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic64_read(p,flags);
}
extern void gasneti_slow_atomic64_set(gasneti_atomic64_t *p, uint64_t v, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic64_set(p, v, flags);
}
extern void gasneti_slow_atomic64_increment(gasneti_atomic64_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic64_increment(p, flags);
}
extern void gasneti_slow_atomic64_decrement(gasneti_atomic64_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
gasneti_atomic64_decrement(p, flags);
}
extern int gasneti_slow_atomic64_decrement_and_test(gasneti_atomic64_t *p, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic64_decrement_and_test(p, flags);
}
extern int gasneti_slow_atomic64_compare_and_swap(gasneti_atomic64_t *p, uint64_t oldval, uint64_t newval, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic64_compare_and_swap(p,oldval,newval,flags);
}
extern uint64_t gasneti_slow_atomic64_swap(gasneti_atomic64_t *p, uint64_t val, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic64_swap(p,val,flags);
}
extern uint64_t gasneti_slow_atomic64_add(gasneti_atomic64_t *p, uint64_t op, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic64_add(p,op,flags);
}
extern uint64_t gasneti_slow_atomic64_subtract(gasneti_atomic64_t *p, uint64_t op, const int flags) {
GASNETI_SLOW_ATOMIC_WARNING();
return gasneti_atomic64_subtract(p,op,flags);
}
#endif
/* ------------------------------------------------------------------------------------ */
/* ident strings and idiot checks */
#define GASNETT_THREAD_MODEL_STR _STRINGIFY(GASNETT_THREAD_MODEL)
GASNETI_IDENT(gasnett_IdentString_ThreadModel, "$GASNetToolsThreadModel: " GASNETT_THREAD_MODEL_STR " $");
GASNETI_IDENT(gasnett_IdentString_Config, "$GASNetToolsConfig: " GASNETT_CONFIG_STRING " $");
GASNETI_IDENT(gasnett_IdentString_BuildTimestamp,
"$GASNetBuildTimestamp: " __DATE__ " " __TIME__ " $");
GASNETI_IDENT(gasnett_IdentString_BuildID,
"$GASNetBuildId: " GASNETI_BUILD_ID " $");
GASNETI_IDENT(gasnett_IdentString_ConfigureArgs,
"$GASNetConfigureArgs: " GASNETI_CONFIGURE_ARGS " $");
GASNETI_IDENT(gasnett_IdentString_SystemTuple,
"$GASNetSystemTuple: " GASNETI_SYSTEM_TUPLE " $");
GASNETI_IDENT(gasnett_IdentString_SystemName,
"$GASNetSystemName: " GASNETI_SYSTEM_NAME " $");
GASNETI_IDENT(gasnett_IdentString_CompilerID,
"$GASNetCompilerID: " PLATFORM_COMPILER_IDSTR " $");
#ifndef GASNETI_GIT_HASH
#define GASNETI_GIT_HASH no-version-control-info
#endif
GASNETI_IDENT(gasnett_IdentString_GitHash,
"$GASNetGitHash: " _STRINGIFY(GASNETI_GIT_HASH) " $");
int GASNETT_LINKCONFIG_IDIOTCHECK(_CONCAT(RELEASE_MAJOR_,GASNET_RELEASE_VERSION_MAJOR)) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(_CONCAT(RELEASE_MINOR_,GASNET_RELEASE_VERSION_MINOR)) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(_CONCAT(RELEASE_PATCH_,GASNET_RELEASE_VERSION_PATCH)) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(LITE) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETT_THREAD_MODEL) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETT_DEBUG_CONFIG) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETT_PTR_CONFIG) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETT_TIMER_CONFIG) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETT_MEMBAR_CONFIG) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETT_ATOMIC_CONFIG) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETI_ATOMIC32_CONFIG) = 1;
int GASNETT_LINKCONFIG_IDIOTCHECK(GASNETI_ATOMIC64_CONFIG) = 1;
static gasneti_atomic_t gasneti_backtrace_enabled = gasneti_atomic_init(1);
static int volatile gasneti_internal_crash = 0;
extern uint64_t gasnett_release_version(void) { // motivated by xSDK Community Policy M8
return GASNET_RELEASE_VERSION_MAJOR * (uint64_t)1000000 +
GASNET_RELEASE_VERSION_MINOR * (uint64_t)10000 +
GASNET_RELEASE_VERSION_PATCH;
}
extern const char *gasnett_release_version_str(void) { // motivated by xSDK Community Policy M8
return _STRINGIFY(GASNET_RELEASE_VERSION_MAJOR) "."
_STRINGIFY(GASNET_RELEASE_VERSION_MINOR) "."
_STRINGIFY(GASNET_RELEASE_VERSION_PATCH);
}
extern const char *gasnett_performance_warning_str(void) {
static const char *result =
#if defined(GASNET_DEBUG) || defined(GASNETI_STATS_OR_TRACE) || defined(GASNET_DEBUGMALLOC)
" " /* Leading white space: */
#ifdef GASNET_DEBUG
"debugging "
#endif
#ifdef GASNET_TRACE
"tracing "
#endif
#ifdef GASNET_STATS
"statistical collection "
#endif
#ifdef GASNET_DEBUGMALLOC
"debugging malloc "
#endif
"\n" /* Trailing white space: */
#endif
#if defined(GASNETI_FORCE_GENERIC_ATOMICOPS)
" FORCED mutex-based atomicops\n"
#elif defined(GASNETI_FORCE_OS_ATOMICOPS)
" FORCED os-provided atomicops\n"
#endif
#if defined(GASNETI_FORCE_TRUE_WEAKATOMICS) && GASNETT_THREAD_SINGLE
" FORCED atomics in sequential code\n"
#endif
#if defined(GASNETI_FORCE_GENERIC_SEMAPHORES) && GASNETT_THREAD_SAFE
" FORCED mutex-based semaphores\n"
#endif
#if defined(GASNETI_FORCE_YIELD_MEMBARS)
" FORCED sched_yield() in memory barriers\n"
#elif defined(GASNETI_FORCE_SLOW_MEMBARS)
" FORCED non-inlined memory barriers\n"
#endif
#if defined(GASNETI_FORCE_GETTIMEOFDAY)
" FORCED timers using gettimeofday()\n"
#elif defined(GASNETI_FORCE_POSIX_REALTIME)
" FORCED timers using clock_gettime()\n"
#endif
#if defined(GASNETI_BUG1389_WORKAROUND)
" FORCED conservative byte-wise local access\n"
#endif
"";
return result;
}
/* ------------------------------------------------------------------------------------ */
/* hostname query */
/* get MAXHOSTNAMELEN */
#if PLATFORM_OS_SOLARIS
#include <netdb.h>
#else
#include <sys/param.h>
#endif
#ifndef MAXHOSTNAMELEN
#ifdef HOST_NAME_MAX
#define MAXHOSTNAMELEN HOST_NAME_MAX
#else
#define MAXHOSTNAMELEN 1024 /* give up */
#endif
#endif
const char *gasneti_gethostname(void) {
static gasneti_mutex_t hnmutex = GASNETI_MUTEX_INITIALIZER;
static int firsttime = 1;
static char hostname[MAXHOSTNAMELEN];
gasneti_mutex_lock(&hnmutex);
if (firsttime) {
if (gethostname(hostname, MAXHOSTNAMELEN))
gasnett_fatalerror("gasneti_gethostname() failed to get hostname: aborting");
hostname[MAXHOSTNAMELEN - 1] = '\0';
size_t len = strlen(hostname);
// Scan for chars that suggest anything other than 7-bit ASCII
int safe = 1;
for (int i = 0; i < len; ++i) {
if (iscntrl(hostname[i])) {
safe = 0;
break;
}
}
// Normalize to lowercase if it looks "safe" to do so
if (safe) {
for (int i = 0; i < len; ++i) { hostname[i] = tolower(hostname[i]); }
}
firsttime = 0;
}
gasneti_mutex_unlock(&hnmutex);
return hostname;
}
/* ------------------------------------------------------------------------------------ */
/* sleep/delay support */
/* Sleep for at least ns_delay nanoseconds
* If interrupted by signal, may terminate early returning non-zero with errno = EINTR
*/
extern int gasneti_nsleep(uint64_t ns_delay) {
if_pf (!ns_delay) return 0;
#if HAVE_NANOSLEEP
struct timespec ts;
ts.tv_sec = ns_delay / (uint64_t)1E9;
ts.tv_nsec = ns_delay % (uint64_t)1E9;
return nanosleep(&ts, NULL);
#elif HAVE_CLOCK_NANOSLEEP
struct timespec ts;
ts.tv_sec = ns_delay / (uint64_t)1E9;
ts.tv_nsec = ns_delay % (uint64_t)1E9;
return clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
#elif HAVE_NSLEEP
struct timespec ts;
ts.tv_sec = ns_delay / (uint64_t)1E9;
ts.tv_nsec = ns_delay % (uint64_t)1E9;
return nsleep(&ts, NULL);
#elif HAVE_USLEEP && 0
// Disabled because:
// 1) some systems prohibit us_delay > 1 million
// 2) some systems have undesired interactions with alarm()
return usleep(ns_delay / 1000);
#else
struct timeval tv;
uint64_t us_delay = ns_delay / 1000;
tv.tv_sec = us_delay / (uint64_t)1E6;
tv.tv_usec = us_delay % (uint64_t)1E6;
return select(0, NULL, NULL, NULL, &tv);
#endif
}
/* ------------------------------------------------------------------------------------ */
/* timer support */
#ifdef GASNETI_TIMER_DEFN
GASNETI_TIMER_DEFN
#endif
GASNETI_INLINE(_gasneti_gettimeofday_us)
uint64_t _gasneti_gettimeofday_us(void) {
uint64_t retval;
struct timeval tv;
gasneti_assert_zeroret(gettimeofday(&tv, NULL));
retval = ((uint64_t)tv.tv_sec) * 1000000 + (uint64_t)tv.tv_usec;
return retval;
}
extern uint64_t gasneti_gettimeofday_us(void) { return _gasneti_gettimeofday_us(); }
GASNETI_INLINE(_gasneti_wallclock_ns)
uint64_t _gasneti_wallclock_ns(void) {
#if HAVE_CLOCK_GETTIME
struct timespec tm;
#if defined(_POSIX_MONOTONIC_CLOCK)
static clockid_t clockid = CLOCK_MONOTONIC;
if_pf (clock_gettime(clockid,&tm)) {
clockid = CLOCK_REALTIME; // next call will succeed
gasneti_assert_zeroret(clock_gettime(CLOCK_REALTIME,&tm));
}
#else
gasneti_assert_zeroret(clock_gettime(CLOCK_REALTIME,&tm));
#endif
return tm.tv_sec*((uint64_t)1E9)+tm.tv_nsec;
#else
struct timeval tv;
gasneti_assert_zeroret(gettimeofday(&tv, NULL));
return ((uint64_t)tv.tv_sec)*1000000000 + ((uint64_t)tv.tv_usec)*1000;
#endif
}
extern uint64_t gasneti_wallclock_ns(void) { return _gasneti_wallclock_ns(); }
// Conditionally available:
#if GASNETI_USING_GETTIMEOFDAY // Used *only* for gtod-based timers:
extern uint64_t gasneti_ticks_gtod_us(void) { return _gasneti_gettimeofday_us(); }
#endif
#if GASNETI_USING_POSIX_REALTIME // Used *only* for POSIX-RT timers:
extern uint64_t gasneti_ticks_posix_ns(void) { return _gasneti_wallclock_ns(); }
#endif
extern double gasneti_tick_metric(int idx) {
static double *_gasneti_tick_metric = NULL;
gasneti_assert_int(idx ,<=, 1);
if_pf (_gasneti_tick_metric == NULL) {
int i, ticks, iters = 1000, minticks = 10;
double *_tmp_metric;
gasneti_tick_t min = GASNETI_TICK_MAX;
gasneti_tick_t start = gasneti_ticks_now();
gasneti_tick_t last = start;
for (i=0,ticks=0; i < iters || ticks < minticks; i++) {
gasneti_tick_t x = gasneti_ticks_now();
gasneti_tick_t curr = (x - last);
if_pt (curr > 0) {
ticks++;
if_pf (curr < min) min = curr;
}
last = x;
}
_tmp_metric = (double *)malloc(2*sizeof(double));
gasneti_assert(_tmp_metric != NULL);
/* granularity */
gasneti_assert(min > 0);
uint64_t min_ns = gasneti_ticks_to_ns(min);
if (!min_ns) min_ns = 1; // Never report a granularity of 0
_tmp_metric[0] = ((double)min_ns)/1000.0;
/* overhead */
_tmp_metric[1] = ((double)(gasneti_ticks_to_ns(last - start)))/(i*1000.0);
gasneti_sync_writes();
_gasneti_tick_metric = _tmp_metric;
} else gasneti_sync_reads();
return _gasneti_tick_metric[idx];
}
/* ------------------------------------------------------------------------------------ */
#ifndef GASNETI_MAYBE_TRACEFILE
#if GASNET_TRACE && GASNETI_BUILDING_CONDUIT
extern FILE *gasneti_tracefile;
#define GASNETI_MAYBE_TRACEFILE gasneti_tracefile
#else
#define GASNETI_MAYBE_TRACEFILE ((FILE *)NULL)
#endif
#endif
#if GASNETI_BUILDING_CONDUIT
// shadows gasnet_fwd.h, which is deliberately excluded:
extern uint32_t gasneti_mynode;
#define GASNETI_PROCID gasneti_mynode
#define GASNETI_PROCID_INVALID ((uint32_t)-1)
#else
#define GASNETI_PROCID 0
#define GASNETI_PROCID_INVALID -1
#endif
extern const char *gasneti_procid_str;
const char *gasneti_procid_str = NULL;
extern void gasneti_console_messageVA(const char *funcname, const char *filename, int linenum,
int console_procid, // -1 == wildcard
const char *prefix, const char *msg, va_list argptr) {
#ifndef GASNETI_CONSOLEMSG_PREFIX_LEN
#define GASNETI_CONSOLEMSG_PREFIX_LEN 128
#endif
#ifndef GASNETI_CONSOLEMSG_IDSTR_LEN
#define GASNETI_CONSOLEMSG_IDSTR_LEN MIN(MAXHOSTNAMELEN,128)
#endif
#ifndef GASNETI_CONSOLEMSG_CONTEXT_LEN
#define GASNETI_CONSOLEMSG_CONTEXT_LEN 128
#endif
int console_speak = 1;
char expandedmsg[GASNETI_CONSOLEMSG_PREFIX_LEN+GASNETI_CONSOLEMSG_IDSTR_LEN+GASNETI_CONSOLEMSG_CONTEXT_LEN+20];
if (console_procid >= 0) { // omit proc id for "job-wide" messages
snprintf(expandedmsg, sizeof(expandedmsg)-4, "*** %s: ", prefix);
console_speak = (console_procid == GASNETI_PROCID) // I am the walrus
|| (GASNETI_PROCID == GASNETI_PROCID_INVALID); // too early to know, assume I am the walrus
} else if (gasneti_procid_str) {
snprintf(expandedmsg, sizeof(expandedmsg)-4, "*** %s (%s): ", prefix, gasneti_procid_str);
} else {
// we are either in tools-only mode or early in conduit startup before procid's are established
// try to provide some useful information to identify the failing process.
int pid = (int)getpid();
// Do NOT use gasneti_gethostname here, too many dependencies and chance of recursion
char hostname[MAXHOSTNAMELEN];
if (!gethostname(hostname, MAXHOSTNAMELEN) &&
hostname[0] && strlen(hostname) < GASNETI_CONSOLEMSG_IDSTR_LEN) {
snprintf(expandedmsg, sizeof(expandedmsg)-4, "*** %s (%s:%i): ", prefix, hostname, pid);
} else { // no idstr easily accessible
snprintf(expandedmsg, sizeof(expandedmsg)-4, "*** %s (:%i): ", prefix, pid);
}
}
if (funcname || filename) { // append location information, if any
#ifndef GASNETI_CONSOLEMSG_NAME_LEN
#define GASNETI_CONSOLEMSG_NAME_LEN 55
#endif
// use the last NAME_LEN characters of funcname and filename
if (!funcname) funcname = "";
size_t funclen = strlen(funcname);
if (funclen > GASNETI_CONSOLEMSG_NAME_LEN) funcname += (funclen - GASNETI_CONSOLEMSG_NAME_LEN);
if (!filename || !*filename) filename = "*unknown file*";
size_t filelen = strlen(filename);
if (filelen > GASNETI_CONSOLEMSG_NAME_LEN) filename += (filelen - GASNETI_CONSOLEMSG_NAME_LEN);
// format location info
char linestr[8] = { 0 };
if (linenum > 0 && linenum <= 999999) { // format up to 6-char linenum, if provided
snprintf(linestr, sizeof(linestr), ":%i", linenum);
}
gasneti_static_assert(GASNETI_CONSOLEMSG_CONTEXT_LEN >= 2*GASNETI_CONSOLEMSG_NAME_LEN + 18);
const size_t pos = strlen(expandedmsg);
if (*funcname)
snprintf(expandedmsg+pos, sizeof(expandedmsg)-4 - pos,
"in %s%s at %s%s: ",
funcname, (funcname[strlen(funcname)-1] != ')'?"()":""),
filename, linestr);
else
snprintf(expandedmsg+pos, sizeof(expandedmsg)-4 - pos,
"at %s%s: ",
filename, linestr);
}
const size_t maxshortmsg = sizeof(expandedmsg)-4 - strlen(expandedmsg);
const size_t msglen = strlen(msg);
int isshort = 0;
int isveryshort = 0;
#ifndef GASNETI_CONSOLEMSG_VERYSHORT_LEN
#define GASNETI_CONSOLEMSG_VERYSHORT_LEN 384
#endif
char veryshort_msg[GASNETI_CONSOLEMSG_VERYSHORT_LEN];
if (msglen <= maxshortmsg) { // short enough to send to fprintf(stderr) in a single operation
strncat(expandedmsg, msg, maxshortmsg);
if (expandedmsg[strlen(expandedmsg)-1] != '\n') strcat(expandedmsg, "\n");
isshort = 1;
va_list args;
va_copy(args, argptr);
int result = vsnprintf(veryshort_msg, sizeof(veryshort_msg), expandedmsg, args);
if (result < sizeof(veryshort_msg)) isveryshort = 1; // short enough to send as a formatted buffer
va_end(args);
}
FILE * streams[] = { (console_speak ? stderr : NULL), GASNETI_MAYBE_TRACEFILE };
for (int s = 0; s < sizeof(streams)/sizeof(streams[0]); s++) {
FILE *stream = streams[s];
if (stream) {
if (isveryshort) {
fputs(veryshort_msg, stream);
} else {
va_list args;
va_copy(args, argptr);
if (isshort) {
vfprintf(stream, expandedmsg, args);
} else { /* long format msg */
fputs(expandedmsg, stream);
vfprintf(stream, msg, args);
if (msg[msglen-1] != '\n') fprintf(stream, "\n");
}
va_end(args);
}
fflush(stream);
}
}
}
#undef GASNETI_MAYBE_TRACEFILE
#undef GASNETI_PROCID
#undef GASNETI_PROCID_INVALID
extern void gasneti_console_message(const char *prefix, const char *msg, ...) {
va_list argptr;
va_start(argptr, msg); /* pass in last argument */
gasneti_console_messageVA(0,0,0,-1, prefix, msg, argptr);
va_end(argptr);
}
extern void gasneti_console0_message(const char *prefix, const char *msg, ...) {
va_list argptr;
va_start(argptr, msg); /* pass in last argument */
gasneti_console_messageVA(0,0,0,0, prefix, msg, argptr);
va_end(argptr);
}
static void gasneti_output_config(void) {
gasneti_console_message("Details for bug reporting",
"config=" GASNETT_CONFIG_STRING
" compiler=" _STRINGIFY(PLATFORM_COMPILER_FAMILYNAME) "/" PLATFORM_COMPILER_VERSION_STR
" sys=" GASNETT_SYSTEM_TUPLE);
}
extern void gasneti_error_abort(void) {
gasneti_internal_crash = 1;
gasnett_freezeForDebuggerErr(); /* allow freeze */
/* try to get a pre-signal backtrace, which may be more precise */
if (!gasneti_print_backtrace_ifenabled(STDERR_FILENO))
gasneti_atomic_set(&gasneti_backtrace_enabled,0,GASNETI_ATOMIC_REL);
// Try to flush I/O (especially the tracefile) before crashing
signal(SIGALRM, _exit); alarm(5);
gasneti_flush_streams();
#if PLATFORM_OS_CYGWIN && CYGWIN_VERSION_DLL_MAJOR < 3000 && GASNETT_THREAD_SAFE
// Bug 3856 - Cygwin signal-handling discrepancies with multiple threads
// Following should be equivalent to abort(), but Cygwin 2.x abort is non-compliant
// and this generates more reliable behavior:
if (gasneti_raise(SIGABRT) == 0) (void)0; // success
else
#endif /* intentional fall-thru */
abort();
static const char err[] = "ERROR: abort() returned!\n";
gasneti_unused_result( write(2 /*stderr*/, err, sizeof(err)) );
(void)fsync(2);
// ensure this function never returns, even if abort does
_exit(1);
}
const char *_gasneti_fatalerror_funcname;
const char *_gasneti_fatalerror_filename;
int _gasneti_fatalerror_linenum;
extern void _gasneti_fatalerror(const char *msg, ...) {
va_list argptr;
va_start(argptr, msg); /* pass in last argument */
gasneti_console_messageVA(_gasneti_fatalerror_funcname,
_gasneti_fatalerror_filename,
_gasneti_fatalerror_linenum,
-1, "FATAL ERROR", msg, argptr);
va_end(argptr);
gasneti_error_abort();
}
extern void gasneti_fatalerror_nopos(const char *msg, ...) {
va_list argptr;
va_start(argptr, msg); /* pass in last argument */
gasneti_console_messageVA(0,0,0,-1, "FATAL ERROR", msg, argptr);
va_end(argptr);
gasneti_error_abort();
}
extern void _gasneti_assert_fail(const char *funcname, const char *filename, int linenum,
const char *fmt, ...) {
// generate the fatal error and crash
va_list argptr;
va_start(argptr, fmt); /* pass in last argument */
gasneti_console_messageVA(funcname, filename, linenum, -1,
"FATAL ERROR: Assertion failure", fmt, argptr);
va_end(argptr);
gasneti_error_abort();
}
/* ------------------------------------------------------------------------------------ */
extern void gasneti_killmyprocess(int exitcode) {
/* wrapper for _exit() that does the "right thing" to immediately kill this process */
#if GASNETI_THREADS && defined(HAVE_PTHREAD_KILL_OTHER_THREADS_NP)
/* on LinuxThreads we need to explicitly kill other threads before calling _exit() */
pthread_kill_other_threads_np();
#endif
_exit(exitcode); /* use _exit to bypass atexit handlers */
gasneti_fatalerror("gasneti_killmyprocess failed to kill the process!");
}
extern void gasneti_filesystem_sync(void) {
static int enabled = -1;
if (enabled == -1) enabled = gasneti_getenv_yesno_withdefault("GASNET_FS_SYNC",0);
if (enabled) {
sync();
}
}
extern void gasneti_flush_streams(void) {
/* XXX: When should we consider failures to be errors? When should we warn?
* For a long time failures here were fatal, but that choice precludes
* clients or systems which close the standard fds.
*/
fflush(stdout);
fflush(stderr);
fsync(STDOUT_FILENO); /* ignore errors for output is a console */
fsync(STDERR_FILENO); /* ignore errors for output is a console */
fflush(NULL); /* passing NULL to fflush SHOULD cause it to flush all open FILE streams */
gasneti_filesystem_sync();
gasneti_sched_yield();
}
extern void gasneti_close_streams(void) {
/* XXX: When should we consider failures to be errors? When should we warn?
* For a long time failures here were fatal, but that choice precludes
* clients or systems which close the standard fds.
*/
gasneti_reghandler(SIGPIPE, SIG_IGN); /* In case we still try to generate output */
fclose(stdin);
fclose(stdout);
fclose(stderr);
gasneti_sched_yield();
}
/* ------------------------------------------------------------------------------------ */
static void (*_gasneti_exitfn)(int);
#if HAVE_ON_EXIT
static void gasneti_on_exit(int exitcode, void *arg) {
if (_gasneti_exitfn) _gasneti_exitfn(exitcode);
}
#else
static void gasneti_atexit(void) {
if (_gasneti_exitfn) _gasneti_exitfn(0);
}
#endif
extern void gasneti_registerExitHandler(void (*_exitfn)(int)) {
_gasneti_exitfn = _exitfn;
static int firstcall = 1;
if (!firstcall) return;
firstcall = 0;
if (gasneti_getenv_yesno_withdefault("GASNET_CATCH_EXIT", 1)) {
#if HAVE_ON_EXIT
on_exit(gasneti_on_exit, NULL);
#else
atexit(gasneti_atexit);
#endif
}
}
/* ------------------------------------------------------------------------------------ */
extern gasneti_sighandlerfn_t gasneti_reghandler(int sigtocatch, gasneti_sighandlerfn_t fp) {
gasneti_sighandlerfn_t fpret = (gasneti_sighandlerfn_t)signal(sigtocatch, fp);
if (fpret == (gasneti_sighandlerfn_t)SIG_ERR) {
gasneti_fatalerror("Got a SIG_ERR while registering handler for signal %i : %s",
sigtocatch,strerror(errno));
return NULL;
}
#ifdef SIG_HOLD
else if (fpret == (gasneti_sighandlerfn_t)SIG_HOLD) {
gasneti_fatalerror("Got a SIG_HOLD while registering handler for signal %i : %s",
sigtocatch,strerror(errno));
return NULL;
}
#endif
return fpret;
}
/* ------------------------------------------------------------------------------------ */
typedef struct {
int signum;
const char *name;
const char *desc;
enum {
GASNETI_SV_PROGRAM_ERROR, /* program errors that will continus to occur if ignored */
GASNETI_SV_TERM_INT, /* interrupt signal from the terminal (stop or kill) */
GASNETI_SV_SYS_INT, /* interrupt signal from the system (kill, hangup, etc.) */
GASNETI_SV_FATAL, /* interrupts that cannot be caught or ignored */
GASNETI_SV_OTHER /* everything else */
} variety;
int enable_gasnet_handler;
gasneti_sighandlerfn_t oldhandler;
} gasnett_siginfo_t;
static gasnett_siginfo_t gasneti_sigtable[] = {
#ifdef SIGABRT
{SIGABRT, "SIGABRT", "Process abort signal.", GASNETI_SV_PROGRAM_ERROR, 1}, /* (abort()) */
#endif
#ifdef SIGFPE
{SIGFPE, "SIGFPE", "Erroneous arithmetic operation.", GASNETI_SV_PROGRAM_ERROR, 1}, /* (FP error) */
#endif
#ifdef SIGILL
{SIGILL, "SIGILL", "Illegal instruction.", GASNETI_SV_PROGRAM_ERROR, 1}, /* (bad instruction) */
#endif
#ifdef SIGINT
{SIGINT, "SIGINT", "Terminal interrupt signal.", GASNETI_SV_TERM_INT, 1}, /* (control-c) */
#endif
#ifdef SIGSEGV
{SIGSEGV, "SIGSEGV", "Invalid memory reference.", GASNETI_SV_PROGRAM_ERROR, 1}, /* (seg fault) */
#endif
#ifdef SIGTERM
{SIGTERM, "SIGTERM", "Termination signal.", GASNETI_SV_SYS_INT, 1}, /* (kill command) */
#endif
#ifdef SIGALRM
{SIGALRM, "SIGALRM", "Alarm clock.", GASNETI_SV_OTHER, 0},
#endif
#ifdef SIGHUP
{SIGHUP, "SIGHUP", "Hangup.", GASNETI_SV_SYS_INT, 1},
#endif
#ifdef SIGKILL
{SIGKILL, "SIGKILL", "Kill (cannot be caught or ignored).", GASNETI_SV_FATAL, 0}, /* (kill -9 command) */
#endif
#ifdef SIGPIPE
{SIGPIPE, "SIGPIPE", "Write on a pipe with no one to read it.", GASNETI_SV_OTHER, 1}, /* (send() after close) */
#endif
#ifdef SIGQUIT
{SIGQUIT, "SIGQUIT", "Terminal quit signal.", GASNETI_SV_TERM_INT, 1}, /* (control-\) */
#endif
#ifdef SIGUSR1
{SIGUSR1, "SIGUSR1", "User-defined signal 1.", GASNETI_SV_OTHER, 0},
#endif
#ifdef SIGUSR2
{SIGUSR2, "SIGUSR2", "User-defined signal 2.", GASNETI_SV_OTHER, 0},
#endif
#ifdef SIGCHLD
{SIGCHLD, "SIGCHLD", "Child process terminated or stopped.", GASNETI_SV_OTHER, 0}, /* (sent to parent proc) */
#endif
#ifdef SIGCONT
{SIGCONT, "SIGCONT", "Continue executing, if stopped.", GASNETI_SV_OTHER, 0}, /* (also sent by kill command) */
#endif
#ifdef SIGSTOP