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 Mutex
ProcessManager::prepareMutex
;
27 caddr_t
ProcessManager::sysAddr
=0;
28 caddr_t
ProcessManager::usrAddr
=0;
29 Database
* ProcessManager::systemDatabase
=NULL
;
31 void ThreadInfo::init()
36 for (int i
=0; i
<MAX_MUTEX_PER_THREAD
; i
++) has_
[i
] = NULL
;
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");
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
* tInfo
= systemDatabase
->getThreadInfo(0);
86 ThreadInfo
* freeSlot
= NULL
;
88 bool freeSlotSelected
= false;
89 for (; i
< Conf::config
.getMaxProcs(); i
++)
91 if (tInfo
->pid_
== 0 ) break;
94 if ( i
== Conf::config
.getMaxProcs())
96 systemDatabase
->releaseProcessTableMutex(false);
97 printError(ErrNoResource
, "No free thread slot. Limit reached");
100 logFiner(Conf::logger
, "Process slot taken: %d", i
);
103 tInfo
->thrid_
= thrid
;
105 printDebug(DM_Process
, "Process %d %lu registered with slot %d\n", pid
, thrid
, procSlot
);
106 systemDatabase
->releaseProcessTableMutex(false);
110 DbRetVal
ProcessManager::deregisterThread(int procSlot
)
112 //mutex.getLock(-1, false);
114 //mutex.releaseLock(-1, false);
115 DbRetVal rv
= systemDatabase
->getProcessTableMutex(false);
118 printError(rv
,"Unable to get process table mutex");
121 Transaction
*trans
= ProcessManager::getThreadTransaction(procSlot
);
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);
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);
148 printDebug(DM_Process
, "Process %d %lu deregistered slot %d\n", tInfo
->pid_
, tInfo
->thrid_
, procSlot
);
149 logFiner(Conf::logger
, "ProcSlot Freed %d", procSlot
);
151 systemDatabase
->releaseProcessTableMutex(false);
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
);
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
);
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
,
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
)
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
++;
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
++;
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.
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
++;
280 if (usedCount
== 1) return false; else return true;