Update in sync with enterprise version.
[csql.git] / src / storage / Process.cxx
blobb70f9001da9bacd8bdc22b7336e5a3738d6dce42
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 mutex for registering");
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");
147 trans->status_ = TransNotUsed;
149 if (pInfo->want_ != NULL)
151 printError(ErrSysFatal, "Probable data corruption.wants_ is not null\n");
152 systemDatabase->releaseProcessTableMutex(false);
153 return ErrSysFatal;
155 for (int muti = 0 ;muti < MAX_MUTEX_PER_THREAD; muti++)
157 if (pInfo->has_[muti] != NULL)
159 printError(ErrSysFatal, "Probable data corruption.some mutexes are not freed %x \n", pInfo->has_[muti] );
160 pInfo->has_[muti]->print();
161 pInfo->has_[muti]->releaseLock(procSlot);
162 systemDatabase->releaseProcessTableMutex(false);
163 return ErrSysFatal;
166 printDebug(DM_Process, "Process %d %lu deregistered slot %d\n", pInfo->pid_, pInfo->thrid_, procSlot);
168 //printf("Slot freed %d %x %d %lu\n", i, pInfo, pid, thrid);
169 pInfo->init();
170 systemDatabase->releaseProcessTableMutex(false);
171 return OK;
174 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
176 //pid_t pid = os::getpid();
177 //pthread_t thrid = os::getthrid();
178 if (systemDatabase == NULL)
180 return OK;
182 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
183 int i=0;
184 /*for (; i < Conf::config.getMaxProcs(); i++)
186 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
187 pInfo++;
189 if (i == Conf::config.getMaxProcs())
191 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable while adding mutex %s", pid, thrid, mut->name);
192 return ErrSysFatal;
194 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
196 if (pInfo->has_[i] == NULL)
198 pInfo->has_[i] = mut;
199 printDebug(DM_Process, "procSlot %d acquiring %d mutex %x %s\n", pslot, i, mut, mut->name);
200 return OK;
203 printError(ErrSysInternal, "All slots are full. Reached per thread mutex limit.");
204 //printStackTrace();
205 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
207 printError(ErrWarning, "mutex %d %x", i, pInfo->has_[i]);
208 pInfo->has_[i]->print();
210 return ErrSysInternal;
213 DbRetVal ProcessManager::removeMutex(Mutex *mut, int pslot)
215 //pid_t pid = os::getpid();
216 //pthread_t thrid = os::getthrid();
217 if (systemDatabase == NULL)
219 return OK;
222 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
223 int i=0;
224 /*for (; i < Conf::config.getMaxProcs(); i++)
226 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
227 pInfo++;
229 if (i == Conf::config.getMaxProcs())
231 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
232 return ErrSysFatal;
234 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
236 if (pInfo->has_[i] == mut)
238 pInfo->has_[i] = NULL;
239 printDebug(DM_Process, "procSlot %d releasing %d mutex %x %s\n", pslot, i, mut, mut->name);
240 return OK;
243 printError(ErrSysInternal, "Mutex could not be found in the list %s", mut->name);
244 return ErrSysInternal;
247 DbRetVal ProcessManager::setThreadTransaction(Transaction *trans, int pslot)
249 pid_t pid = os::getpid();
250 pthread_t thrid = os::getthrid();
251 if (systemDatabase == NULL)
253 return OK;
256 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
257 int i=0;
259 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
261 if (pInfo->thrTrans_[i].pid_ != 0) continue;
263 if (i == MAX_THREADS_PER_PROCESS)
265 printError(ErrSysInternal, "Max thread limit reached.");
266 return ErrSysInternal;
268 pInfo->thrTrans_[i].pid_ = pid;
269 pInfo->thrTrans_[i].thrid_ = thrid;
270 pInfo->thrTrans_[i].trans_ = trans;
272 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot,
273 pid, thrid, trans);
274 //pInfo->trans_ = trans;
275 return OK;
278 Transaction* ProcessManager::getThreadTransaction(int pslot)
280 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
281 return pInfo->thrTrans_[0].trans_;
284 Transaction** ProcessManager::getThreadTransAddr(int pslot)
286 pid_t pid = os::getpid();
287 pthread_t thrid = os::getthrid();
288 if (systemDatabase == NULL)
290 return NULL;
293 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
294 int i=0;
296 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
298 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
300 if (i == MAX_THREADS_PER_PROCESS)
302 printDebug(DM_Process, "Thread specific trans could not be found in list");
303 return NULL;
306 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
307 pid, thrid, pInfo->thrTrans_[i].trans_);
308 return &pInfo->thrTrans_[i].trans_;
314 void ProcessManager::printUsageStatistics()
316 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
317 int i=0, usedCount =0 , freeCount =0;
318 for (; i < Conf::config.getMaxProcs(); i++)
320 if (pInfo->pid_ != 0 ) usedCount++; else freeCount++;
321 pInfo++;
323 printf("<ProcTable>\n");
324 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
325 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
326 printf("</ProcTable>\n");
330 void ProcessManager::printDebugInfo()
332 printf("<ProcTable>\n");
333 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
334 int i=0, usedCount =0 , freeCount =0;
335 for (; i < Conf::config.getMaxProcs(); i++)
337 if (pInfo->pid_ != 0 ) {pInfo->print(); usedCount++;} else freeCount++;
338 pInfo++;
340 printf("<UsedSlots> %d </UsedSlots>\n", usedCount);
341 printf("<FreeSlots> %d </FreeSlots>\n", freeCount);
342 printf("</ProcTable>\n");
346 bool ProcessManager::isAnyOneRegistered()
348 //the process which calls this will have an entry in proc table.
349 //so checking for 1
350 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
351 int i=0, usedCount =0;
352 for (; i < Conf::config.getMaxProcs(); i++)
354 if (pInfo->pid_ != 0 ) usedCount++;
355 pInfo++;
357 if (usedCount == 1) return false; else return true;