-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsight_structure_init.h
134 lines (115 loc) · 5.51 KB
/
sight_structure_init.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2013, Lawrence Livermore National Security, LLC.
// Produced at the Lawrence Livermore National Laboratory.
// Written by the Greg Bronevetsky <bronevetsky1@llnl.gov> / <greg@bronevetsky.com>.
//
// LLNL-CODE-642002
// All rights reserved.
//
// This file is part of Sight. For details, see https://e-reports-ext.llnl.gov/pdf/781752.pdf or
// https://github.com/bronevet/sight.
//
// Licensed under the GNU Lesser General Public License (Lesser GPU) Version 2.1,
// February 1999; you may not use this file except in compliance with the License.
// The full licence is included in file LICENCE and you may obtain a copy of the
// License at:
// https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the license.
////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <list>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include <ostream>
#include <fstream>
#include <stdarg.h>
#include <assert.h>
#include "sight_common.h"
#include "utils.h"
#if (CALLPATH_ENABLED==1)
#include "tools/callpath/include/Callpath.h"
#include "tools/callpath/include/CallpathRuntime.h"
#endif
#include "thread_local_storage.h"
#include <signal.h>
#include <deque>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/adjacency_list.hpp>
namespace sight {
namespace structure{
// This mechanism allows different widgets to register their own code to be called when each
// thread is started and stopped. This includes both the main thread and threads created
// using pthread_create. Each widget can provide initialization and finalization methods,
// and order them relative to other widgets' methods to maintain relative order among different
// initialization/finalization logic.
// Initializers/finalizers are specified by
// - deriving a widget-specific class from ThreadInitFinInstantiator that uses method
// addFuncs() in its constructor to register the widget-specific functions, and
// - declaring a single global variable of this type.
typedef void (*ThreadInitializer)();
typedef void (*ThreadFinalizer)();
class ThreadInitFinInstantiator : public sight::common::LoadTimeRegistry {
// The maximum unique ID assigned to any threadFuncs so far
static int* maxUID;
class threadFuncs {
public:
int UID;
ThreadInitializer init;
ThreadFinalizer fin;
set<std::string> mustFollow;
set<std::string> mustPrecede;
threadFuncs(ThreadInitializer init, ThreadFinalizer fin,
const set<std::string>& mustFollow, const set<std::string>& mustPrecede) :
UID((*maxUID)++), init(init), fin(fin), mustFollow(mustFollow), mustPrecede(mustPrecede) {}
std::string str() const {
return txt()<<"[threadFuncs: UID="<<UID<<", mustFollow="<<set2str(mustFollow)<<", mustPrecede="<<set2str(mustPrecede)<<"]";
}
};
public:
// Keep track of the funcs that are currently registered to initialize and finalize threads
// Maps the string labels of funcs to their threadFuncs data structures
// Each threadFuncs has a unique ID that is used as the vertex number in the dependence
// graph, which is implemented using the Boost Graph Library
static std::map<std::string, threadFuncs*>* funcsM;
// Vector of pointers to the threadFuncs in funcsM, where the index of each record is
// equal to its UID.
static std::vector<threadFuncs*>* funcsV;
// Records the dependencies among the entries in funcs
static boost::adjacency_list<boost::listS, boost::vecS, boost::directedS>* depGraph;
// Records the topological order among the funcs
static std::deque<int>* topoOrder;
// Records whether the dependence graph is upto-date relative to the current
// entries in funcs
static bool* depGraphUptoDate;
// The height of each thread's SOStack after it has been initialized. This is important
// for ensuring that on shutdown we destroy any sightObjects above this point before
// calling the finalization routines.
static ThreadLocalStorage0<int> initializedSOStackHeight;
ThreadInitFinInstantiator();
// Called exactly once for each class that derives from LoadTimeRegistry to initialize its static data structures.
static void init();
// Adds the given initialization/finalization funcs under the given widet label.
// mustFollow - set of widget labels that the given functors must follow during initialization
// mustPrecede - set of widget labels that the given functors must precede during initialization
// finalization is performed in reverse
static void addFuncs(const std::string& label, ThreadInitializer init, ThreadFinalizer fin,
const common::easyset<std::string>& mustFollow, const common::easyset<std::string>& mustPrecede);
// Update the dependence graph based on funcs, if it not already upto-date
static void computeDepGraph();
// Calls all the initializers in their topological order
static void initialize();
// Calls all the finalizers in their topological order (reverse of initializers)
static void finalize();
static std::string str();
};
} // namespace structure
} // namespace sight