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);
109 DbRetVal
ProcessManager::deregisterThread(int procSlot
)
111 //mutex.getLock(-1, false);
113 //mutex.releaseLock(-1, false);
114 DbRetVal rv
= systemDatabase
->getProcessTableMutex(false);
117 printError(rv
,"Unable to get process table mutex");
120 Transaction
*trans
= ProcessManager::getThreadTransaction(procSlot
);
123 if (trans
->status_
== TransRunning
)
125 printError(ErrWarning
, "Transaction is still running\n");
127 trans
->status_
= TransNotUsed
;
129 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(procSlot
);
130 if (tInfo
->want_
!= NULL
)
132 printError(ErrSysFatal
, "Fatal:wants_ is not null\n");
133 systemDatabase
->releaseProcessTableMutex(false);
136 for (int muti
= 0 ;muti
< MAX_MUTEX_PER_THREAD
; muti
++)
138 if (tInfo
->has_
[muti
] != NULL
)
140 printError(ErrSysFatal
, "Fatal:Some mutexes are not freed %x\n",tInfo
->has_
[muti
] );
141 tInfo
->has_
[muti
]->print();
142 tInfo
->has_
[muti
]->releaseLock(procSlot
);
143 systemDatabase
->releaseProcessTableMutex(false);
147 printDebug(DM_Process
, "Process %d %lu deregistered slot %d\n", tInfo
->pid_
, tInfo
->thrid_
, procSlot
);
148 logFiner(Conf::logger
, "ProcSlot Freed %d", procSlot
);
150 systemDatabase
->releaseProcessTableMutex(false);
154 DbRetVal
ProcessManager::addMutex(Mutex
*mut
, int pslot
)
156 if (systemDatabase
== NULL
) return OK
;
157 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(pslot
);
158 for (int i
= 0 ;i
< MAX_MUTEX_PER_THREAD
; i
++)
160 if (tInfo
->has_
[i
] == NULL
)
162 tInfo
->has_
[i
] = mut
;
163 printDebug(DM_Process
, "procSlot %d acquiring %d mutex %x %s\n", pslot
, i
, mut
, mut
->name
);
164 logFinest(Conf::logger
, "acquiring mutex %x %s", mut
, mut
->name
);
168 printError(ErrSysInternal
, "All slots are full. Reached per thread mutex limit.");
169 for (int i
= 0 ;i
< MAX_MUTEX_PER_THREAD
; i
++)
171 printError(ErrWarning
, "mutex %d %x", i
, tInfo
->has_
[i
]);
172 tInfo
->has_
[i
]->print();
174 return ErrSysInternal
;
177 DbRetVal
ProcessManager::removeMutex(Mutex
*mut
, int pslot
)
179 if (systemDatabase
== NULL
) return OK
;
180 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(pslot
);
181 for (int i
= 0 ;i
< MAX_MUTEX_PER_THREAD
; i
++)
183 if (tInfo
->has_
[i
] == mut
)
185 tInfo
->has_
[i
] = NULL
;
186 printDebug(DM_Process
, "procSlot %d releasing %d mutex %x %s\n", pslot
, i
, mut
, mut
->name
);
187 logFinest(Conf::logger
, "releasing mutex %x %d", mut
, mut
->name
);
191 printError(ErrSysInternal
, "Mutex could not be found in the list %s", mut
->name
);
192 return ErrSysInternal
;
195 DbRetVal
ProcessManager::setThreadTransaction(Transaction
*trans
, int pslot
)
197 if (systemDatabase
== NULL
) return OK
;
198 pid_t pid
= os::getpid();
199 pthread_t thrid
= os::getthrid();
201 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(pslot
);
202 tInfo
->thrTrans_
.pid_
= pid
;
203 tInfo
->thrTrans_
.thrid_
= thrid
;
204 tInfo
->thrTrans_
.trans_
= trans
;
206 printDebug(DM_Process
, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot
,
211 Transaction
* ProcessManager::getThreadTransaction(int pslot
)
213 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(pslot
);
214 return tInfo
->thrTrans_
.trans_
;
217 Transaction
** ProcessManager::getThreadTransAddr(int pslot
)
219 pid_t pid
= os::getpid();
220 pthread_t thrid
= os::getthrid();
221 if (systemDatabase
== NULL
)
226 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(pslot
);
228 printDebug(DM_Process
, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot
,
229 pid
, thrid
, tInfo
->thrTrans_
.trans_
);
230 return &tInfo
->thrTrans_
.trans_
;
236 void ProcessManager::printUsageStatistics()
238 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(0);
239 int i
=0, usedCount
=0 , freeCount
=0;
240 for (; i
< Conf::config
.getMaxProcs(); i
++)
242 if (tInfo
->pid_
!= 0 ) usedCount
++; else freeCount
++;
245 printf("<ProcTable>\n");
246 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount
);
247 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount
);
248 printf("</ProcTable>\n");
252 void ProcessManager::printDebugInfo()
254 printf("<ProcTable>\n");
255 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(0);
256 int i
=0, usedCount
=0 , freeCount
=0;
257 for (; i
< Conf::config
.getMaxProcs(); i
++)
259 if (tInfo
->pid_
!= 0 ) {tInfo
->print(); usedCount
++;} else freeCount
++;
262 printf("<UsedSlots> %d </UsedSlots>\n", usedCount
);
263 printf("<FreeSlots> %d </FreeSlots>\n", freeCount
);
264 printf("</ProcTable>\n");
267 //caller is expected to take proc mutex
268 bool ProcessManager::isAnyOneRegistered()
270 //the process which calls this will have an entry in proc table.
272 ThreadInfo
* tInfo
= systemDatabase
->getThreadInfo(0);
273 int i
=0, usedCount
=0;
274 for (; i
< Conf::config
.getMaxProcs(); i
++)
276 if (tInfo
->pid_
!= 0 ) usedCount
++;
279 if (usedCount
== 1) return false; else return true;