code reorganisation phase-I
[csql.git] / src / storage / Process.cxx
blobdff0ec4b39404c1e8a2d38ca08c0e6fbf2e95b71
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 thrTrans_.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 thrTrans_.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* tInfo = 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 (tInfo->pid_ == 0 ) break;
92 tInfo++;
94 if ( i == Conf::config.getMaxProcs())
96 systemDatabase->releaseProcessTableMutex(false);
97 printError(ErrNoResource, "No free thread slot. Limit reached");
98 return ErrNoResource;
100 logFiner(Conf::logger, "Process slot taken: %d", i);
101 tInfo->init();
102 tInfo->pid_ = pid;
103 tInfo->thrid_ = thrid;
104 procSlot = i;
105 printDebug(DM_Process, "Process %d %lu registered with slot %d\n", pid, thrid, procSlot);
106 systemDatabase->releaseProcessTableMutex(false);
107 return OK;
109 DbRetVal ProcessManager::deregisterThread(int procSlot)
111 mutex.getLock(-1, false);
112 noThreads--;
113 mutex.releaseLock(-1, false);
114 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
115 if (OK != rv)
117 printError(rv,"Unable to get process table mutex");
118 return rv;
120 Transaction *trans = ProcessManager::getThreadTransaction(procSlot);
121 if (NULL != trans)
123 if (trans->status_ == TransRunning)
125 printError(ErrWarning, "Transaction is still running\n");
127 trans->status_ = TransNotUsed;
129 ThreadInfo* tInfo = systemDatabase->getThreadInfo(procSlot);
130 if (tInfo->want_ != NULL)
132 printError(ErrSysFatal, "Fatal:wants_ is not null\n");
133 systemDatabase->releaseProcessTableMutex(false);
134 return ErrSysFatal;
136 for (int muti = 0 ;muti < MAX_MUTEX_PER_THREAD; muti++)
138 if (tInfo->has_[muti] != NULL)
140 printError(ErrSysFatal, "Fatal:Some mutexes are not freed %x\n",tInfo->has_[muti] );
141 tInfo->has_[muti]->print();
142 tInfo->has_[muti]->releaseLock(procSlot);
143 systemDatabase->releaseProcessTableMutex(false);
144 return ErrSysFatal;
147 printDebug(DM_Process, "Process %d %lu deregistered slot %d\n", tInfo->pid_, tInfo->thrid_, procSlot);
148 logFiner(Conf::logger, "ProcSlot Freed %d", procSlot);
149 tInfo->init();
150 systemDatabase->releaseProcessTableMutex(false);
151 return OK;
154 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
156 if (systemDatabase == NULL) return OK;
157 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
158 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
160 if (tInfo->has_[i] == NULL)
162 tInfo->has_[i] = mut;
163 printDebug(DM_Process, "procSlot %d acquiring %d mutex %x %s\n", pslot, i, mut, mut->name);
164 logFinest(Conf::logger, "acquiring mutex %x %s", mut, mut->name);
165 return OK;
168 printError(ErrSysInternal, "All slots are full. Reached per thread mutex limit.");
169 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
171 printError(ErrWarning, "mutex %d %x", i, tInfo->has_[i]);
172 tInfo->has_[i]->print();
174 return ErrSysInternal;
177 DbRetVal ProcessManager::removeMutex(Mutex *mut, int pslot)
179 if (systemDatabase == NULL) return OK;
180 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
181 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
183 if (tInfo->has_[i] == mut)
185 tInfo->has_[i] = NULL;
186 printDebug(DM_Process, "procSlot %d releasing %d mutex %x %s\n", pslot, i, mut, mut->name);
187 logFinest(Conf::logger, "releasing mutex %x %d", mut, mut->name);
188 return OK;
191 printError(ErrSysInternal, "Mutex could not be found in the list %s", mut->name);
192 return ErrSysInternal;
195 DbRetVal ProcessManager::setThreadTransaction(Transaction *trans, int pslot)
197 if (systemDatabase == NULL) return OK;
198 pid_t pid = os::getpid();
199 pthread_t thrid = os::getthrid();
201 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
202 tInfo->thrTrans_.pid_ = pid;
203 tInfo->thrTrans_.thrid_ = thrid;
204 tInfo->thrTrans_.trans_ = trans;
206 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot,
207 pid, thrid, trans);
208 return OK;
211 Transaction* ProcessManager::getThreadTransaction(int pslot)
213 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
214 return tInfo->thrTrans_.trans_;
217 Transaction** ProcessManager::getThreadTransAddr(int pslot)
219 pid_t pid = os::getpid();
220 pthread_t thrid = os::getthrid();
221 if (systemDatabase == NULL)
223 return NULL;
226 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
228 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
229 pid, thrid, tInfo->thrTrans_.trans_);
230 return &tInfo->thrTrans_.trans_;
236 void ProcessManager::printUsageStatistics()
238 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
239 int i=0, usedCount =0 , freeCount =0;
240 for (; i < Conf::config.getMaxProcs(); i++)
242 if (tInfo->pid_ != 0 ) usedCount++; else freeCount++;
243 tInfo++;
245 printf("<ProcTable>\n");
246 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
247 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
248 printf("</ProcTable>\n");
252 void ProcessManager::printDebugInfo()
254 printf("<ProcTable>\n");
255 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
256 int i=0, usedCount =0 , freeCount =0;
257 for (; i < Conf::config.getMaxProcs(); i++)
259 if (tInfo->pid_ != 0 ) {tInfo->print(); usedCount++;} else freeCount++;
260 tInfo++;
262 printf("<UsedSlots> %d </UsedSlots>\n", usedCount);
263 printf("<FreeSlots> %d </FreeSlots>\n", freeCount);
264 printf("</ProcTable>\n");
267 //caller is expected to take proc mutex
268 bool ProcessManager::isAnyOneRegistered()
270 //the process which calls this will have an entry in proc table.
271 //so checking for 1
272 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
273 int i=0, usedCount =0;
274 for (; i < Conf::config.getMaxProcs(); i++)
276 if (tInfo->pid_ != 0 ) usedCount++;
277 tInfo++;
279 if (usedCount == 1) return false; else return true;