src/server/Mutex.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 <os.h>
00017 #include <Mutex.h>
00018 #include <Debug.h>
00019 #include <NanoTimer.h>
00020 #include <Config.h>
00021 #include <Process.h>
00022 Mutex::Mutex()
00023 {
00024 #if defined(sparc) || defined(i686)
00025     lock =0;
00026 #else
00027     pthread_mutexattr_t attr;
00028     pthread_mutexattr_init(&attr);
00029     pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
00030     pthread_mutex_init(&mutex_, &attr);
00031 #endif
00032 }
00033 
00034 int Mutex::init()
00035 {
00036 #if defined(sparc) || defined(i686)
00037     lock = 0;
00038 #else
00039     pthread_mutexattr_t attr;
00040     pthread_mutexattr_init(&attr);
00041     int ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
00042     printf("pthread_mutexattr_setpshared Returned %d\n", ret);
00043     pthread_mutex_init(&mutex_, &attr);
00044     pthread_mutexattr_destroy(&attr);
00045 #endif
00046     return 0;
00047 }
00048 int Mutex::init(char *mname)
00049 {
00050     if (strlen(mname) > 19 ) return 0;
00051     init();
00052     strcpy(name, mname);
00053     return 0;
00054 
00055 }
00056 
00057 #if defined(sparc) || defined(i686)
00058 int TSL(Lock *lock)
00059 {
00060 /*
00061     if (lock == 0) {
00062        __asm("mov  $1, %eax");
00063        __asm("mov 20(%ebp), %edx");
00064        __asm("xchg %eax, (%edx)");
00065        __asm("test %eax %eax");
00066        __asm("jnz .L1000"); 
00067        return 0;
00068     } else
00069     {
00070         __asm(".L1000:");
00071         return 1;
00072     }
00073 */
00074 /*Was Working in linux
00075         char oldval;
00076         __asm__ __volatile__(
00077                 "xchgb %b0,%1"
00078                 :"=q" (oldval), "=m" (lock)
00079                 :"0" (0) : "memory");
00080 
00081         return oldval > 0;
00082 */
00083 #if defined(i686)
00084     int*  lw;
00085     int   res;
00086     lw = (int*)lock;
00087     if (*lock == 1) return 1;
00088     /* In assembly we use the so-called AT & T syntax where
00089     the order of operands is inverted compared to the ordinary Intel
00090     syntax. The 'l' after the mnemonics denotes a 32-bit operation.
00091     The line after the code tells which values come out of the asm
00092     code, and the second line tells the input to the asm code. */
00093 
00094     /* This assembly compiles only with -O2 option, and not with -g option. Version1
00095     __asm__ __volatile__(
00096         "movl $1, %%eax; xchgl (%%ecx), %%eax" 
00097         : "=eax" (res), "=m" (*lw) 
00098         : "ecx" (lw));
00099     */
00100 
00101      /* This assembly takes lot of time for test/performance/DMLTest. Version2
00102      __asm__ __volatile__(
00103         "movl %1, %0; xchgl %0, %2" 
00104         : "=r" (res), "=r" (lock) 
00105         : "r" (lock));
00106      */
00107     
00108 
00109     // This assembly is Version3. Working fine for now
00110     __asm__ __volatile__(
00111         "xchgl %0, %1 \n\t"
00112         : "=r"(res), "=m"(*lock)
00113         : "0"(1), "m"(*lock)
00114         : "memory"); 
00115 
00116     //fprintf(stderr,"after asm %d ret %d\n", *lock, res);
00117 
00118     return(res);
00119 
00120 #elif defined (sparc)
00121     Lock res;
00122     __asm__ __volatile__("ldstub  [%2], %0    \n"
00123        "=r"(res), "+m"(*lock)
00124        "r"(lock)
00125        "memory");
00126      return (int) res;
00127 #endif
00128 }
00129 #endif
00130 
00131 int Mutex::tryLock(int tryTimes, int waitmsecs)
00132 {
00133     int tries = 0;
00134     int ret = 0;
00135     struct timeval timeout;
00136     timeout.tv_sec = 0;
00137     timeout.tv_usec = waitmsecs;
00138     if (tryTimes == 0 && waitmsecs == 0)
00139     {
00140         timeout.tv_sec = Conf::config.getMutexSecs();
00141         timeout.tv_usec = Conf::config.getMutexUSecs();
00142         tryTimes = Conf::config.getMutexRetries();
00143     }
00144     while (tries < tryTimes)
00145     {
00146 #if defined(sparc) || defined(i686)
00147     if (TSL(&lock) == 0) 
00148     {
00149         return 0; 
00150     }
00151 #else
00152     ret = pthread_mutex_trylock(&mutex_);
00153     if (EBUSY  != ret) return 0;
00154 
00155 #endif
00156         os::select(0, 0, 0, 0, &timeout);
00157         tries++;
00158     }
00159     printError(ErrLockTimeOut, "Unable to get the mutex , tried %d times", tries);
00160     return 1;
00161 }
00162 
00163 
00164 int Mutex::getLock(int procSlot, bool procAccount)
00165 {
00166     int ret=0;
00167 #if defined(sparc) || defined(i686)
00168     ret = tryLock();
00169     //add it to the has_ of the ThreadInfo
00170     if (ret ==0 && procAccount) ProcessManager::addMutex(this, procSlot);
00171 
00172     return ret;
00173 #else
00174     ret = pthread_mutex_lock(&mutex_);
00175 #endif
00176     if (ret == 0) return 0;
00177     else
00178         return 1;
00179 }
00180 
00181 int Mutex::releaseLock(int procSlot, bool procAccount)
00182 {
00183     int ret=0;
00184 #if defined(sparc) || defined(i686)
00185     /*int *lw = &lock;
00186     if (*lw == 0) return 0;
00187     __asm__ __volatile__("movl $0, %%eax; xchgl (%%ecx), %%eax" :
00188                       "=m" (*lw) :
00189                       "ecx" (lw) :
00190                       "eax");   
00191     */
00192     lock = 0;
00193 #else
00194     ret = pthread_mutex_unlock(&mutex_);
00195 #endif
00196     if (ret == 0 && procAccount) 
00197     {
00198         ProcessManager::removeMutex(this, procSlot);
00199         return ret;
00200     }
00201     else
00202         return 1;
00203 }
00204 
00205 int Mutex::destroy()
00206 {
00207 #if defined(sparc) || defined(i686)
00208 #else
00209     return pthread_mutex_destroy(&mutex_);
00210 #endif
00211     return 0;
00212 }

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