commiting changes from enterprise version for V2.4
[csql.git] / src / storage / Process.cxx
blob718456acf380f562044838dc159e7c2a2b0a07fa
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include <Process.h>
17 #include <Debug.h>
18 #include <Database.h>
19 #include <Config.h>
20 #include <ErrorType.h>
21 #include <Globals.h>
22 #include <Mutex.h>
24 int ProcessManager::noThreads=0;
25 Mutex ProcessManager::mutex;
26 caddr_t ProcessManager::sysAddr=0;
27 caddr_t ProcessManager::usrAddr=0;
28 Database* ProcessManager::systemDatabase=NULL;
29 List ProcessManager::hasLockList;
31 void ThreadInfo::init()
33 pid_ = 0;
34 thrid_ =0;
35 want_ = NULL;
36 for (int i =0; i <MAX_MUTEX_PER_THREAD; i++) has_[i] = NULL;
37 for (int i =0; i <MAX_THREADS_PER_PROCESS; i++) thrTrans_[i].init();
39 void ThreadTrans::print()
41 if (pid_ ==0) return;
42 printf("<THREADTRANS>\n");
43 printf(" <PID> %d </PID>\n", pid_);
44 printf(" <THRID> %lu </THRID>\n", thrid_);
45 printf(" <TRANSACTION> %x </TRANSACTION>\n");
46 printf("</THREADTRANS>\n");
48 void ThreadInfo::print()
50 printf("<THREADINFO>\n");
51 printf(" <PID> %d </PID>\n", pid_);
52 printf(" <THRID> %lu </THRID>\n", thrid_);
53 printf(" <WAIT> %x </WAIT>\n", want_);
54 printf(" <MUTEXLIST>\n");
55 for (int i =0; i <MAX_MUTEX_PER_THREAD; i++) if (has_[i]) printf(" <MUTEX> %x </MUTEX>\n", has_[i]);
56 printf(" </MUTEXLIST>\n");
57 printf(" <TRANSLIST>\n");
58 for (int i =0; i <MAX_THREADS_PER_PROCESS; i++) thrTrans_[i].print();
59 printf(" </TRANSLIST>\n");
60 printf("</THREADINFO>\n");
64 //It does not check for re registering as well as deregistering unregistered threads.
65 //as it is handled in the connection class open and close methods.
66 DbRetVal ProcessManager::registerThread()
68 mutex.getLock(-1, false);
69 noThreads++;
70 mutex.releaseLock(-1, false);
71 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
72 if (OK != rv)
74 printError(rv,"Unable to get process table mutex");
75 printError(rv,"Recovery may be going on. Retry after some time.");
76 mutex.getLock(-1, false);
77 noThreads--;
78 mutex.releaseLock(-1, false);
79 return rv;
81 pid_t pid;
82 pid = os::getpid();
83 pthread_t thrid = os::getthrid();
84 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
85 int i=0;
86 ThreadInfo* freeSlot = NULL;
87 int freeSlotPos =0;
88 bool freeSlotSelected = false;
89 for (; i < Conf::config.getMaxProcs(); i++)
91 if (pInfo->pid_ == 0 ) break;
92 pInfo++;
94 if ( i == Conf::config.getMaxProcs())
96 systemDatabase->releaseProcessTableMutex(false);
97 printError(ErrNoResource, "No free thread slot. Limit reached");
98 return ErrNoResource;
100 //printf("Process slot used %d %x\n", i, pInfo);
101 //TODO::make the above debug message
102 //TODO:print it to the trace file
103 pInfo->init();
104 pInfo->pid_ = pid;
105 pInfo->thrid_ = thrid;
106 procSlot = i;
107 printDebug(DM_Process, "Process %d %lu registered with slot %d\n", pid, thrid, procSlot);
108 systemDatabase->releaseProcessTableMutex(false);
109 return OK;
111 DbRetVal ProcessManager::deregisterThread(int procSlot)
113 mutex.getLock(-1, false);
114 noThreads--;
115 mutex.releaseLock(-1, false);
116 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
117 if (OK != rv)
119 printError(rv,"Unable to get process table mutex");
120 return rv;
122 pid_t pid = os::getpid();
123 pthread_t thrid = os::getthrid();
125 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
126 int i=0;
127 for (; i < Conf::config.getMaxProcs(); i++)
129 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
130 pInfo++;
133 systemDatabase->releaseProcessTableMutex(false);
134 if (i == Conf::config.getMaxProcs())
136 printError(ErrSysFatal, "Degistering process %d is not registered with csql", pid);
137 return ErrNoResource;
139 ThreadInfo* pInfo = systemDatabase->getThreadInfo(procSlot);
140 Transaction *trans = ProcessManager::getThreadTransaction(procSlot);
141 if (NULL != trans)
143 if (trans->status_ == TransRunning)
145 printError(ErrWarning, "Transaction is still running\n");
148 if (pInfo->want_ != NULL)
150 printError(ErrSysFatal, "Probable data corruption.wants_ is not null\n");
151 return ErrSysFatal;
153 for (int muti = 0 ;muti < MAX_MUTEX_PER_THREAD; muti++)
155 if (pInfo->has_[muti] != NULL)
157 printError(ErrSysFatal, "Probable data corruption.some mutexes are not freed %x \n", pInfo->has_[muti]);
158 pInfo->has_[muti]->releaseLock(procSlot);
159 return ErrSysFatal;
162 printDebug(DM_Process, "Process %d %lu deregistered slot %d\n", pInfo->pid_, pInfo->thrid_, procSlot);
164 //printf("Slot freed %d %x %d %lu\n", i, pInfo, pid, thrid);
165 pInfo->init();
166 systemDatabase->releaseProcessTableMutex(false);
167 return OK;
170 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
172 //pid_t pid = os::getpid();
173 //pthread_t thrid = os::getthrid();
174 if (systemDatabase == NULL)
176 return OK;
178 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
179 int i=0;
180 /*for (; i < Conf::config.getMaxProcs(); i++)
182 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
183 pInfo++;
185 if (i == Conf::config.getMaxProcs())
187 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable while adding mutex %s", pid, thrid, mut->name);
188 return ErrSysFatal;
190 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
192 if (pInfo->has_[i] == NULL)
194 pInfo->has_[i] = mut;
195 printDebug(DM_Process, "procSlot %d acquiring %d mutex %x %s\n", pslot, i, mut, mut->name);
196 return OK;
199 printError(ErrSysInternal, "All slots are full. Reached per thread mutex limit.");
200 return ErrSysInternal;
203 DbRetVal ProcessManager::removeMutex(Mutex *mut, int pslot)
205 //pid_t pid = os::getpid();
206 //pthread_t thrid = os::getthrid();
207 if (systemDatabase == NULL)
209 return OK;
212 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
213 int i=0;
214 /*for (; i < Conf::config.getMaxProcs(); i++)
216 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
217 pInfo++;
219 if (i == Conf::config.getMaxProcs())
221 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
222 return ErrSysFatal;
224 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
226 if (pInfo->has_[i] == mut)
228 pInfo->has_[i] = NULL;
229 printDebug(DM_Process, "procSlot %d releasing %d mutex %x %s\n", pslot, i, mut, mut->name);
230 return OK;
233 printError(ErrSysInternal, "Mutex could not be found in the list %s", mut->name);
234 void *array[10];
235 size_t size;
236 size = backtrace(array, 10);
237 backtrace_symbols_fd(array, size, 2);
238 return ErrSysInternal;
241 DbRetVal ProcessManager::setThreadTransaction(Transaction *trans, int pslot)
243 pid_t pid = os::getpid();
244 pthread_t thrid = os::getthrid();
245 if (systemDatabase == NULL)
247 return OK;
250 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
251 int i=0;
253 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
255 if (pInfo->thrTrans_[i].pid_ != 0) continue;
257 if (i == MAX_THREADS_PER_PROCESS)
259 printError(ErrSysInternal, "Max thread limit reached.");
260 return ErrSysInternal;
262 pInfo->thrTrans_[i].pid_ = pid;
263 pInfo->thrTrans_[i].thrid_ = thrid;
264 pInfo->thrTrans_[i].trans_ = trans;
266 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot,
267 pid, thrid, trans);
268 //pInfo->trans_ = trans;
269 return OK;
272 Transaction* ProcessManager::getThreadTransaction(int pslot)
274 pid_t pid = os::getpid();
275 pthread_t thrid = os::getthrid();
276 if (systemDatabase == NULL)
278 return NULL;
281 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
282 int i=0;
284 for (i = 0; i < MAX_THREADS_PER_PROCESS; i++)
286 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
288 if (i == MAX_THREADS_PER_PROCESS)
290 printDebug(DM_Process, "Thread specific trans could not be found in list");
291 return NULL;
294 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
295 pid, thrid, pInfo->thrTrans_[i].trans_);
296 //pInfo->trans_ = trans;
297 return pInfo->thrTrans_[i].trans_;
300 Transaction** ProcessManager::getThreadTransAddr(int pslot)
302 pid_t pid = os::getpid();
303 pthread_t thrid = os::getthrid();
304 if (systemDatabase == NULL)
306 return NULL;
309 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
310 int i=0;
312 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
314 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
316 if (i == MAX_THREADS_PER_PROCESS)
318 printDebug(DM_Process, "Thread specific trans could not be found in list");
319 return NULL;
322 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
323 pid, thrid, pInfo->thrTrans_[i].trans_);
324 return &pInfo->thrTrans_[i].trans_;
330 void ProcessManager::printUsageStatistics()
332 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
333 int i=0, usedCount =0 , freeCount =0;
334 for (; i < Conf::config.getMaxProcs(); i++)
336 if (pInfo->pid_ != 0 ) usedCount++; else freeCount++;
337 pInfo++;
339 printf("<ProcTable>\n");
340 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
341 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
342 printf("</ProcTable>\n");
346 void ProcessManager::printDebugInfo()
348 printf("<ProcTable>\n");
349 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
350 int i=0, usedCount =0 , freeCount =0;
351 for (; i < Conf::config.getMaxProcs(); i++)
353 if (pInfo->pid_ != 0 ) {pInfo->print(); usedCount++;} else freeCount++;
354 pInfo++;
356 printf("<UsedSlots> %d </UsedSlots>\n", usedCount);
357 printf("<FreeSlots> %d </FreeSlots>\n", freeCount);
358 printf("</ProcTable>\n");
362 bool ProcessManager::isAnyOneRegistered()
364 //the process which calls this will have an entry in proc table.
365 //so checking for 1
366 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
367 int i=0, usedCount =0;
368 for (; i < Conf::config.getMaxProcs(); i++)
370 if (pInfo->pid_ != 0 ) usedCount++;
371 pInfo++;
373 if (usedCount == 1) return false; else return true;