changing global prepare mutex to process level mutex
[csql.git] / src / storage / Process.cxx
blob3a8b3aee8cb925ab2ec055e373be93317f3ab148
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 Mutex ProcessManager::prepareMutex;
27 caddr_t ProcessManager::sysAddr=0;
28 caddr_t ProcessManager::usrAddr=0;
29 Database* ProcessManager::systemDatabase=NULL;
30 List ProcessManager::hasLockList;
32 void ThreadInfo::init()
34 pid_ = 0;
35 thrid_ =0;
36 want_ = NULL;
37 for (int i =0; i <MAX_MUTEX_PER_THREAD; i++) has_[i] = NULL;
38 thrTrans_.init();
40 void ThreadTrans::print()
42 if (pid_ ==0) return;
43 printf("<THREADTRANS>\n");
44 printf(" <PID> %d </PID>\n", pid_);
45 printf(" <THRID> %lu </THRID>\n", thrid_);
46 printf(" <TRANSACTION> %x </TRANSACTION>\n");
47 printf("</THREADTRANS>\n");
49 void ThreadInfo::print()
51 printf("<THREADINFO>\n");
52 printf(" <PID> %d </PID>\n", pid_);
53 printf(" <THRID> %lu </THRID>\n", thrid_);
54 printf(" <WAIT> %x </WAIT>\n", want_);
55 printf(" <MUTEXLIST>\n");
56 for (int i =0; i <MAX_MUTEX_PER_THREAD; i++) if (has_[i]) printf(" <MUTEX> %x </MUTEX>\n", has_[i]);
57 printf(" </MUTEXLIST>\n");
58 printf(" <TRANSLIST>\n");
59 thrTrans_.print();
60 printf(" </TRANSLIST>\n");
61 printf("</THREADINFO>\n");
65 //It does not check for re registering as well as deregistering unregistered threads.
66 //as it is handled in the connection class open and close methods.
67 DbRetVal ProcessManager::registerThread()
69 //mutex.getLock(-1, false);
70 noThreads++;
71 // mutex.releaseLock(-1, false);
72 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
73 if (OK != rv)
75 printError(rv,"Unable to get mutex for registering");
76 printError(rv,"Recovery may be going on. Retry after some time.");
77 // mutex.getLock(-1, false);
78 noThreads--;
79 // mutex.releaseLock(-1, false);
80 return rv;
82 pid_t pid;
83 pid = os::getpid();
84 pthread_t thrid = os::getthrid();
85 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
86 int i=0;
87 ThreadInfo* freeSlot = NULL;
88 int freeSlotPos =0;
89 bool freeSlotSelected = false;
90 for (; i < Conf::config.getMaxProcs(); i++)
92 if (tInfo->pid_ == 0 ) break;
93 tInfo++;
95 if ( i == Conf::config.getMaxProcs())
97 systemDatabase->releaseProcessTableMutex(false);
98 printError(ErrNoResource, "No free thread slot. Limit reached");
99 return ErrNoResource;
101 logFiner(Conf::logger, "Process slot taken: %d", i);
102 tInfo->init();
103 tInfo->pid_ = pid;
104 tInfo->thrid_ = thrid;
105 procSlot = i;
106 printDebug(DM_Process, "Process %d %lu registered with slot %d\n", pid, thrid, procSlot);
107 systemDatabase->releaseProcessTableMutex(false);
108 return OK;
110 DbRetVal ProcessManager::deregisterThread(int procSlot)
112 //mutex.getLock(-1, false);
113 noThreads--;
114 //mutex.releaseLock(-1, false);
115 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
116 if (OK != rv)
118 printError(rv,"Unable to get process table mutex");
119 return rv;
121 Transaction *trans = ProcessManager::getThreadTransaction(procSlot);
122 if (NULL != trans)
124 if (trans->status_ == TransRunning)
126 printError(ErrWarning, "Transaction is still running\n");
128 trans->status_ = TransNotUsed;
130 ThreadInfo* tInfo = systemDatabase->getThreadInfo(procSlot);
131 if (tInfo->want_ != NULL)
133 printError(ErrSysFatal, "Fatal:wants_ is not null\n");
134 systemDatabase->releaseProcessTableMutex(false);
135 return ErrSysFatal;
137 for (int muti = 0 ;muti < MAX_MUTEX_PER_THREAD; muti++)
139 if (tInfo->has_[muti] != NULL)
141 printError(ErrSysFatal, "Fatal:Some mutexes are not freed %x\n",tInfo->has_[muti] );
142 tInfo->has_[muti]->print();
143 tInfo->has_[muti]->releaseLock(procSlot);
144 systemDatabase->releaseProcessTableMutex(false);
145 return ErrSysFatal;
148 printDebug(DM_Process, "Process %d %lu deregistered slot %d\n", tInfo->pid_, tInfo->thrid_, procSlot);
149 logFiner(Conf::logger, "ProcSlot Freed %d", procSlot);
150 tInfo->init();
151 systemDatabase->releaseProcessTableMutex(false);
152 return OK;
155 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
157 if (systemDatabase == NULL) return OK;
158 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
159 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
161 if (tInfo->has_[i] == NULL)
163 tInfo->has_[i] = mut;
164 printDebug(DM_Process, "procSlot %d acquiring %d mutex %x %s\n", pslot, i, mut, mut->name);
165 logFinest(Conf::logger, "acquiring mutex %x %s", mut, mut->name);
166 return OK;
169 printError(ErrSysInternal, "All slots are full. Reached per thread mutex limit.");
170 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
172 printError(ErrWarning, "mutex %d %x", i, tInfo->has_[i]);
173 tInfo->has_[i]->print();
175 return ErrSysInternal;
178 DbRetVal ProcessManager::removeMutex(Mutex *mut, int pslot)
180 if (systemDatabase == NULL) return OK;
181 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
182 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
184 if (tInfo->has_[i] == mut)
186 tInfo->has_[i] = NULL;
187 printDebug(DM_Process, "procSlot %d releasing %d mutex %x %s\n", pslot, i, mut, mut->name);
188 logFinest(Conf::logger, "releasing mutex %x %d", mut, mut->name);
189 return OK;
192 printError(ErrSysInternal, "Mutex could not be found in the list %s", mut->name);
193 return ErrSysInternal;
196 DbRetVal ProcessManager::setThreadTransaction(Transaction *trans, int pslot)
198 if (systemDatabase == NULL) return OK;
199 pid_t pid = os::getpid();
200 pthread_t thrid = os::getthrid();
202 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
203 tInfo->thrTrans_.pid_ = pid;
204 tInfo->thrTrans_.thrid_ = thrid;
205 tInfo->thrTrans_.trans_ = trans;
207 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot,
208 pid, thrid, trans);
209 return OK;
212 Transaction* ProcessManager::getThreadTransaction(int pslot)
214 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
215 return tInfo->thrTrans_.trans_;
218 Transaction** ProcessManager::getThreadTransAddr(int pslot)
220 pid_t pid = os::getpid();
221 pthread_t thrid = os::getthrid();
222 if (systemDatabase == NULL)
224 return NULL;
227 ThreadInfo* tInfo = systemDatabase->getThreadInfo(pslot);
229 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
230 pid, thrid, tInfo->thrTrans_.trans_);
231 return &tInfo->thrTrans_.trans_;
237 void ProcessManager::printUsageStatistics()
239 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
240 int i=0, usedCount =0 , freeCount =0;
241 for (; i < Conf::config.getMaxProcs(); i++)
243 if (tInfo->pid_ != 0 ) usedCount++; else freeCount++;
244 tInfo++;
246 printf("<ProcTable>\n");
247 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
248 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
249 printf("</ProcTable>\n");
253 void ProcessManager::printDebugInfo()
255 printf("<ProcTable>\n");
256 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
257 int i=0, usedCount =0 , freeCount =0;
258 for (; i < Conf::config.getMaxProcs(); i++)
260 if (tInfo->pid_ != 0 ) {tInfo->print(); usedCount++;} else freeCount++;
261 tInfo++;
263 printf("<UsedSlots> %d </UsedSlots>\n", usedCount);
264 printf("<FreeSlots> %d </FreeSlots>\n", freeCount);
265 printf("</ProcTable>\n");
268 //caller is expected to take proc mutex
269 bool ProcessManager::isAnyOneRegistered()
271 //the process which calls this will have an entry in proc table.
272 //so checking for 1
273 ThreadInfo* tInfo = systemDatabase->getThreadInfo(0);
274 int i=0, usedCount =0;
275 for (; i < Conf::config.getMaxProcs(); i++)
277 if (tInfo->pid_ != 0 ) usedCount++;
278 tInfo++;
280 if (usedCount == 1) return false; else return true;