00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <Process.h>
00017 #include <Debug.h>
00018 #include <Database.h>
00019 #include <Config.h>
00020 #include <ErrorType.h>
00021 #include <Globals.h>
00022 #include <Mutex.h>
00023
00024 int ProcessManager::noThreads=0;
00025 Mutex ProcessManager::mutex;
00026 caddr_t ProcessManager::sysAddr=0;
00027 caddr_t ProcessManager::usrAddr=0;
00028 Database* ProcessManager::systemDatabase=NULL;
00029 List ProcessManager::hasLockList;
00030
00031 void ThreadInfo::init()
00032 {
00033 pid_ = 0;
00034 thrid_ =0;
00035 want_ = NULL;
00036 for (int i =0; i <MAX_MUTEX_PER_THREAD; i++) has_[i] = NULL;
00037 for (int i =0; i <MAX_THREADS_PER_PROCESS; i++) thrTrans_[i].init();
00038 }
00039 void ThreadTrans::print()
00040 {
00041 if (pid_ ==0) return;
00042 printf("<THREADTRANS>\n");
00043 printf(" <PID> %d </PID>\n", pid_);
00044 printf(" <THRID> %lu </THRID>\n", thrid_);
00045 printf(" <TRANSACTION> %x </TRANSACTION>\n");
00046 printf("</THREADTRANS>\n");
00047 }
00048 void ThreadInfo::print()
00049 {
00050 printf("<THREADINFO>\n");
00051 printf(" <PID> %d </PID>\n", pid_);
00052 printf(" <THRID> %lu </THRID>\n", thrid_);
00053 printf(" <WAIT> %x </WAIT>\n", want_);
00054 printf(" <MUTEXLIST>\n");
00055 for (int i =0; i <MAX_MUTEX_PER_THREAD; i++) if (has_[i]) printf(" <MUTEX> %x </MUTEX>\n", has_[i]);
00056 printf(" </MUTEXLIST>\n");
00057 printf(" <TRANSLIST>\n");
00058 for (int i =0; i <MAX_THREADS_PER_PROCESS; i++) thrTrans_[i].print();
00059 printf(" </TRANSLIST>\n");
00060 printf("</THREADINFO>\n");
00061
00062 }
00063
00064
00065
00066 DbRetVal ProcessManager::registerThread()
00067 {
00068 mutex.getLock(false);
00069 noThreads++;
00070 mutex.releaseLock(false);
00071 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
00072 if (OK != rv)
00073 {
00074 printError(rv,"Unable to get process table mutex");
00075 return rv;
00076 }
00077 pid_t pid;
00078 pid = os::getpid();
00079 pthread_t thrid = os::getthrid();
00080 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
00081 int i=0;
00082 ThreadInfo* freeSlot = NULL;
00083 int freeSlotPos =0;
00084 bool freeSlotSelected = false;
00085 for (; i < Conf::config.getMaxProcs(); i++)
00086 {
00087 if (pInfo->pid_ == 0 ) break;
00088 pInfo++;
00089 }
00090 if ( i == Conf::config.getMaxProcs())
00091 {
00092 systemDatabase->releaseProcessTableMutex(false);
00093 printError(ErrNoResource, "No free thread slot. Limit reached");
00094 return ErrNoResource;
00095 }
00096
00097
00098
00099 pInfo->init();
00100 pInfo->pid_ = pid;
00101 pInfo->thrid_ = thrid;
00102 procSlot = i;
00103 printDebug(DM_Process, "Process %d %lu registered with slot %d\n", pid, thrid, procSlot);
00104 systemDatabase->releaseProcessTableMutex(false);
00105 return OK;
00106 }
00107 DbRetVal ProcessManager::deregisterThread(int procSlot)
00108 {
00109 mutex.getLock(false);
00110 noThreads--;
00111 mutex.releaseLock(false);
00112 DbRetVal rv = systemDatabase->getProcessTableMutex(false);
00113 if (OK != rv)
00114 {
00115 printError(rv,"Unable to get process table mutex");
00116 return rv;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 ThreadInfo* pInfo = systemDatabase->getThreadInfo(procSlot);
00136 Transaction *trans = ProcessManager::getThreadTransaction(procSlot);
00137 if (NULL != trans)
00138 {
00139 if (trans->status_ == TransRunning)
00140 {
00141 printError(ErrWarning, "Transaction is still running\n");
00142 }
00143 }
00144 if (pInfo->want_ != NULL)
00145 {
00146 printError(ErrSysFatal, "Probable data corruption.wants_ is not null\n");
00147 return ErrSysFatal;
00148 }
00149 for (int muti = 0 ;muti < MAX_MUTEX_PER_THREAD; muti++)
00150 {
00151 if (pInfo->has_[muti] != NULL)
00152 {
00153 printError(ErrSysFatal, "Probable data corruption.some mutexes are not freed %x %s\n", pInfo->has_[muti], pInfo->has_[muti]->name);
00154 pInfo->has_[muti]->releaseLock(procSlot);
00155 return ErrSysFatal;
00156 }
00157 }
00158 printDebug(DM_Process, "Process %d %lu deregistered slot %d\n", pInfo->pid_, pInfo->thrid_, procSlot);
00159
00160
00161 pInfo->init();
00162 systemDatabase->releaseProcessTableMutex(false);
00163 return OK;
00164 }
00165
00166 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
00167 {
00168
00169
00170 if (systemDatabase == NULL)
00171 {
00172 return OK;
00173 }
00174 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00175 int i=0;
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
00187 {
00188 if (pInfo->has_[i] == NULL)
00189 {
00190 pInfo->has_[i] = mut;
00191 printDebug(DM_Process, "procSlot %d acquiring %d mutex %x %s\n", pslot, i, mut, mut->name);
00192 return OK;
00193 }
00194 }
00195 printError(ErrSysInternal, "All slots are full. Reached per thread mutex limit.");
00196 return ErrSysInternal;
00197 }
00198
00199 DbRetVal ProcessManager::removeMutex(Mutex *mut, int pslot)
00200 {
00201
00202
00203 if (systemDatabase == NULL)
00204 {
00205 return OK;
00206 }
00207
00208 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00209 int i=0;
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 for (int i = 0 ;i < MAX_MUTEX_PER_THREAD; i++)
00221 {
00222 if (pInfo->has_[i] == mut)
00223 {
00224 pInfo->has_[i] = NULL;
00225 printDebug(DM_Process, "procSlot %d releasing %d mutex %x %s\n", pslot, i, mut, mut->name);
00226 return OK;
00227 }
00228 }
00229 printError(ErrSysInternal, "Mutex could not be found in the list %s", mut->name);
00230 return ErrSysInternal;
00231 }
00232
00233 DbRetVal ProcessManager::setThreadTransaction(Transaction *trans, int pslot)
00234 {
00235 pid_t pid = os::getpid();
00236 pthread_t thrid = os::getthrid();
00237 if (systemDatabase == NULL)
00238 {
00239 return OK;
00240 }
00241
00242 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00243 int i=0;
00244
00245 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
00246 {
00247 if (pInfo->thrTrans_[i].pid_ != 0) continue;
00248 }
00249 if (i == MAX_THREADS_PER_PROCESS)
00250 {
00251 printError(ErrSysInternal, "Max thread limit reached.");
00252 return ErrSysInternal;
00253 }
00254 pInfo->thrTrans_[i].pid_ = pid;
00255 pInfo->thrTrans_[i].thrid_ = thrid;
00256 pInfo->thrTrans_[i].trans_ = trans;
00257
00258 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is set to use trans %x\n", pslot,
00259 pid, thrid, trans);
00260
00261 return OK;
00262 }
00263
00264 Transaction* ProcessManager::getThreadTransaction(int pslot)
00265 {
00266 pid_t pid = os::getpid();
00267 pthread_t thrid = os::getthrid();
00268 if (systemDatabase == NULL)
00269 {
00270 return NULL;
00271 }
00272
00273 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00274 int i=0;
00275
00276 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
00277 {
00278 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
00279 }
00280 if (i == MAX_THREADS_PER_PROCESS)
00281 {
00282 printDebug(DM_Process, "Thread specific trans could not be found in list");
00283 return NULL;
00284 }
00285
00286 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
00287 pid, thrid, pInfo->thrTrans_[i].trans_);
00288
00289 return pInfo->thrTrans_[i].trans_;
00290 }
00291
00292 Transaction** ProcessManager::getThreadTransAddr(int pslot)
00293 {
00294 pid_t pid = os::getpid();
00295 pthread_t thrid = os::getthrid();
00296 if (systemDatabase == NULL)
00297 {
00298 return NULL;
00299 }
00300
00301 ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00302 int i=0;
00303
00304 for (int i = 0 ;i < MAX_THREADS_PER_PROCESS; i++)
00305 {
00306 if (pInfo->thrTrans_[i].pid_ == pid && pInfo->thrTrans_[i].thrid_ == thrid) break;
00307 }
00308 if (i == MAX_THREADS_PER_PROCESS)
00309 {
00310 printDebug(DM_Process, "Thread specific trans could not be found in list");
00311 return NULL;
00312 }
00313
00314 printDebug(DM_Process, "procSlot %d: pid: %d thrid: %lu is returning trans %x\n", pslot,
00315 pid, thrid, pInfo->thrTrans_[i].trans_);
00316 return &pInfo->thrTrans_[i].trans_;
00317 }
00318
00319
00320
00321
00322 void ProcessManager::printUsageStatistics()
00323 {
00324 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
00325 int i=0, usedCount =0 , freeCount =0;
00326 for (; i < Conf::config.getMaxProcs(); i++)
00327 {
00328 if (pInfo->pid_ != 0 ) usedCount++; else freeCount++;
00329 pInfo++;
00330 }
00331 printf("<ProcTable>\n");
00332 printf(" <UsedSlots> %d </UsedSlots>\n", usedCount);
00333 printf(" <FreeSlots> %d </FreeSlots>\n", freeCount);
00334 printf("</ProcTable>\n");
00335
00336 }
00337
00338 void ProcessManager::printDebugInfo()
00339 {
00340 printf("<ProcTable>\n");
00341 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
00342 int i=0, usedCount =0 , freeCount =0;
00343 for (; i < Conf::config.getMaxProcs(); i++)
00344 {
00345 if (pInfo->pid_ != 0 ) {pInfo->print(); usedCount++;} else freeCount++;
00346 pInfo++;
00347 }
00348 printf("<UsedSlots> %d </UsedSlots>\n", usedCount);
00349 printf("<FreeSlots> %d </FreeSlots>\n", freeCount);
00350 printf("</ProcTable>\n");
00351 }
00352
00353
00354 bool ProcessManager::isAnyOneRegistered()
00355 {
00356
00357
00358 ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
00359 int i=0, usedCount =0;
00360 for (; i < Conf::config.getMaxProcs(); i++)
00361 {
00362 if (pInfo->pid_ != 0 ) usedCount++;
00363 pInfo++;
00364 }
00365 if (usedCount == 1) return false; else return true;
00366 }