xref: /petsc/src/sys/error/pstack.c (revision 11525c0d8e626c522c766a3408f7e8671b0dac87)
1 
2 #include <petscsys.h>        /*I  "petscsys.h"   I*/
3 
4 #if defined(PETSC_USE_DEBUG)
5 
6 #if defined(PETSC_HAVE_PTHREADCLASSES)
7 #if defined(PETSC_PTHREAD_LOCAL)
8 PETSC_PTHREAD_LOCAL PetscStack *petscstack = 0;
9 #else
10 PetscThreadKey petscstack;
11 #endif
12 #else
13 PetscStack *petscstack = 0;
14 #endif
15 
16 
17 #if defined(PETSC_HAVE_SAWS)
18 #include <petscviewersaws.h>
19 
20 static PetscBool amsmemstack = PETSC_FALSE;
21 
22 #undef __FUNCT__
23 #define __FUNCT__ "PetscStackSAWsGrantAccess"
24 /*@C
25    PetscStackSAWsGrantAccess - Grants access of the PETSc stack frames to the SAWs publisher
26 
27    Collective on PETSC_COMM_WORLD?
28 
29    Level: developer
30 
31    Concepts: publishing object
32 
33    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscStackCallSAWs() since it may be used within those routines
34 
35 .seealso: PetscObjectSetName(), PetscObjectSAWsViewOff(), PetscObjectSAWsTakeAccess()
36 
37 @*/
38 void  PetscStackSAWsGrantAccess(void)
39 {
40   if (amsmemstack) {
41     /* ignore any errors from SAWs */
42     SAWs_Unlock();
43   }
44 }
45 
46 #undef __FUNCT__
47 #define __FUNCT__ "PetscStackSAWsTakeAccess"
48 /*@C
49    PetscStackSAWsTakeAccess - Takes access of the PETSc stack frames to the SAWs publisher
50 
51    Collective on PETSC_COMM_WORLD?
52 
53    Level: developer
54 
55    Concepts: publishing object
56 
57    Developers Note: Cannot use PetscFunctionBegin/Return() or PetscStackCallSAWs() since it may be used within those routines
58 
59 .seealso: PetscObjectSetName(), PetscObjectSAWsViewOff(), PetscObjectSAWsTakeAccess()
60 
61 @*/
62 void  PetscStackSAWsTakeAccess(void)
63 {
64   if (amsmemstack) {
65     /* ignore any errors from SAWs */
66     SAWs_Lock();
67   }
68 }
69 
70 PetscErrorCode PetscStackViewSAWs(void)
71 {
72   PetscStack*    petscstackp;
73   PetscMPIInt    rank;
74   PetscErrorCode ierr;
75 
76   ierr  = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
77   if (rank) return 0;
78   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
79   PetscStackCallSAWs(SAWs_Register,("/PETSc/Stack/functions",petscstackp->function,20,SAWs_READ,SAWs_STRING));
80   PetscStackCallSAWs(SAWs_Register,("/PETSc/Stack/__current_size",&petscstackp->currentsize,1,SAWs_READ,SAWs_INT));
81   amsmemstack = PETSC_TRUE;
82   return 0;
83 }
84 
85 #undef __FUNCT__
86 #define __FUNCT__ "PetscStackSAWsViewOff"
87 PetscErrorCode PetscStackSAWsViewOff(void)
88 {
89   PetscFunctionBegin;
90   if (!amsmemstack) PetscFunctionReturn(0);
91   PetscStackCallSAWs(SAWs_Delete,("/PETSc/Stack"));
92   amsmemstack = PETSC_FALSE;
93   PetscFunctionReturn(0);
94 }
95 
96 #endif
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   PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,petscstack_in);
106 
107 #if defined(PETSC_HAVE_SAWS)
108   {
109   PetscBool flg = PETSC_FALSE;
110   PetscOptionsHasName(NULL,"-stack_view",&flg);
111   if (flg) PetscStackViewSAWs();
112   }
113 #endif
114   return 0;
115 }
116 
117 
118 #undef __FUNCT__
119 #define __FUNCT__ "PetscStackView"
120 PetscErrorCode  PetscStackView(FILE *file)
121 {
122   int        i;
123   PetscStack *petscstackp;
124 
125   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
126   if (!file) file = PETSC_STDOUT;
127 
128   if (file == PETSC_STDOUT) {
129     (*PetscErrorPrintf)("Note: The EXACT line numbers in the stack are not available,\n");
130     (*PetscErrorPrintf)("      INSTEAD the line number of the start of the function\n");
131     (*PetscErrorPrintf)("      is given.\n");
132     for (i=petscstackp->currentsize-1; i>=0; i--) (*PetscErrorPrintf)("[%d] %s line %d %s%s\n",PetscGlobalRank,petscstackp->function[i],petscstackp->line[i],petscstackp->directory[i],petscstackp->file[i]);
133   } else {
134     fprintf(file,"Note: The EXACT line numbers in the stack are not available,\n");
135     fprintf(file,"      INSTEAD the line number of the start of the function\n");
136     fprintf(file,"      is given.\n");
137     for (i=petscstackp->currentsize-1; i>=0; i--) fprintf(file,"[%d] %s line %d %s%s\n",PetscGlobalRank,petscstackp->function[i],petscstackp->line[i],petscstackp->directory[i],petscstackp->file[i]);
138   }
139   return 0;
140 }
141 
142 PetscErrorCode PetscStackDestroy(void)
143 {
144   if (PetscStackActive()) {
145     PetscStack *petscstack_in;
146     petscstack_in = (PetscStack*)PetscThreadLocalGetValue(petscstack);
147     free(petscstack_in);
148     PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,NULL);
149   }
150   return 0;
151 }
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "PetscStackCopy"
155 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
156 PetscErrorCode  PetscStackCopy(PetscStack *sint,PetscStack *sout)
157 {
158   int i;
159 
160   if (!sint) sout->currentsize = 0;
161   else {
162     for (i=0; i<sint->currentsize; i++) {
163       sout->function[i]     = sint->function[i];
164       sout->file[i]         = sint->file[i];
165       sout->directory[i]    = sint->directory[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%s\n",PetscGlobalRank,sint->function[i],sint->line[i],sint->directory[i],sint->file[i]);
183   return 0;
184 }
185 
186 #else
187 
188 #if defined(PETSC_HAVE_PTHREADCLASSES)
189 #if defined(PETSC_PTHREAD_LOCAL)
190 PETSC_PTHREAD_LOCAL void *petscstack = 0;
191 #else
192 PetscThreadKey petscstack;
193 #endif
194 #else
195 void *petscstack = 0;
196 #endif
197 
198 #undef __FUNCT__
199 #define __FUNCT__ "PetscStackCreate"
200 PetscErrorCode  PetscStackCreate(void)
201 {
202   PetscFunctionBegin;
203   PetscFunctionReturn(0);
204 }
205 #undef __FUNCT__
206 #define __FUNCT__ "PetscStackView"
207 PetscErrorCode  PetscStackView(PETSC_UNUSED FILE *file)
208 {
209   PetscFunctionBegin;
210   PetscFunctionReturn(0);
211 }
212 #undef __FUNCT__
213 #define __FUNCT__ "PetscStackDestroy"
214 PetscErrorCode  PetscStackDestroy(void)
215 {
216   PetscFunctionBegin;
217   PetscFunctionReturn(0);
218 }
219 #undef __FUNCT__
220 #define __FUNCT__ "PetscStackCopy"
221 PetscErrorCode  PetscStackCopy(PETSC_UNUSED void *sint,PETSC_UNUSED void *sout)
222 {
223   PetscFunctionBegin;
224   PetscFunctionReturn(0);
225 }
226 #undef __FUNCT__
227 #define __FUNCT__ "PetscStackPrint"
228 PetscErrorCode  PetscStackPrint(PETSC_UNUSED void *sint,PETSC_UNUSED FILE *fp)
229 {
230   PetscFunctionBegin;
231   PetscFunctionReturn(0);
232 }
233 
234 #if defined(PETSC_HAVE_SAWS)     /* SAWs stack functions do nothing in optimized mode */
235 void PetscStackSAWsGrantAccess(void) {}
236 void PetscStackSAWsTakeAccess(void) {}
237 
238 PetscErrorCode PetscStackViewSAWs(void)
239 {
240   return 0;
241 }
242 
243 #undef __FUNCT__
244 #define __FUNCT__ "PetscStackSAWsViewOff"
245 PetscErrorCode  PetscStackSAWsViewOff(void)
246 {
247   PetscFunctionBegin;
248   PetscFunctionReturn(0);
249 }
250 #endif
251 
252 #endif
253 
254