xref: /petsc/src/sys/error/pstack.c (revision fe998a80077c9ee0917a39496df43fc256e1b478)
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   PetscInt   i;
102 
103   if (PetscStackActive()) return 0;
104 
105   petscstack_in              = (PetscStack*)malloc(sizeof(PetscStack));
106   petscstack_in->currentsize = 0;
107   petscstack_in->hotdepth    = 0;
108   for (i=0; i<PETSCSTACKSIZE; i++) {
109     petscstack_in->function[i] = 0;
110     petscstack_in->file[i]     = 0;
111   }
112   PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,petscstack_in);
113 
114 #if defined(PETSC_HAVE_SAWS)
115   {
116   PetscBool flg = PETSC_FALSE;
117   PetscOptionsHasName(NULL,"-stack_view",&flg);
118   if (flg) PetscStackViewSAWs();
119   }
120 #endif
121   return 0;
122 }
123 
124 
125 #undef __FUNCT__
126 #define __FUNCT__ "PetscStackView"
127 PetscErrorCode  PetscStackView(FILE *file)
128 {
129   int        i;
130   PetscStack *petscstackp;
131 
132   petscstackp = (PetscStack*)PetscThreadLocalGetValue(petscstack);
133   if (!file) file = PETSC_STDOUT;
134 
135   if (file == PETSC_STDOUT) {
136     (*PetscErrorPrintf)("Note: The EXACT line numbers in the stack are not available,\n");
137     (*PetscErrorPrintf)("      INSTEAD the line number of the start of the function\n");
138     (*PetscErrorPrintf)("      is given.\n");
139     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]);
140   } else {
141     fprintf(file,"Note: The EXACT line numbers in the stack are not available,\n");
142     fprintf(file,"      INSTEAD the line number of the start of the function\n");
143     fprintf(file,"      is given.\n");
144     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]);
145   }
146   return 0;
147 }
148 
149 PetscErrorCode PetscStackDestroy(void)
150 {
151   if (PetscStackActive()) {
152     PetscStack *petscstack_in;
153     petscstack_in = (PetscStack*)PetscThreadLocalGetValue(petscstack);
154     free(petscstack_in);
155     PetscThreadLocalSetValue((PetscThreadKey*)&petscstack,NULL);
156   }
157   return 0;
158 }
159 
160 #undef __FUNCT__
161 #define __FUNCT__ "PetscStackCopy"
162 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
163 PetscErrorCode  PetscStackCopy(PetscStack *sint,PetscStack *sout)
164 {
165   int i;
166 
167   if (!sint) sout->currentsize = 0;
168   else {
169     for (i=0; i<sint->currentsize; i++) {
170       sout->function[i]     = sint->function[i];
171       sout->file[i]         = sint->file[i];
172       sout->line[i]         = sint->line[i];
173       sout->petscroutine[i] = sint->petscroutine[i];
174     }
175     sout->currentsize = sint->currentsize;
176   }
177   return 0;
178 }
179 
180 #undef __FUNCT__
181 #define __FUNCT__ "PetscStackPrint"
182 /*  PetscFunctionBegin;  so that make rule checkbadPetscFunctionBegin works */
183 PetscErrorCode  PetscStackPrint(PetscStack *sint,FILE *fp)
184 {
185   int i;
186 
187   if (!sint) return(0);
188   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]);
189   return 0;
190 }
191 
192