1 /*
2 Copyright (c) 2003, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "SimBlockList.hpp"
26 #include <Emulator.hpp>
27 #include <SimulatedBlock.hpp>
28 #include <Cmvmi.hpp>
29 #include <Ndbfs.hpp>
30 #include <Dbacc.hpp>
31 #include <Dbdict.hpp>
32 #include <Dbdih.hpp>
33 #include <Dblqh.hpp>
34 #include <Dbspj.hpp>
35 #include <Dbtc.hpp>
36 #include <Dbtup.hpp>
37 #include <Ndbcntr.hpp>
38 #include <Qmgr.hpp>
39 #include <Trix.hpp>
40 #include <Backup.hpp>
41 #include <DbUtil.hpp>
42 #include <Suma.hpp>
43 #include <Dbtux.hpp>
44 #include <tsman.hpp>
45 #include <lgman.hpp>
46 #include <pgman.hpp>
47 #include <restore.hpp>
48 #include <Dbinfo.hpp>
49 #include <NdbEnv.h>
50 #include <LocalProxy.hpp>
51 #include <DblqhProxy.hpp>
52 #include <DbspjProxy.hpp>
53 #include <DbaccProxy.hpp>
54 #include <DbtupProxy.hpp>
55 #include <DbtuxProxy.hpp>
56 #include <BackupProxy.hpp>
57 #include <RestoreProxy.hpp>
58 #include <PgmanProxy.hpp>
59 #include <DbtcProxy.hpp>
60 #include <DbspjProxy.hpp>
61 #include <thrman.hpp>
62 #include <trpman.hpp>
63 #include <mt.hpp>
64
65 #define JAM_FILE_ID 492
66
67
68 #ifndef VM_TRACE
69 #define NEW_BLOCK(B) new B
70 #else
71 enum SIMBLOCKLIST_DUMMY { A_VALUE = 0 };
72
operator new(size_t sz,SIMBLOCKLIST_DUMMY dummy)73 void * operator new (size_t sz, SIMBLOCKLIST_DUMMY dummy){
74 char * tmp = (char *)malloc(sz);
75 if (!tmp)
76 abort();
77
78 #ifndef NDB_PURIFY
79 #ifdef VM_TRACE
80 const int initValue = 0xf3;
81 #else
82 const int initValue = 0x0;
83 #endif
84
85 const int p = (sz / 4096);
86 const int r = (sz % 4096);
87
88 for(int i = 0; i<p; i++)
89 memset(tmp+(i*4096), initValue, 4096);
90
91 if(r > 0)
92 memset(tmp+p*4096, initValue, r);
93
94 #endif
95
96 return tmp;
97 }
98 #define NEW_BLOCK(B) new(A_VALUE) B
99 #endif
100
101 void
load(EmulatorData & data)102 SimBlockList::load(EmulatorData& data){
103 noOfBlocks = NO_OF_BLOCKS;
104 theList = new SimulatedBlock * [noOfBlocks];
105 if (!theList)
106 {
107 ERROR_SET(fatal, NDBD_EXIT_MEMALLOC,
108 "Failed to create the block list", "");
109 }
110
111 Block_context ctx(*data.theConfiguration, *data.m_mem_manager);
112
113 SimulatedBlock * fs = 0;
114 {
115 Uint32 dl;
116 const ndb_mgm_configuration_iterator * p =
117 ctx.m_config.getOwnConfigIterator();
118 if(p && !ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl){
119 fs = NEW_BLOCK(VoidFs)(ctx);
120 } else {
121 fs = NEW_BLOCK(Ndbfs)(ctx);
122 }
123 }
124
125 const bool mtLqh = globalData.isNdbMtLqh;
126
127 if (!mtLqh)
128 theList[0] = NEW_BLOCK(Pgman)(ctx);
129 else
130 theList[0] = NEW_BLOCK(PgmanProxy)(ctx);
131 theList[1] = NEW_BLOCK(Lgman)(ctx);
132 theList[2] = NEW_BLOCK(Tsman)(ctx);
133 if (!mtLqh)
134 theList[3] = NEW_BLOCK(Dbacc)(ctx);
135 else
136 theList[3] = NEW_BLOCK(DbaccProxy)(ctx);
137 theList[4] = NEW_BLOCK(Cmvmi)(ctx);
138 theList[5] = fs;
139 theList[6] = NEW_BLOCK(Dbdict)(ctx);
140 theList[7] = NEW_BLOCK(Dbdih)(ctx);
141 if (!mtLqh)
142 theList[8] = NEW_BLOCK(Dblqh)(ctx);
143 else
144 theList[8] = NEW_BLOCK(DblqhProxy)(ctx);
145 if (globalData.ndbMtTcThreads == 0)
146 theList[9] = NEW_BLOCK(Dbtc)(ctx);
147 else
148 theList[9] = NEW_BLOCK(DbtcProxy)(ctx);
149 if (!mtLqh)
150 theList[10] = NEW_BLOCK(Dbtup)(ctx);
151 else
152 theList[10] = NEW_BLOCK(DbtupProxy)(ctx);
153 theList[11] = NEW_BLOCK(Ndbcntr)(ctx);
154 theList[12] = NEW_BLOCK(Qmgr)(ctx);
155 theList[13] = NEW_BLOCK(Trix)(ctx);
156 if (!mtLqh)
157 theList[14] = NEW_BLOCK(Backup)(ctx);
158 else
159 theList[14] = NEW_BLOCK(BackupProxy)(ctx);
160 theList[15] = NEW_BLOCK(DbUtil)(ctx);
161 theList[16] = NEW_BLOCK(Suma)(ctx);
162 if (!mtLqh)
163 theList[17] = NEW_BLOCK(Dbtux)(ctx);
164 else
165 theList[17] = NEW_BLOCK(DbtuxProxy)(ctx);
166 if (!mtLqh)
167 theList[18] = NEW_BLOCK(Restore)(ctx);
168 else
169 theList[18] = NEW_BLOCK(RestoreProxy)(ctx);
170 theList[19] = NEW_BLOCK(Dbinfo)(ctx);
171 if (globalData.ndbMtTcThreads == 0)
172 theList[20] = NEW_BLOCK(Dbspj)(ctx);
173 else
174 theList[20] = NEW_BLOCK(DbspjProxy)(ctx);
175 if (NdbIsMultiThreaded() == false)
176 theList[21] = NEW_BLOCK(Thrman)(ctx);
177 else
178 theList[21] = NEW_BLOCK(ThrmanProxy)(ctx);
179 if (NdbIsMultiThreaded() == false)
180 theList[22] = NEW_BLOCK(Trpman)(ctx);
181 else
182 theList[22] = NEW_BLOCK(TrpmanProxy)(ctx);
183 assert(NO_OF_BLOCKS == 23);
184
185 // Check that all blocks could be created
186 for (int i = 0; i < noOfBlocks; i++)
187 {
188 if (!theList[i])
189 {
190 ERROR_SET(fatal, NDBD_EXIT_MEMALLOC,
191 "Failed to create block", "");
192 }
193 }
194
195 if (globalData.isNdbMt)
196 {
197 /**
198 This is where we bind blocks to their respective threads.
199 mt_init_thr_map binds the blocks to the two main threads,
200 the thread for Global blocks (thr = 0), and the thread
201 for Local blocks (thr = 1) and it puts CMVMI into the receiver
202 thread.
203
204 For those blocks where we created proxies above the loadWorkers
205 function will map the instances of the block into the right
206 thread. mt_add_thr_map will be called for each of the block
207 instances.
208 */
209 mt_init_thr_map();
210 for (int i = 0; i < noOfBlocks; i++)
211 theList[i]->loadWorkers();
212 mt_finalize_thr_map();
213 }
214 }
215
216 void
unload()217 SimBlockList::unload(){
218 if(theList != 0){
219 for(int i = 0; i<noOfBlocks; i++){
220 if(theList[i] != 0){
221 #ifdef VM_TRACE
222 theList[i]->~SimulatedBlock();
223 free(theList[i]);
224 #else
225 delete(theList[i]);
226 #endif
227 theList[i] = 0;
228 }
229 }
230 delete [] theList;
231 theList = 0;
232 noOfBlocks = 0;
233 }
234 }
235