1: #include <petsc/private/petscimpl.h>
3: static PetscInt petsc_checkpointer_intensity = 1;
5: /*@
7: confirm whether the address is valid. An intensity of 0 never uses signal handlers, 1 uses them when not in a "hot"
8: function, and intensity of 2 always uses a signal handler.
10: Not Collective
12: Input Parameter:
13: . intensity - how much to check pointers for validity
15: Options Database Key:
16: . -check_pointer_intensity - intensity (0, 1, or 2)
18: Level: advanced
21: @*/
23: {
25: petsc_checkpointer_intensity = intensity;
26: return 0;
27: }
29: /* ---------------------------------------------------------------------------------------*/
31: #if PetscDefined(HAVE_SETJMP_H)
32: #include <setjmp.h>
33: static jmp_buf PetscSegvJumpBuf;
34: static PetscBool PetscSegvJumpBuf_set;
36: /*@C
37: PetscSignalSegvCheckPointerOrMpi - To be called from a signal handler for SIGSEGV.
39: Not Collective
41: Notes:
43: there, otherwise returns with no effect. This function is called automatically by
44: PetscSignalHandlerDefault().
46: Level: developer
48: .seealso: `PetscPushSignalHandler()`
49: @*/
50: void PetscSignalSegvCheckPointerOrMpi(void)
51: {
52: if (PetscSegvJumpBuf_set) longjmp(PetscSegvJumpBuf, 1);
53: }
55: /*@C
58: Not Collective
60: Input Parameters:
61: + ptr - the pointer
62: - dtype - the type of data the pointer is suppose to point to
64: Level: developer
66: Note:
67: This is a non-standard PETSc function in that it returns the result as the return code and does not return an error code
70: @*/
72: {
73: if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE;
74: if (!ptr) return PETSC_FALSE;
75: if (petsc_checkpointer_intensity < 1) return PETSC_TRUE;
77: #if PetscDefined(USE_DEBUG)
78: /* Skip the verbose check if we are inside a hot function. */
79: if (petscstack.hotdepth > 0 && petsc_checkpointer_intensity < 2) return PETSC_TRUE;
80: #endif
82: PetscSegvJumpBuf_set = PETSC_TRUE;
84: if (setjmp(PetscSegvJumpBuf)) {
85: /* A segv was triggered in the code below hence we return with an error code */
86: PetscSegvJumpBuf_set = PETSC_FALSE;
87: return PETSC_FALSE;
88: } else {
89: switch (dtype) {
90: case PETSC_INT: {
91: PETSC_UNUSED PetscInt x = (PetscInt) * (volatile PetscInt *)ptr;
92: break;
93: }
94: #if defined(PETSC_USE_COMPLEX)
95: case PETSC_SCALAR: { /* C++ is seriously dysfunctional with volatile std::complex. */
96: #if defined(PETSC_USE_CXXCOMPLEX)
97: PetscReal xreal = ((volatile PetscReal *)ptr)[0], ximag = ((volatile PetscReal *)ptr)[1];
98: PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i * ximag;
99: #else
100: PETSC_UNUSED PetscScalar x = *(volatile PetscScalar *)ptr;
101: #endif
102: break;
103: }
104: #endif
105: case PETSC_REAL: {
106: PETSC_UNUSED PetscReal x = *(volatile PetscReal *)ptr;
107: break;
108: }
109: case PETSC_BOOL: {
110: PETSC_UNUSED PetscBool x = *(volatile PetscBool *)ptr;
111: break;
112: }
113: case PETSC_ENUM: {
114: PETSC_UNUSED PetscEnum x = *(volatile PetscEnum *)ptr;
115: break;
116: }
117: case PETSC_CHAR: {
118: PETSC_UNUSED char x = *(volatile char *)ptr;
119: break;
120: }
121: case PETSC_OBJECT: {
122: PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid;
123: break;
124: }
125: default:;
126: }
127: }
128: PetscSegvJumpBuf_set = PETSC_FALSE;
129: return PETSC_TRUE;
130: }
131: #endif