1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
20 #include <ErrorType.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()
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()
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);
70 mutex
.releaseLock(-1, false);
71 DbRetVal rv
= systemDatabase
->getProcessTableMutex(false);
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);
78 mutex
.releaseLock(-1, false);
83 pthread_t thrid
= os::getthrid();
84 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(0);
86 ThreadInfo
* freeSlot
= NULL
;
88 bool freeSlotSelected
= false;
89 for (; i
< Conf::config
.getMaxProcs(); i
++)
91 if (pInfo
->pid_
== 0 ) break;
94 if ( i
== Conf::config
.getMaxProcs())
96 systemDatabase
->releaseProcessTableMutex(false);
97 printError(ErrNoResource
, "No free thread slot. Limit reached");
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
105 pInfo
->thrid_
= thrid
;
107 printDebug(DM_Process
, "Process %d %lu registered with slot %d\n", pid
, thrid
, procSlot
);
108 systemDatabase
->releaseProcessTableMutex(false);
111 DbRetVal
ProcessManager::deregisterThread(int procSlot
)
113 mutex
.getLock(-1, false);
115 mutex
.releaseLock(-1, false);
116 DbRetVal rv
= systemDatabase
->getProcessTableMutex(false);
119 printError(rv
,"Unable to get process table mutex");
122 pid_t pid = os::getpid();
123 pthread_t thrid = os::getthrid();
125 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
127 for (; i < Conf::config.getMaxProcs(); i++)
129 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
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
);
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");
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
);
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);
166 systemDatabase
->releaseProcessTableMutex(false);
170 DbRetVal
ProcessManager::addMutex(Mutex
*mut
, int pslot
)
172 //pid_t pid = os::getpid();
173 //pthread_t thrid = os::getthrid();
174 if (systemDatabase
== NULL
)
178 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
180 /*for (; i < Conf::config.getMaxProcs(); i++)
182 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
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);
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
);
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
)
212 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
214 /*for (; i < Conf::config.getMaxProcs(); i++)
216 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
219 if (i == Conf::config.getMaxProcs())
221 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
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
);
233 printError(ErrSysInternal
, "Mutex could not be found in the list %s", mut
->name
);
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
)
250 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
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
,
268 //pInfo->trans_ = trans;
272 Transaction
* ProcessManager::getThreadTransaction(int pslot
)
274 pid_t pid
= os::getpid();
275 pthread_t thrid
= os::getthrid();
276 if (systemDatabase
== NULL
)
281 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
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");
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
)
309 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
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");
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
++;
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
++;
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.
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
++;
373 if (usedCount
== 1) return false; else return true;