xref: /petsc/src/sys/error/pstack.c (revision c7ff62de565b7a47aed9937d7304d01fbead9a78)
1 
2 #include <petscsys.h>        /*I  "petscsys.h"   I*/
3 
4 
5 #if defined(PETSC_HAVE_PTHREADCLASSES)
6 #if defined(PETSC_PTHREAD_LOCAL)
7 PETSC_PTHREAD_LOCAL PetscStack *petscstack = 0;
8 #else
9 PetscThreadKey petscstack;
10 #endif
11 #else
12 PetscStack *petscstack = 0;
13 #endif
14 
15 
16 #if defined(PETSC_HAVE_SAWS)
17 #include <petscviewersaws.h>
18 
19 static PetscBool amsmemstack = PETSC_FALSE;
20 
21 #undef __FUNCT__
22 #define __FUNCT__ "PetscStackSAWsGrantAccess"
23 /*@C
24    PetscStackSAWsGrantAccess - Grants access of the PETSc stack frames to the SAWs publisher
25 
26    Collective on PETSC_COMM_WORLD?
27 
28    Level: developer
29 
30    Concepts: publishing object
31 
32    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscStackCallSAWs() since it may be used within those routines
33 
34 .seealso: PetscObjectSetName(), PetscObjectSAWsViewOff(), PetscObjectSAWsTakeAccess()
35 
36 @*/
37 void  PetscStackSAWsGrantAccess(void)
38 {
39   if (amsmemstack) {
40     /* ignore any errors from SAWs */
41     SAWs_Unlock();
42   }
43 }
44 
45 #undef __FUNCT__
46 #define __FUNCT__ "PetscStackSAWsTakeAccess"
47 /*@C
48    PetscStackSAWsTakeAccess - Takes access of the PETSc stack frames to the SAWs publisher
49 
50    Collective on PETSC_COMM_WORLD?
51 
52    Level: developer
53 
54    Concepts: publishing object
55 
56    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscStackCallSAWs() since it may be used within those routines
57 
58 .seealso: PetscObjectSetName(), PetscObjectSAWsViewOff(), PetscObjectSAWsTakeAccess()
59 
60 @*/
61 void  PetscStackSAWsTakeAccess(void)
62 {
63   if (amsmemstack) {
64     /* ignore any errors from SAWs */
65     SAWs_Lock();
66   }
67 }
68 
69 PetscErrorCode PetscStackViewSAWs(void)
70 {
71   PetscStack*    petscstackp;
72   PetscMPIInt    rank;
73   PetscErrorCode ierr;
74 
75   ierr  = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
76   if (rank) return 0;
77   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
78   PetscStackCallSAWs(SAWs_Register,("/PETSc/Stack/functions",petscstackp->function,20,SAWs_READ,SAWs_STRING));
79   PetscStackCallSAWs(SAWs_Register,("/PETSc/Stack/__current_size",&petscstackp->currentsize,1,SAWs_READ,SAWs_INT));
80   amsmemstack = PETSC_TRUE;
81   return 0;
82 }
83 
84 #undef __FUNCT__
85 #define __FUNCT__ "PetscStackSAWsViewOff"
86 PetscErrorCode PetscStackSAWsViewOff(void)
87 {
88   PetscFunctionBegin;
89   if (!amsmemstack) PetscFunctionReturn(0);
90   PetscStackCallSAWs(SAWs_Delete,("/PETSc/Stack"));
91   amsmemstack = PETSC_FALSE;
92   PetscFunctionReturn(0);
93 }
94 
95 #  endif
96 
97 
98 PetscErrorCode PetscStackCreate(void)
99 {
100   PetscStack *petscstack_in;
101   if (PetscStackActive()) return 0;
102 
103   petscstack_in              = (PetscStack*)malloc(sizeof(PetscStack));
104   petscstack_in->currentsize = 0;
105   petscstack_in->hotdepth    = 0;
106   PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,petscstack_in);
107 
108 #if defined(PETSC_HAVE_SAWS)
109   {
110   PetscBool flg = PETSC_FALSE;
111   PetscOptionsHasName(NULL,"-stack_view",&flg);
112   if (flg) PetscStackViewSAWs();
113   }
114 #endif
115   return 0;
116 }
117 
118 
119 #undef __FUNCT__
120 #define __FUNCT__ "PetscStackView"
121 PetscErrorCode  PetscStackView(FILE *file)
122 {
123   int        i;
124   PetscStack *petscstackp;
125 
126   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
127   if (!file) file = PETSC_STDOUT;
128 
129   if (file == PETSC_STDOUT) {
130     (*PetscErrorPrintf)("Note: The EXACT line numbers in the stack are not available,\n");
131     (*PetscErrorPrintf)("      INSTEAD the line number of the start of the function\n");
132     (*PetscErrorPrintf)("      is given.\n");
133     for (i=petscstackp->currentsize-1; i>=0; i--) (*PetscErrorPrintf)("[%d] %s line %d %s\n",PetscGlobalRank,petscstackp->function[i],petscstackp->line[i],petscstackp->file[i]);
134   } else {
135     fprintf(file,"Note: The EXACT line numbers in the stack are not available,\n");
136     fprintf(file,"      INSTEAD the line number of the start of the function\n");
137     fprintf(file,"      is given.\n");
138     for (i=petscstackp->currentsize-1; i>=0; i--) fprintf(file,"[%d] %s line %d %s\n",PetscGlobalRank,petscstackp->function[i],petscstackp->line[i],petscstackp->file[i]);
139   }
140   return 0;
141 }
142 
143 PetscErrorCode PetscStackDestroy(void)
144 {
145   if (PetscStackActive()) {
146     PetscStack *petscstack_in;
147     petscstack_in = (PetscStack*)PetscThreadLocalGetValue(petscstack);
148     free(petscstack_in);
149     PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,NULL);
150   }
151   return 0;
152 }
153 
154 #undef __FUNCT__
155 #define __FUNCT__ "PetscStackCopy"
156 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
157 PetscErrorCode  PetscStackCopy(PetscStack *sint,PetscStack *sout)
158 {
159   int i;
160 
161   if (!sint) sout->currentsize = 0;
162   else {
163     for (i=0; i<sint->currentsize; i++) {
164       sout->function[i]     = sint->function[i];
165       sout->file[i]         = sint->file[i];
166       sout->line[i]         = sint->line[i];
167       sout->petscroutine[i] = sint->petscroutine[i];
168     }
169     sout->currentsize = sint->currentsize;
170   }
171   return 0;
172 }
173 
174 #undef __FUNCT__
175 #define __FUNCT__ "PetscStackPrint"
176 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
177 PetscErrorCode  PetscStackPrint(PetscStack *sint,FILE *fp)
178 {
179   int i;
180 
181   if (!sint) return(0);
182   for (i=sint->currentsize-2; i>=0; i--) fprintf(fp,"      [%d]  %s() line %d in %s\n",PetscGlobalRank,sint->function[i],sint->line[i],sint->file[i]);
183   return 0;
184 }
185 
186