1*d96cc911SJed Brown #include <petsc-private/petscimpl.h> 2*d96cc911SJed Brown 3*d96cc911SJed Brown /* ---------------------------------------------------------------------------------------*/ 4*d96cc911SJed Brown #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T) 5*d96cc911SJed Brown #include <signal.h> 6*d96cc911SJed Brown #include <setjmp.h> 7*d96cc911SJed Brown PETSC_EXTERN jmp_buf PetscSegvJumpBuf; 8*d96cc911SJed Brown PETSC_EXTERN void PetscSegv_sigaction(int, siginfo_t*, void *); 9*d96cc911SJed Brown /*@C 10*d96cc911SJed Brown PetscCheckPointer - Returns PETSC_TRUE if a pointer points to accessible data 11*d96cc911SJed Brown 12*d96cc911SJed Brown Not Collective 13*d96cc911SJed Brown 14*d96cc911SJed Brown Input Parameters: 15*d96cc911SJed Brown + ptr - the pointer 16*d96cc911SJed Brown - dtype - the type of data the pointer is suppose to point to 17*d96cc911SJed Brown 18*d96cc911SJed Brown Level: developer 19*d96cc911SJed Brown 20*d96cc911SJed Brown @*/ 21*d96cc911SJed Brown PetscBool PetscCheckPointer(const void *ptr,PetscDataType dtype) 22*d96cc911SJed Brown { 23*d96cc911SJed Brown struct sigaction sa,oldsa; 24*d96cc911SJed Brown 25*d96cc911SJed Brown if (PETSC_RUNNING_ON_VALGRIND) return PETSC_TRUE; 26*d96cc911SJed Brown if (!ptr) return PETSC_FALSE; 27*d96cc911SJed Brown 28*d96cc911SJed Brown sigemptyset(&sa.sa_mask); 29*d96cc911SJed Brown sa.sa_sigaction = PetscSegv_sigaction; 30*d96cc911SJed Brown sa.sa_flags = SA_SIGINFO; 31*d96cc911SJed Brown sigaction(SIGSEGV, &sa, &oldsa); 32*d96cc911SJed Brown 33*d96cc911SJed Brown if (setjmp(PetscSegvJumpBuf)) { 34*d96cc911SJed Brown /* A segv was triggered in the code below hence we return with an error code */ 35*d96cc911SJed Brown sigaction(SIGSEGV, &oldsa, NULL);/* reset old signal hanlder */ 36*d96cc911SJed Brown return PETSC_FALSE; 37*d96cc911SJed Brown } else { 38*d96cc911SJed Brown switch (dtype) { 39*d96cc911SJed Brown case PETSC_INT:{ 40*d96cc911SJed Brown PETSC_UNUSED PetscInt x = (PetscInt)*(volatile PetscInt*)ptr; 41*d96cc911SJed Brown break; 42*d96cc911SJed Brown } 43*d96cc911SJed Brown #if defined(PETSC_USE_COMPLEX) 44*d96cc911SJed Brown case PETSC_SCALAR:{ /* C++ is seriously dysfunctional with volatile std::complex. */ 45*d96cc911SJed Brown PetscReal xreal = ((volatile PetscReal*)ptr)[0],ximag = ((volatile PetscReal*)ptr)[1]; 46*d96cc911SJed Brown PETSC_UNUSED volatile PetscScalar x = xreal + PETSC_i*ximag; 47*d96cc911SJed Brown break; 48*d96cc911SJed Brown } 49*d96cc911SJed Brown #endif 50*d96cc911SJed Brown case PETSC_REAL:{ 51*d96cc911SJed Brown PETSC_UNUSED PetscReal x = *(volatile PetscReal*)ptr; 52*d96cc911SJed Brown break; 53*d96cc911SJed Brown } 54*d96cc911SJed Brown case PETSC_BOOL:{ 55*d96cc911SJed Brown PETSC_UNUSED PetscBool x = *(volatile PetscBool*)ptr; 56*d96cc911SJed Brown break; 57*d96cc911SJed Brown } 58*d96cc911SJed Brown case PETSC_ENUM:{ 59*d96cc911SJed Brown PETSC_UNUSED PetscEnum x = *(volatile PetscEnum*)ptr; 60*d96cc911SJed Brown break; 61*d96cc911SJed Brown } 62*d96cc911SJed Brown case PETSC_CHAR:{ 63*d96cc911SJed Brown PETSC_UNUSED char *x = *(char*volatile*)ptr; 64*d96cc911SJed Brown break; 65*d96cc911SJed Brown } 66*d96cc911SJed Brown case PETSC_OBJECT:{ 67*d96cc911SJed Brown PETSC_UNUSED volatile PetscClassId classid = ((PetscObject)ptr)->classid; 68*d96cc911SJed Brown break; 69*d96cc911SJed Brown } 70*d96cc911SJed Brown default:; 71*d96cc911SJed Brown } 72*d96cc911SJed Brown } 73*d96cc911SJed Brown sigaction(SIGSEGV, &oldsa, NULL); /* reset old signal hanlder */ 74*d96cc911SJed Brown return PETSC_TRUE; 75*d96cc911SJed Brown } 76*d96cc911SJed Brown #else 77*d96cc911SJed Brown PetscBool PetscCheckPointer(const void *ptr,PETSC_UNUSED PetscDataType dtype) 78*d96cc911SJed Brown { 79*d96cc911SJed Brown if (!ptr) return PETSC_FALSE; 80*d96cc911SJed Brown return PETSC_TRUE; 81*d96cc911SJed Brown } 82*d96cc911SJed Brown #endif 83