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");
79 pthread_t thrid
= os::getthrid();
80 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(0);
82 ThreadInfo
* freeSlot
= NULL
;
84 bool freeSlotSelected
= false;
85 for (; i
< Conf::config
.getMaxProcs(); i
++)
87 if (pInfo
->pid_
== 0 ) break;
90 if ( i
== Conf::config
.getMaxProcs())
92 systemDatabase
->releaseProcessTableMutex(false);
93 printError(ErrNoResource
, "No free thread slot. Limit reached");
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
101 pInfo
->thrid_
= thrid
;
103 printDebug(DM_Process
, "Process %d %lu registered with slot %d\n", pid
, thrid
, procSlot
);
104 systemDatabase
->releaseProcessTableMutex(false);
107 DbRetVal
ProcessManager::deregisterThread(int procSlot
)
109 mutex
.getLock(-1, false);
111 mutex
.releaseLock(-1, false);
112 DbRetVal rv
= systemDatabase
->getProcessTableMutex(false);
115 printError(rv
,"Unable to get process table mutex");
118 pid_t pid = os::getpid();
119 pthread_t thrid = os::getthrid();
121 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
123 for (; i < Conf::config.getMaxProcs(); i++)
125 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
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
);
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");
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
);
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);
162 systemDatabase
->releaseProcessTableMutex(false);
166 DbRetVal
ProcessManager::addMutex(Mutex
*mut
, int pslot
)
168 //pid_t pid = os::getpid();
169 //pthread_t thrid = os::getthrid();
170 if (systemDatabase
== NULL
)
174 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
176 /*for (; i < Conf::config.getMaxProcs(); i++)
178 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
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);
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
);
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
)
208 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
210 /*for (; i < Conf::config.getMaxProcs(); i++)
212 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
215 if (i == Conf::config.getMaxProcs())
217 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
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
);
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
)
242 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
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
,
260 //pInfo->trans_ = trans;
264 Transaction
* ProcessManager::getThreadTransaction(int pslot
)
266 pid_t pid
= os::getpid();
267 pthread_t thrid
= os::getthrid();
268 if (systemDatabase
== NULL
)
273 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
276 for (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");
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
)
301 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
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");
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
++;
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
++;
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.
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
++;
365 if (usedCount
== 1) return false; else return true;