src/server/Process.cxx

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by www.databasecache.com                           *
00003  *   Contact: praba_tuty@databasecache.com                                 *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
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 //It does not check for re registering as well as deregistering unregistered threads.
00065 //as it is handled in the connection class open and close methods.
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     //printf("Process slot used %d %x\n", i, pInfo);
00097     //TODO::make the above debug message
00098     //TODO:print it to the trace file
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     pid_t pid = os::getpid();
00119     pthread_t thrid = os::getthrid();
00120 
00121     ThreadInfo* pInfo = systemDatabase->getThreadInfo(0);
00122     int i=0;
00123     for (; i < Conf::config.getMaxProcs(); i++)
00124     {
00125         if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
00126         pInfo++;
00127     }
00128 
00129     systemDatabase->releaseProcessTableMutex(false);
00130     if (i == Conf::config.getMaxProcs()) 
00131     {
00132         printError(ErrSysFatal, "Degistering process %d is not registered with csql", pid);
00133         return ErrNoResource;
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     //printf("Slot freed %d %x %d %lu\n", i, pInfo, pid, thrid); 
00161     pInfo->init();
00162     systemDatabase->releaseProcessTableMutex(false);
00163     return OK;
00164 }
00165 
00166 DbRetVal ProcessManager::addMutex(Mutex *mut, int pslot)
00167 {
00168     //pid_t pid = os::getpid();
00169     //pthread_t thrid = os::getthrid();
00170     if (systemDatabase == NULL)
00171     {
00172         return OK;
00173     }
00174     ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00175     int i=0;
00176     /*for (; i < Conf::config.getMaxProcs(); i++)
00177     {
00178         if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
00179         pInfo++;
00180     }
00181     if (i == Conf::config.getMaxProcs())
00182     {
00183         printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable while adding mutex %s", pid, thrid, mut->name);
00184         return ErrSysFatal;
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     //pid_t pid = os::getpid();
00202     //pthread_t thrid = os::getthrid();
00203     if (systemDatabase == NULL)
00204     {
00205         return OK;
00206     }
00207 
00208     ThreadInfo* pInfo = systemDatabase->getThreadInfo(pslot);
00209     int i=0;
00210     /*for (; i < Conf::config.getMaxProcs(); i++)
00211     {
00212         if (pInfo->pid_ == pid && pInfo->thrid_ == thrid) break;
00213         pInfo++;
00214     }
00215     if (i == Conf::config.getMaxProcs())
00216     {
00217         printError(ErrSysFatal, "Logical Error pid %d thrid %lu not found in procTable", pid, thrid);
00218         return ErrSysFatal;
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     //pInfo->trans_ = trans;
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     //pInfo->trans_ = trans;
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     //the process which calls this will have an entry in proc table. 
00357     //so checking for 1
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 }

Generated on Mon Jun 9 22:37:15 2008 for csql by  doxygen 1.4.7