00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <errno.h>
00033 #include <string.h>
00034 #include <ctype.h>
00035 #include <unistd.h>
00036 #include <sys/types.h>
00037 #include <fcntl.h>
00038
00039 #ifdef FLOCK
00040 #include <sys/file.h>
00041
00042 static int lock_fd;
00043 #endif
00044
00045 #ifdef POSIX_SEM
00046 #include <semaphore.h>
00047
00048 static sem_t sem;
00049 #endif
00050
00051 #ifdef PTHREAD_MUTEX
00052 #include <pthread.h>
00053 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00054 #endif
00055
00056 #ifdef FAST_LOCK
00057 #include "../../fastlock.h"
00058 fl_lock_t lock;
00059 #endif
00060
00061 #ifdef FUTEX
00062 #define USE_FUTEX
00063 #include "../../futexlock.h"
00064 futex_lock_t lock;
00065 #endif
00066
00067 #ifdef SYSV_SEM
00068 #include <sys/ipc.h>
00069 #include <sys/sem.h>
00070
00071
00072 #if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) || \
00073 defined(__FreeBSD__)
00074
00075 #else
00076
00077 union semun {
00078 int val;
00079 struct semid_ds *buf;
00080 unsigned short int *array;
00081 struct seminfo *__buf;
00082 };
00083 #endif
00084
00085 static int semid=-1;
00086
00087 #endif
00088
00089
00090 #ifdef NO_LOCK
00091 #define LOCK()
00092 #define UNLOCK()
00093 #elif defined SYSV_SEM
00094 #define LOCK() \
00095 {\
00096 struct sembuf sop; \
00097 sop.sem_num=0; \
00098 sop.sem_op=-1; \
00099 sop.sem_flg=0 ; \
00100 semop(semid, &sop, 1); \
00101 }
00102
00103 #define UNLOCK() \
00104 {\
00105 struct sembuf sop;\
00106 sop.sem_num=0;\
00107 sop.sem_op=1; \
00108 sop.sem_flg=0 ;\
00109 semop(semid, &sop, 1);\
00110 }
00111 #elif defined FLOCK
00112
00113 #define LOCK() \
00114 flock(lock_fd, LOCK_EX)
00115 #define UNLOCK() \
00116 flock(lock_fd, LOCK_UN)
00117 #elif defined POSIX_SEM
00118 #define LOCK() \
00119 sem_wait(&sem)
00120 #define UNLOCK() \
00121 sem_post(&sem);
00122 #elif defined PTHREAD_MUTEX
00123 #define LOCK() \
00124 pthread_mutex_lock(&mutex)
00125 #define UNLOCK() \
00126 pthread_mutex_unlock(&mutex)
00127 #elif defined FAST_LOCK
00128 #define LOCK() \
00129 get_lock(&lock)
00130 #define UNLOCK() \
00131 release_lock(&lock)
00132 #elif defined FUTEX
00133 #define LOCK() \
00134 futex_get(&lock)
00135 #define UNLOCK() \
00136 futex_release(&lock)
00137 #endif
00138
00139
00140
00141
00142 static char *id="$Id$";
00143 static char *version="locking_test 0.1-"
00144 #ifdef NO_LOCK
00145 "nolock"
00146 #elif defined SYSV_SEM
00147 "sysv_sem"
00148 #elif defined FLOCK
00149 "flock"
00150 #elif defined POSIX_SEM
00151 "posix_sem"
00152 #elif defined PTHREAD_MUTEX
00153 "pthread_mutex"
00154 #elif defined FAST_LOCK
00155 "fast_lock"
00156 #elif defined FUTEX
00157 "futex"
00158 #endif
00159 ;
00160
00161 static char* help_msg="\
00162 Usage: locking_test -n address [-c count] [-v]\n\
00163 Options:\n\
00164 -c count how many times to try lock/unlock \n\
00165 -v increase verbosity level\n\
00166 -V version number\n\
00167 -h this help message\n\
00168 ";
00169
00170
00171
00172 int main (int argc, char** argv)
00173 {
00174 int c;
00175 int r;
00176 char *tmp;
00177
00178 int count;
00179 int verbose;
00180 char *address;
00181 #ifdef SYSV_SEM
00182 union semun su;
00183 #endif
00184
00185
00186 count=0;
00187 verbose=0;
00188 address=0;
00189
00190
00191
00192 opterr=0;
00193 while ((c=getopt(argc,argv, "c:vhV"))!=-1){
00194 switch(c){
00195 case 'v':
00196 verbose++;
00197 break;
00198 case 'c':
00199 count=strtol(optarg, &tmp, 10);
00200 if ((tmp==0)||(*tmp)){
00201 fprintf(stderr, "bad count: -c %s\n", optarg);
00202 goto error;
00203 }
00204 break;
00205 case 'V':
00206 printf("version: %s\n", version);
00207 printf("%s\n",id);
00208 exit(0);
00209 break;
00210 case 'h':
00211 printf("version: %s\n", version);
00212 printf("%s", help_msg);
00213 exit(0);
00214 break;
00215 case '?':
00216 if (isprint(optopt))
00217 fprintf(stderr, "Unknown option `-%c´\n", optopt);
00218 else
00219 fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
00220 goto error;
00221 case ':':
00222 fprintf(stderr, "Option `-%c´ requires an argument.\n",
00223 optopt);
00224 goto error;
00225 break;
00226 default:
00227 abort();
00228 }
00229 }
00230
00231
00232
00233 if(count==0){
00234 fprintf(stderr, "Missing count (-c number)\n");
00235 exit(-1);
00236 }else if(count<0){
00237 fprintf(stderr, "Invalid count (-c %d)\n", count);
00238 exit(-1);
00239 }
00240
00241
00242 #ifdef SYSV_SEM
00243
00244 puts("Initializing SYS V semaphores\n");
00245 semid=semget(IPC_PRIVATE,1,0700);
00246 if(semid==-1){
00247 fprintf(stderr, "ERROR: could not init semaphore: %s\n",
00248 strerror(errno));
00249 goto error;
00250 }
00251
00252 su.val=1;
00253 if (semctl(semid, 0, SETVAL, su)==-1){
00254 fprintf(stderr, "ERROR: could not set initial semaphore value: %s\n",
00255 strerror(errno));
00256 semctl(semid, 0, IPC_RMID, (union semun)0);
00257 goto error;
00258 }
00259 #elif defined FLOCK
00260 puts("Initializing flock\n");
00261 lock_fd=open("/dev/zero", O_RDONLY);
00262 if (lock_fd==-1){
00263 fprintf(stderr, "ERROR: could not open file: %s\n", strerror(errno));
00264 goto error;
00265 }
00266 #elif defined POSIX_SEM
00267 puts("Initializing semaphores\n");
00268 if (sem_init(&sem, 0, 1)<0){
00269 fprintf(stderr, "ERROR: could not initialize semaphore: %s\n",
00270 strerror(errno));
00271 goto error;
00272 }
00273 #elif defined PTHREAD_MUTEX
00274 puts("Initializing mutex -already initialized (statically)\n");
00275
00276 #elif defined FAST_LOCK
00277 puts("Initializing fast lock\n");
00278 init_lock(lock);
00279 #elif defined FUTEX
00280 puts("Initializing futex lock\n");
00281 futex_init(&lock);
00282 #endif
00283
00284
00285
00286 for (r=0; r<count; r++){
00287 LOCK();
00288 if ((verbose>1)&&(r%1000)) putchar('.');
00289 UNLOCK();
00290 }
00291
00292 printf("%d loops\n", count);
00293
00294 #ifdef SYSV_SEM
00295 semctl(semid, 0, IPC_RMID, (union semun)0);
00296 #elif defined LIN_SEM
00297 sem_destroy(&sem);
00298 #endif
00299
00300 exit(0);
00301
00302 error:
00303 exit(-1);
00304 }