code reorg
[csql.git] / src / server / Mutex.cxx
blob4d51b846d79de482128e5b4cfd0bf5f9e9ed50dc
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
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. *
9 * *
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. *
14 * *
15 ***************************************************************************/
16 #include <os.h>
17 #include <Mutex.h>
18 #include <Debug.h>
19 #include <NanoTimer.h>
20 #include <Config.h>
21 #include <Process.h>
22 Mutex::Mutex()
24 #if defined(sparc) || defined(i686)
25 lock =0;
26 #else
27 pthread_mutexattr_t attr;
28 pthread_mutexattr_init(&attr);
29 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
30 pthread_mutex_init(&mutex_, &attr);
31 #endif
34 int Mutex::init()
36 #if defined(sparc) || defined(i686)
37 lock = 0;
38 #else
39 pthread_mutexattr_t attr;
40 pthread_mutexattr_init(&attr);
41 int ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
42 printf("pthread_mutexattr_setpshared Returned %d\n", ret);
43 pthread_mutex_init(&mutex_, &attr);
44 pthread_mutexattr_destroy(&attr);
45 #endif
46 return 0;
48 int Mutex::init(char *mname)
50 if (strlen(mname) > 19 ) return 0;
51 init();
52 strcpy(name, mname);
53 return 0;
57 #if defined(sparc) || defined(i686)
58 int TSL(Lock *lock)
61 if (lock == 0) {
62 __asm("mov $1, %eax");
63 __asm("mov 20(%ebp), %edx");
64 __asm("xchg %eax, (%edx)");
65 __asm("test %eax %eax");
66 __asm("jnz .L1000");
67 return 0;
68 } else
70 __asm(".L1000:");
71 return 1;
74 /*Was Working in linux
75 char oldval;
76 __asm__ __volatile__(
77 "xchgb %b0,%1"
78 :"=q" (oldval), "=m" (lock)
79 :"0" (0) : "memory");
81 return oldval > 0;
83 #if defined(i686)
84 int* lw;
85 int res;
86 lw = (int*)lock;
87 if (*lock == 1) return 1;
88 /* In assembly we use the so-called AT & T syntax where
89 the order of operands is inverted compared to the ordinary Intel
90 syntax. The 'l' after the mnemonics denotes a 32-bit operation.
91 The line after the code tells which values come out of the asm
92 code, and the second line tells the input to the asm code. */
94 /* This assembly compiles only with -O2 option, and not with -g option. Version1
95 __asm__ __volatile__(
96 "movl $1, %%eax; xchgl (%%ecx), %%eax"
97 : "=eax" (res), "=m" (*lw)
98 : "ecx" (lw));
101 /* This assembly takes lot of time for test/performance/DMLTest. Version2
102 __asm__ __volatile__(
103 "movl %1, %0; xchgl %0, %2"
104 : "=r" (res), "=r" (lock)
105 : "r" (lock));
109 // This assembly is Version3. Working fine for now
110 __asm__ __volatile__(
111 "xchgl %0, %1 \n\t"
112 : "=r"(res), "=m"(*lock)
113 : "0"(1), "m"(*lock)
114 : "memory");
116 //fprintf(stderr,"after asm %d ret %d\n", *lock, res);
118 return(res);
120 #elif defined (sparc)
121 Lock res;
122 __asm__ __volatile__("ldstub [%2], %0 \n"
123 "=r"(res), "+m"(*lock)
124 "r"(lock)
125 "memory");
126 return (int) res;
127 #endif
129 #endif
131 int Mutex::tryLock(int tryTimes, int waitmsecs)
133 int tries = 0;
134 int ret = 0;
135 struct timeval timeout;
136 timeout.tv_sec = 0;
137 timeout.tv_usec = waitmsecs;
138 if (tryTimes == 0 && waitmsecs == 0)
140 timeout.tv_sec = Conf::config.getMutexSecs();
141 timeout.tv_usec = Conf::config.getMutexUSecs();
142 tryTimes = Conf::config.getMutexRetries();
144 while (tries < tryTimes)
146 #if defined(sparc) || defined(i686)
147 if (TSL(&lock) == 0)
149 return 0;
151 #else
152 ret = pthread_mutex_trylock(&mutex_);
153 if (EBUSY != ret) return 0;
155 #endif
156 os::select(0, 0, 0, 0, &timeout);
157 tries++;
159 printError(ErrLockTimeOut, "Unable to get the mutex , tried %d times", tries);
160 return 1;
164 int Mutex::getLock(int procSlot, bool procAccount)
166 int ret=0;
167 #if defined(sparc) || defined(i686)
168 ret = tryLock();
169 //add it to the has_ of the ThreadInfo
170 if (ret ==0 && procAccount) ProcessManager::addMutex(this, procSlot);
172 return ret;
173 #else
174 ret = pthread_mutex_lock(&mutex_);
175 #endif
176 if (ret == 0) return 0;
177 else
178 return 1;
181 int Mutex::releaseLock(int procSlot, bool procAccount)
183 int ret=0;
184 #if defined(sparc) || defined(i686)
185 /*int *lw = &lock;
186 if (*lw == 0) return 0;
187 __asm__ __volatile__("movl $0, %%eax; xchgl (%%ecx), %%eax" :
188 "=m" (*lw) :
189 "ecx" (lw) :
190 "eax");
192 lock = 0;
193 #else
194 ret = pthread_mutex_unlock(&mutex_);
195 #endif
196 if (ret == 0 && procAccount)
198 ProcessManager::removeMutex(this, procSlot);
199 return ret;
201 else
202 return 1;
205 int Mutex::destroy()
207 #if defined(sparc) || defined(i686)
208 #else
209 return pthread_mutex_destroy(&mutex_);
210 #endif
211 return 0;