code reorg
[csql.git] / src / server / Process.cxx
blob2cbc699971f19b1dc9142a423d504672cdca9ad9
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(false);
69 noThreads++;
70 mutex.releaseLock(false);
71 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
72 if (OK != rv)
74 printError(rv,"Unable to get process table mutex");
75 return rv;
77 pid_t pid;
78 pid = os::getpid();
79 pthread_t thrid = os::getthrid();
80 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
81 int i=0;
82 ThreadInfo* freeSlot = NULL;
83 int freeSlotPos =0;
84 bool freeSlotSelected = false;
85 for (; i < Conf::config.getMaxProcs(); i++)
87 if (pInfo->pid_ == 0 ) break;
88 pInfo++;
90 if ( i == Conf::config.getMaxProcs())
92 systemDatabase->releaseProcessTableMutex(false);
93 printError(ErrNoResource, "No free thread slot. Limit reached");
94 return ErrNoResource;
96 //printf("Process slot used %d %x\n", i, pInfo);
97 //TODO::make the above debug message
98 //TODO:print it to the trace file
99 pInfo->init();
100 pInfo->pid_ = pid;
101 pInfo->thrid_ = thrid;
102 procSlot = i;
103 printDebug(DM_Process, "Process %d %lu registered with slot %d\n", pid, thrid, procSlot);
104 systemDatabase->releaseProcessTableMutex(false);
105 return OK;
107 DbRetVal ProcessManager::deregisterThread(int procSlot)
109 mutex.getLock(false);
110 noThreads--;
111 mutex.releaseLock(false);
112 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
113 if (OK != rv)
115 printError(rv,"Unable to get process table mutex");
116 return rv;
118 pid_t pid = os::getpid();
119 pthread_t thrid = os::getthrid();
121 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
122 int i=0;
123 for (; i < Conf::config.getMaxProcs(); i++)
125 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
126 pInfo++;
129 systemDatabase->releaseProcessTableMutex(false);
130 if (i == Conf::config.getMaxProcs())
132 printError(ErrSysFatal, "Degistering process %d is not registered with csql", pid);
133 return ErrNoResource;
135 ThreadInfo* pInfo = systemDatabase->getThreadInfo(procSlot);
136 Transaction *trans = ProcessManager::getThreadTransaction(procSlot);
137 if (NULL != trans)
139 if (trans->status_ == TransRunning)
141 printError(ErrWarning, "Transaction is still running\n");
144 if (pInfo->want_ != NULL)
146 printError(ErrSysFatal, "Probable data corruption.wants_ is not null\n");
147 return ErrSysFatal;
149 for (int muti = 0 ;muti < MAX_MUTEX_PER_THREAD; muti++)
151 if (pInfo->has_[muti] != NULL)
153 printError(ErrSysFatal, "Probable data corruption.some mutexes are not freed %x %s\n", pInfo->has_[muti], pInfo->has_[muti]->name);
154 pInfo->has_[muti]->releaseLock(procSlot);
155 return ErrSysFatal;
158 printDebug(DM_Process, "Process %d %lu deregistered slot %d\n", pInfo->pid_, pInfo->thrid_, procSlot);
160 //printf("Slot freed %d %x %d %lu\n", i, pInfo, pid, thrid);
161 pInfo->init();
162 systemDatabase->releaseProcessTableMutex(false);
163 return OK;
166 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
168 //pid_t pid = os::getpid();
169 //pthread_t thrid = os::getthrid();
170 if (systemDatabase == NULL)
172 return OK;
174 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
175 int i=0;
176 /*for (; i < Conf::config.getMaxProcs(); i++)
178 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
179 pInfo++;
181 if (i == Conf::config.getMaxProcs())
183 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable while adding mutex %s", pid, thrid, mut->name);
184 return ErrSysFatal;
186 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
188 if (pInfo->has_[i] == NULL)
190 pInfo->has_[i] = mut;
191 printDebug(DM_Process, "procSlot %d acquiring %d mutex %x %s\n", pslot, i, mut, mut->name);
192 return OK;
195 printError(ErrSysInternal, "All slots are full. Reached per thread mutex limit.");
196 return ErrSysInternal;
199 DbRetVal ProcessManager::removeMutex(Mutex *mut, int pslot)
201 //pid_t pid = os::getpid();
202 //pthread_t thrid = os::getthrid();
203 if (systemDatabase == NULL)
205 return OK;
208 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
209 int i=0;
210 /*for (; i < Conf::config.getMaxProcs(); i++)
212 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
213 pInfo++;
215 if (i == Conf::config.getMaxProcs())
217 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
218 return ErrSysFatal;
220 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
222 if (pInfo->has_[i] == mut)
224 pInfo->has_[i] = NULL;
225 printDebug(DM_Process, "procSlot %d releasing %d mutex %x %s\n", pslot, i, mut, mut->name);
226 return OK;
229 printError(ErrSysInternal, "Mutex could not be found in the list %s", mut->name);
230 return ErrSysInternal;
233 DbRetVal ProcessManager::setThreadTransaction(Transaction *trans, int pslot)
235 pid_t pid = os::getpid();
236 pthread_t thrid = os::getthrid();
237 if (systemDatabase == NULL)
239 return OK;
242 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
243 int i=0;
245 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
247 if (pInfo->thrTrans_[i].pid_ != 0) continue;
249 if (i == MAX_THREADS_PER_PROCESS)
251 printError(ErrSysInternal, "Max thread limit reached.");
252 return ErrSysInternal;
254 pInfo->thrTrans_[i].pid_ = pid;
255 pInfo->thrTrans_[i].thrid_ = thrid;
256 pInfo->thrTrans_[i].trans_ = trans;
258 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot,
259 pid, thrid, trans);
260 //pInfo->trans_ = trans;
261 return OK;
264 Transaction* ProcessManager::getThreadTransaction(int pslot)
266 pid_t pid = os::getpid();
267 pthread_t thrid = os::getthrid();
268 if (systemDatabase == NULL)
270 return NULL;
273 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
274 int i=0;
276 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
278 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
280 if (i == MAX_THREADS_PER_PROCESS)
282 printDebug(DM_Process, "Thread specific trans could not be found in list");
283 return NULL;
286 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
287 pid, thrid, pInfo->thrTrans_[i].trans_);
288 //pInfo->trans_ = trans;
289 return pInfo->thrTrans_[i].trans_;
292 Transaction** ProcessManager::getThreadTransAddr(int pslot)
294 pid_t pid = os::getpid();
295 pthread_t thrid = os::getthrid();
296 if (systemDatabase == NULL)
298 return NULL;
301 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
302 int i=0;
304 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
306 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
308 if (i == MAX_THREADS_PER_PROCESS)
310 printDebug(DM_Process, "Thread specific trans could not be found in list");
311 return NULL;
314 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
315 pid, thrid, pInfo->thrTrans_[i].trans_);
316 return &pInfo->thrTrans_[i].trans_;
322 void ProcessManager::printUsageStatistics()
324 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
325 int i=0, usedCount =0 , freeCount =0;
326 for (; i < Conf::config.getMaxProcs(); i++)
328 if (pInfo->pid_ != 0 ) usedCount++; else freeCount++;
329 pInfo++;
331 printf("<ProcTable>\n");
332 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
333 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
334 printf("</ProcTable>\n");
338 void ProcessManager::printDebugInfo()
340 printf("<ProcTable>\n");
341 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
342 int i=0, usedCount =0 , freeCount =0;
343 for (; i < Conf::config.getMaxProcs(); i++)
345 if (pInfo->pid_ != 0 ) {pInfo->print(); usedCount++;} else freeCount++;
346 pInfo++;
348 printf("<UsedSlots> %d </UsedSlots>\n", usedCount);
349 printf("<FreeSlots> %d </FreeSlots>\n", freeCount);
350 printf("</ProcTable>\n");
354 bool ProcessManager::isAnyOneRegistered()
356 //the process which calls this will have an entry in proc table.
357 //so checking for 1
358 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
359 int i=0, usedCount =0;
360 for (; i < Conf::config.getMaxProcs(); i++)
362 if (pInfo->pid_ != 0 ) usedCount++;
363 pInfo++;
365 if (usedCount == 1) return false; else return true;