Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
FunNameStack.cpp
Go to the documentation of this file.
1/*
2Copyright (c) 1999-2003 I. B. Smirnov
3
4Permission to use, copy, modify, distribute and sell this file for any purpose
5is hereby granted without fee, provided that the above copyright notice,
6this permission notice, and notices about any modifications of the original
7text appear in all copies and in supporting documentation.
8The file is provided "as is" without express or implied warranty.
9*/
10
11#include <stdlib.h>
12#include <iostream>
13#include <iomanip>
16#ifdef USE_BOOST_MULTITHREADING
18#endif
19
20//#define USE_TOGETHER_WITH_CLEAN_NEW
21
22#ifdef USE_TOGETHER_WITH_CLEAN_NEW
23#include "wcpplib/util/clean_new.h"
24#endif
25
26#ifdef USE_BOOST_MULTITHREADING
27NameStack& NameStack::operator=(const NameStack& f) {
28#ifdef USE_TOGETHER_WITH_CLEAN_NEW
29#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
30 MemoriseIgnore::instance().ignore();
31#else
32 s_ignore_keynumberlist = 1; // to avoid report from delete at deletion
33#endif
34#endif
35 if (this != &f) {
36 int n;
37 if (nmode == 1) for (n = 0; n < qname; n++)
38 delete name[n];
39 nmode = f.nmode;
40 qname = f.qname;
41 id = f.id;
42 for (n = 0; n < f.qname; n++) {
43 if (nmode == 0) {
44 name[n] = f.name[n];
45 } else {
46 int l = strlen(f.name[n]) + 1;
47 name[n] = new char[l];
48 strcpy(name[n], f.name[n]);
49 }
50 }
51 }
52#ifdef USE_TOGETHER_WITH_CLEAN_NEW
53#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
54 MemoriseIgnore::instance().not_ignore();
55#else
56 s_ignore_keynumberlist = 0;
57#endif
58#endif
59 return *this;
60}
61#endif
62
65
67//static FunNameStack inst; // According to some Internet site this is
68// Meyer's approach,
69// // time of descruction is not determined.
70// // So it can potentially be destructed before it is still in use.
71//return inst;
72#ifdef USE_BOOST_MULTITHREADING
73#ifdef PRINT_BEFORE_LOCK
74 fprintf(stderr, "FunNameStack& FunNameStack::instance()\n");
75#endif
76 boost::mutex locked_object;
77 boost::mutex::scoped_lock scopedLock_object(locked_object);
78#endif
79
80 static FunNameStack* inst = NULL; // According to this site it is
81 // "GoF" approach,
82 // destruction is not performed at all.
83#ifdef USE_TOGETHER_WITH_CLEAN_NEW
84#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
85 MemoriseIgnore::instance().ignore();
86#else
87 s_ignore_keynumberlist = 1; // to avoid report from delete at deletion
88#endif
89#endif
90 if (!inst) inst = new FunNameStack();
91#ifdef USE_TOGETHER_WITH_CLEAN_NEW
92#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
93 MemoriseIgnore::instance().not_ignore();
94#else
95 s_ignore_keynumberlist = 0;
96#endif
97#endif
98 return *inst;
99}
100
102 : // usually called inly from instance()
103 s_init(1),
104 s_act(1),
105 s_print(0),
106 nmode(0) {
107#ifdef USE_BOOST_MULTITHREADING
108
109#ifdef USE_TOGETHER_WITH_CLEAN_NEW
110#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
111 MemoriseIgnore::instance().ignore();
112#else
113 s_ignore_keynumberlist = 1; // to avoid report from delete at deletion
114#endif
115#endif
116 namestack = new AbsList<NameStack>;
117 namestack->append(NameStack());
118#ifdef USE_TOGETHER_WITH_CLEAN_NEW
119#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
120 MemoriseIgnore::instance().not_ignore();
121#else
122 s_ignore_keynumberlist = 0;
123#endif
124#endif // for ifdef USE_TOGETHER_WITH_CLEAN_NEW
125
126 pthread_t id = pthread_self();
127 namestack->get_last_node()->el.id = id;
128#ifdef PRINT_MESSAGE_ABOUT_THREAD_INITIALIZATION
129 mcerr
130 << "-----------------------------------------------------------------\n";
131 mcerr
132 << "-----------------------------------------------------------------\n";
133 mcerr
134 << "-----------------------------------------------------------------\n";
135 mcerr
136 << "-----------------------------------------------------------------\n";
137 mcerr
138 << "-----------------------------------------------------------------\n";
139 mcerr << "FunNameStack::FunNameStack(void) const:\n";
140 mcerr << "thread is initialized:\n";
141 Iprintn(mcerr, id);
142 mcerr
143 << "-----------------------------------------------------------------\n";
144 mcerr
145 << "-----------------------------------------------------------------\n";
146 mcerr
147 << "-----------------------------------------------------------------\n";
148 mcerr
149 << "-----------------------------------------------------------------\n";
150 mcerr
151 << "-----------------------------------------------------------------\n";
152#endif
153#else // for ifdef USE_BOOST_MULTITHREADING
154 qname = 0;
155 for (int n = 0; n < pqname; n++)
156 name[n] = NULL;
157#endif
158}
159
160#ifdef USE_BOOST_MULTITHREADING
161NameStack* FunNameStack::get_thread_stack(void) const {
162 //long nret = 0;
163 pthread_t id = pthread_self();
164 AbsListNode<NameStack>* an = NULL;
165 int s_found = 0;
166 an = namestack->get_first_node();
167 while (an != NULL) {
168 if (pthread_equal(an->el.id, id)) {
169 s_found = 1;
170 break;
171 }
172 an = an->get_next_node();
173 //nret++;
174 }
175 if (s_found == 0) // new thread is detected
176 {
177/*
178mcerr<<"-----------------------------------------------------------------\n";
179mcerr<<"-----------------------------------------------------------------\n";
180mcerr<<"-----------------------------------------------------------------\n";
181mcerr<<"-----------------------------------------------------------------\n";
182mcerr<<"-----------------------------------------------------------------\n";
183mcerr<<"NameStack* FunNameStack::get_thread_stack(void) const:\n";
184mcerr<<"new thread is detected\n";
185Iprintn(mcerr, id);
186 mcerr<<"-----------------------------------------------------------------\n";
187*/
188#ifdef USE_TOGETHER_WITH_CLEAN_NEW
189#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
190 MemoriseIgnore::instance().ignore();
191#else
192 s_ignore_keynumberlist = 1; // to avoid report from delete at deletion
193#endif
194#endif
195 namestack->append(NameStack());
196#ifdef USE_TOGETHER_WITH_CLEAN_NEW
197#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
198 MemoriseIgnore::instance().not_ignore();
199#else
200 s_ignore_keynumberlist = 0; // to avoid report from delete at deletion
201#endif
202#endif
203
204 namestack->get_last_node()->el.id = id;
205 }
206 return &(namestack->get_last_node()->el);
207}
208NameStack* FunNameStack::get_thread_stack_q(long& nthread,
209 long& qthread) const {
210 nthread = 0;
211 qthread = 0;
212 pthread_t id = pthread_self();
214 int s_found = 0;
215 an = namestack->get_first_node();
216 while (an != NULL) {
217 if (s_found == 0 && pthread_equal(an->el.id, id)) {
218 s_found = 1;
219 nthread = qthread;
220 }
221 an = an->get_next_node();
222 qthread++;
223 }
224 if (s_found == 0) // new thread is detected
225 {
226/*
227mcerr<<"-----------------------------------------------------------------\n";
228mcerr<<"-----------------------------------------------------------------\n";
229mcerr<<"-----------------------------------------------------------------\n";
230mcerr<<"-----------------------------------------------------------------\n";
231mcerr<<"-----------------------------------------------------------------\n";
232mcerr<<"NameStack* FunNameStack::get_thread_stack(void) const:\n";
233mcerr<<"new thread is detected\n";
234Iprintn(mcerr, id);
235mcerr<<"-----------------------------------------------------------------\n";
236*/
237#ifdef USE_TOGETHER_WITH_CLEAN_NEW
238#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
239 MemoriseIgnore::instance().ignore();
240#else
241 s_ignore_keynumberlist = 1; // to avoid report from delete at deletion
242#endif
243#endif
244 namestack->append(NameStack());
245#ifdef USE_TOGETHER_WITH_CLEAN_NEW
246#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
247 MemoriseIgnore::instance().not_ignore();
248#else
249 s_ignore_keynumberlist = 0; // to avoid report from delete at deletion
250#endif
251#endif
252 namestack->get_last_node()->el.id = id;
253 nthread = qthread;
254 qthread++;
255
256 }
257 return &(namestack->get_last_node()->el);
258}
259void FunNameStack::remove_thread_stack(void) {
260 //long nret = 0;
261 pthread_t id = pthread_self();
263 int s_found = 0;
264 an = namestack->get_first_node();
265 while (an != NULL) {
266 if (pthread_equal(an->el.id, id)) {
267 s_found = 1;
268 break;
269 }
270 an = an->get_next_node();
271 //nret++;
272 }
273 if (s_found == 0) // new thread is detected
274 {
275 mcerr << "ERROR in void FunNameStack::remove_thread_stack(void) const:\n";
276 mcerr << "new thread is detected\n";
277 Iprintn(mcerr, id);
278 spexit(mcerr);
279 }
280#ifdef USE_TOGETHER_WITH_CLEAN_NEW
281#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
282 MemoriseIgnore::instance().ignore();
283#else
284 s_ignore_keynumberlist = 1; // to avoid report from delete at deletion
285#endif
286#endif
287 namestack->remove(an);
288#ifdef USE_TOGETHER_WITH_CLEAN_NEW
289#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
290 MemoriseIgnore::instance().not_ignore();
291#else
292 s_ignore_keynumberlist = 0; // to avoid report from delete at deletion
293#endif
294#endif
295}
296#endif
297
298#ifdef USE_BOOST_MULTITHREADING
299std::ostream& FunNameStack::printname(std::ostream& file, NameStack* ns,
300 int n) //
301#else
302 std::ostream& FunNameStack::printname(std::ostream& file, int n) //
303#endif
304 {
305#ifdef USE_BOOST_MULTITHREADING
306 file << ns->name[n];
307 return file;
308#else
309 file << name[n];
310 return file;
311#endif
312}
313
314void spexit_action(std::ostream& file) {
315 file << "spexit_action: the streams will be now flushed\n";
316 file.flush();
317 mcout.flush();
318 mcerr.flush();
320 if (s_exit_without_core == 1) {
321 file << "spexit_action: the exit(1) function is called\n";
322 exit(1);
323 } else {
324 file << "spexit_action: the abort function is called\n";
325 abort();
326 }
327 } else {
328 file << "spexit_action: an exception is now called\n";
329 throw ExcFromSpexit();
330 }
331}
332
334
336 if (this == &(FunNameStack::instance())) {
337 mcerr << "ERROR in FunNameStack& FunNameStack::operator=(const "
338 "FunNameStack& f)\n";
339 mcerr << "Attempt to copy to operative FunNameStack\n";
340 mcerr << "You don't need and should not initialize main FunNameStack "
341 "directly\n";
342 mcerr << "If you want to change its parameters, use "
343 "FunNameStack::instance()\n";
344 Iprintn(mcout, this);
346 Iprintn(mcout, (*this));
348
349 spexit(mcerr);
350 }
351#ifdef USE_BOOST_MULTITHREADING
352
353#ifdef USE_TOGETHER_WITH_CLEAN_NEW
354#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
355 MemoriseIgnore::instance().ignore();
356#else
357 s_ignore_keynumberlist = 1;
358#endif
359#endif
360 if (namestack != NULL) delete namestack;
361 namestack = new AbsList<NameStack>(*(f.namestack));
362#ifdef USE_TOGETHER_WITH_CLEAN_NEW
363#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
364 MemoriseIgnore::instance().not_ignore();
365#else
366 s_ignore_keynumberlist = 0;
367#endif
368#endif
369
370#else
371 qname = f.qname;
372#endif
373 s_init = f.s_init;
374 s_act = f.s_act;
375 s_print = f.s_print;
376 nmode = f.nmode;
377#ifdef USE_BOOST_MULTITHREADING
378#else
379 int n;
380 for (n = 0; n < f.qname; n++) {
381 if (nmode == 0) {
382 name[n] = f.name[n];
383 } else {
384 int l = strlen(f.name[n]) + 1;
385#ifdef USE_TOGETHER_WITH_CLEAN_NEW
386 s_ignore_keynumberlist = 1;
387#endif
388 name[n] = new char[l];
389 strcpy(name[n], f.name[n]);
390#ifdef USE_TOGETHER_WITH_CLEAN_NEW
391 s_ignore_keynumberlist = 0;
392#endif
393 }
394 }
395#endif
396 return *this;
397}
398
399void FunNameStack::set_parameters(int fs_act, int fs_print) {
400 s_act = fs_act;
401 s_print = fs_print; // only to correct this
402}
403
405#ifdef USE_BOOST_MULTITHREADING
406#ifdef USE_TOGETHER_WITH_CLEAN_NEW
407#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
408 MemoriseIgnore::instance().ignore();
409#else
410 s_ignore_keynumberlist = 1;
411#endif
412#endif
413 if (namestack != NULL) delete namestack;
414#ifdef USE_TOGETHER_WITH_CLEAN_NEW
415#if defined(MAINTAIN_KEYNUMBER_LIST) && defined(USE_BOOST_MULTITHREADING)
416 MemoriseIgnore::instance().not_ignore();
417#else
418 s_ignore_keynumberlist = 0;
419#endif
420#endif
421#else
422 int n;
423#ifdef USE_TOGETHER_WITH_CLEAN_NEW
424 s_ignore_keynumberlist = 1;
425#endif
426 if (nmode == 1) for (n = 0; n < qname; n++)
427 delete name[n];
428#ifdef USE_TOGETHER_WITH_CLEAN_NEW
429 s_ignore_keynumberlist = 0;
430#endif
431#endif
432}
433
434#ifndef WCPPLIB_INLINE
435#include "util/FunNameStack.ic"
436#endif
437
438void FunNameStack::printput(std::ostream& file) {
439 if (s_print == 1 || s_print == 2) {
440#ifdef USE_BOOST_MULTITHREADING
441 NameStack* ns = get_thread_stack();
442 file << "FunNameStack::put: id=" << ns->id << " qname=" << ns->qname
443 << " last name= \"";
444 printname(file, ns, ns->qname - 1);
445 file << " \"\n";
446#else
447 file << "FunNameStack::put: qname =" << qname << " last name=";
448 printname(file, qname - 1) << '\n';
449#endif
450 } else if (s_print >= 3) {
451#ifdef USE_BOOST_MULTITHREADING
452 NameStack* ns = get_thread_stack();
453 file << "FunNameStack::put: id=" << ns->id << "\n" << (*this);
454#else
455 file << "FunNameStack::put:\n" << (*this);
456#endif
457 }
458}
459void FunNameStack::printdel(std::ostream& file) {
460 if (s_print == 2) {
461#ifdef USE_BOOST_MULTITHREADING
462 NameStack* ns = get_thread_stack();
463 file << "FunNameStack::del: id=" << ns->id << " qname =" << ns->qname
464 << " last name= \"";
465 printname(file, ns, ns->qname - 1);
466 file << " \"\n";
467#else
468 file << "FunNameStack::del: qname =" << qname << " last name=";
469 printname(file, qname - 1) << '\n';
470#endif
471 } else if (s_print == 4) {
472 file << "FunNameStack::del:\n" << (*this);
473 }
474}
475
476std::ostream& operator<<(std::ostream& file, const FunNameStack& f) {
477 if (f.s_act == 1) {
478#ifdef USE_BOOST_MULTITHREADING
479 file << "FunNameStack: s_init=" << f.s_init << '\n';
480 long nret, qret;
481 NameStack* ns = f.get_thread_stack_q(nret, qret);
482 file << " id=" << ns->id << " qname=" << ns->qname << '\n';
483 file << "At the time of scanning there were " << qret << " threads \n"
484 << "registered in FunNameStack system.\n";
485 file << "The current one appeared nth: " << nret << '\n';
486 int n;
487 for (n = 0; n < ns->qname; n++) {
488 //file << " n =" << std::setw(3) << n << " " << f.name[n] << '\n';
489 file << std::setw(3) << n << " " << ns->name[n] << " \n";
490 }
491#else
492 file << "FunNameStack: s_init=" << f.s_init << " qname=" << f.qname << '\n';
493 int n;
494 for (n = 0; n < f.qname; n++) {
495 //file << " n =" << std::setw(3) << n << " " << f.name[n] << '\n';
496 file << std::setw(3) << n << " " << f.name[n] << " \n";
497 }
498#endif
499 }
500 return file;
501}
502
503std::ostream& operator<<(std::ostream& file, const FunNameWatch& f) {
504 f.hdr(file);
505 return file;
506}
507
508//ostream& operator<<(ostream& file, const GenError& f)
509void GenError::print(std::ostream& file) {
510 file << "GenError::print: ERROR detected in:\n"
511 << statcast(FunNameStack*, this) << '\n';
512 //<<static_cast<FunNameStack*>(this)<<'\n';
513}
514void GenError::finish(std::ostream& file) {
515 print(file);
516 exit(1);
517}
std::ostream & operator<<(std::ostream &file, const FunNameStack &f)
void spexit_action(std::ostream &file)
int s_exit_without_core
int s_throw_exception_in_spexit
#define spexit(stream)
Definition: FunNameStack.h:536
const int pqname
Definition: FunNameStack.h:544
AbsListNode< T > * append(const T &fel)
Definition: AbsList.h:216
static FunNameStack & instance()
FunNameStack & operator=(const FunNameStack &f)
void set_parameters(int fs_act=1, int fs_print=0)
std::ostream & hdr(std::ostream &file) const
Definition: FunNameStack.h:718
virtual void print(std::ostream &file)
virtual void finish(std::ostream &file)
#define statcast(type, name)
#define mcout
Definition: prstream.h:133
#define mcerr
Definition: prstream.h:135
#define Iprintn(file, name)
Definition: prstream.h:216