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 mutex for registering");
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");
147 trans
->status_
= TransNotUsed
;
149 if (pInfo
->want_
!= NULL
)
151 printError(ErrSysFatal
, "Probable data corruption.wants_ is not null\n");
152 systemDatabase
->releaseProcessTableMutex(false);
155 for (int muti
= 0 ;muti
< MAX_MUTEX_PER_THREAD
; muti
++)
157 if (pInfo
->has_
[muti
] != NULL
)
159 printError(ErrSysFatal
, "Probable data corruption.some mutexes are not freed %x \n", pInfo
->has_
[muti
] );
160 pInfo
->has_
[muti
]->print();
161 pInfo
->has_
[muti
]->releaseLock(procSlot
);
162 systemDatabase
->releaseProcessTableMutex(false);
166 printDebug(DM_Process
, "Process %d %lu deregistered slot %d\n", pInfo
->pid_
, pInfo
->thrid_
, procSlot
);
168 //printf("Slot freed %d %x %d %lu\n", i, pInfo, pid, thrid);
170 systemDatabase
->releaseProcessTableMutex(false);
174 DbRetVal
ProcessManager::addMutex(Mutex
*mut
, int pslot
)
176 //pid_t pid = os::getpid();
177 //pthread_t thrid = os::getthrid();
178 if (systemDatabase
== NULL
)
182 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
184 /*for (; i < Conf::config.getMaxProcs(); i++)
186 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
189 if (i == Conf::config.getMaxProcs())
191 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable while adding mutex %s", pid, thrid, mut->name);
194 for (int i
= 0 ;i
< MAX_MUTEX_PER_THREAD
; i
++)
196 if (pInfo
->has_
[i
] == NULL
)
198 pInfo
->has_
[i
] = mut
;
199 printDebug(DM_Process
, "procSlot %d acquiring %d mutex %x %s\n", pslot
, i
, mut
, mut
->name
);
203 printError(ErrSysInternal
, "All slots are full. Reached per thread mutex limit.");
205 for (int i
= 0 ;i
< MAX_MUTEX_PER_THREAD
; i
++)
207 printError(ErrWarning
, "mutex %d %x", i
, pInfo
->has_
[i
]);
208 pInfo
->has_
[i
]->print();
210 return ErrSysInternal
;
213 DbRetVal
ProcessManager::removeMutex(Mutex
*mut
, int pslot
)
215 //pid_t pid = os::getpid();
216 //pthread_t thrid = os::getthrid();
217 if (systemDatabase
== NULL
)
222 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
224 /*for (; i < Conf::config.getMaxProcs(); i++)
226 if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
229 if (i == Conf::config.getMaxProcs())
231 printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
234 for (int i
= 0 ;i
< MAX_MUTEX_PER_THREAD
; i
++)
236 if (pInfo
->has_
[i
] == mut
)
238 pInfo
->has_
[i
] = NULL
;
239 printDebug(DM_Process
, "procSlot %d releasing %d mutex %x %s\n", pslot
, i
, mut
, mut
->name
);
243 printError(ErrSysInternal
, "Mutex could not be found in the list %s", mut
->name
);
244 return ErrSysInternal
;
247 DbRetVal
ProcessManager::setThreadTransaction(Transaction
*trans
, int pslot
)
249 pid_t pid
= os::getpid();
250 pthread_t thrid
= os::getthrid();
251 if (systemDatabase
== NULL
)
256 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
259 for (int i
= 0 ;i
< MAX_THREADS_PER_PROCESS
; i
++)
261 if (pInfo
->thrTrans_
[i
].pid_
!= 0) continue;
263 if (i
== MAX_THREADS_PER_PROCESS
)
265 printError(ErrSysInternal
, "Max thread limit reached.");
266 return ErrSysInternal
;
268 pInfo
->thrTrans_
[i
].pid_
= pid
;
269 pInfo
->thrTrans_
[i
].thrid_
= thrid
;
270 pInfo
->thrTrans_
[i
].trans_
= trans
;
272 printDebug(DM_Process
, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot
,
274 //pInfo->trans_ = trans;
278 Transaction
* ProcessManager::getThreadTransaction(int pslot
)
280 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
281 return pInfo
->thrTrans_
[0].trans_
;
284 Transaction
** ProcessManager::getThreadTransAddr(int pslot
)
286 pid_t pid
= os::getpid();
287 pthread_t thrid
= os::getthrid();
288 if (systemDatabase
== NULL
)
293 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(pslot
);
296 for (int i
= 0 ;i
< MAX_THREADS_PER_PROCESS
; i
++)
298 if (pInfo
->thrTrans_
[i
].pid_
== pid
&& pInfo
->thrTrans_
[i
].thrid_
== thrid
) break;
300 if (i
== MAX_THREADS_PER_PROCESS
)
302 printDebug(DM_Process
, "Thread specific trans could not be found in list");
306 printDebug(DM_Process
, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot
,
307 pid
, thrid
, pInfo
->thrTrans_
[i
].trans_
);
308 return &pInfo
->thrTrans_
[i
].trans_
;
314 void ProcessManager::printUsageStatistics()
316 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(0);
317 int i
=0, usedCount
=0 , freeCount
=0;
318 for (; i
< Conf::config
.getMaxProcs(); i
++)
320 if (pInfo
->pid_
!= 0 ) usedCount
++; else freeCount
++;
323 printf("<ProcTable>\n");
324 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount
);
325 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount
);
326 printf("</ProcTable>\n");
330 void ProcessManager::printDebugInfo()
332 printf("<ProcTable>\n");
333 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(0);
334 int i
=0, usedCount
=0 , freeCount
=0;
335 for (; i
< Conf::config
.getMaxProcs(); i
++)
337 if (pInfo
->pid_
!= 0 ) {pInfo
->print(); usedCount
++;} else freeCount
++;
340 printf("<UsedSlots> %d </UsedSlots>\n", usedCount
);
341 printf("<FreeSlots> %d </FreeSlots>\n", freeCount
);
342 printf("</ProcTable>\n");
346 bool ProcessManager::isAnyOneRegistered()
348 //the process which calls this will have an entry in proc table.
350 ThreadInfo
* pInfo
= systemDatabase
->getThreadInfo(0);
351 int i
=0, usedCount
=0;
352 for (; i
< Conf::config
.getMaxProcs(); i
++)
354 if (pInfo
->pid_
!= 0 ) usedCount
++;
357 if (usedCount
== 1) return false; else return true;