b43c2e873ab5d382f16b2ec9e6cb5d7f3287adeb
[sip-router] / test / locking / locking_test.c
1 /* $Id$ */
2
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <ctype.h>
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <fcntl.h>
12
13 #ifdef FLOCK
14 #include <sys/file.h>
15
16 static int lock_fd;
17 #endif
18
19 #ifdef POSIX_SEM
20 #include <semaphore.h>
21
22 static sem_t sem;
23 #endif
24
25 #ifdef PTHREAD_MUTEX
26 #include <pthread.h>
27 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
28 #endif
29
30 #ifdef FAST_LOCK
31 #include "../../fastlock.h"
32 fl_lock_t lock;
33 #endif
34
35 #ifdef SYSV_SEM
36 #include <sys/ipc.h>
37 #include <sys/sem.h>
38
39
40 #if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) || \
41         defined(__FreeBSD__)
42         /* union semun is defined by including <sys/sem.h> */
43 #else
44         /* according to X/OPEN we have to define it ourselves */
45         union semun {
46                 int val;                    /* value for SETVAL */
47                 struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
48                 unsigned short int *array;  /* array for GETALL, SETALL */
49                 struct seminfo *__buf;      /* buffer for IPC_INFO */
50         };
51 #endif
52
53 static int semid=-1;
54
55 #endif
56
57
58 #ifdef NO_LOCK
59         #define LOCK()
60         #define UNLOCK()
61 #elif defined SYSV_SEM
62         #define LOCK() \
63         {\
64                 struct sembuf sop; \
65                 sop.sem_num=0; \
66                 sop.sem_op=-1; /*down*/ \
67                 sop.sem_flg=0 /*SEM_UNDO*/; \
68                 semop(semid, &sop, 1); \
69         }
70
71         #define UNLOCK()        \
72         {\
73                 struct sembuf sop;\
74                 sop.sem_num=0;\
75                 sop.sem_op=1; /*up*/\
76                 sop.sem_flg=0 /*SEM_UNDO*/;\
77                 semop(semid, &sop, 1);\
78         }
79 #elif defined FLOCK
80
81         #define LOCK() \
82                 flock(lock_fd, LOCK_EX)
83         #define  UNLOCK() \
84                 flock(lock_fd, LOCK_UN)
85 #elif defined POSIX_SEM
86         #define LOCK() \
87                 sem_wait(&sem)
88         #define UNLOCK() \
89                 sem_post(&sem);
90 #elif defined PTHREAD_MUTEX
91         #define LOCK() \
92                 pthread_mutex_lock(&mutex)
93         #define UNLOCK() \
94                 pthread_mutex_unlock(&mutex)
95 #elif defined FAST_LOCK
96         #define LOCK() \
97                 get_lock(&lock)
98         #define UNLOCK() \
99                 release_lock(&lock)
100 #endif
101
102
103
104
105 static char *id="$Id$";
106 static char *version="locking_test 0.1-"
107 #ifdef NO_LOCK
108  "nolock"
109 #elif defined SYSV_SEM
110  "sysv_sem"
111 #elif defined FLOCK
112  "flock"
113 #elif defined POSIX_SEM
114  "posix_sem"
115 #elif defined PTHREAD_MUTEX
116  "pthread_mutext"
117 #elif defined FAST_LOCK
118  "fast_lock"
119 #endif
120 ;
121
122 static char* help_msg="\
123 Usage: locking_test -n address [-c count] [-v]\n\
124 Options:\n\
125     -c count      how many times to try lock/unlock \n\
126     -v            increase verbosity level\n\
127     -V            version number\n\
128     -h            this help message\n\
129 ";
130
131
132
133 int main (int argc, char** argv)
134 {
135         int c;
136         int r;
137         char *tmp;
138         
139         int count;
140         int verbose;
141         char *address;
142 #ifdef SYSV_SEM
143         union semun su;
144 #endif
145         
146         /* init */
147         count=0;
148         verbose=0;
149         address=0;
150
151
152
153         opterr=0;
154         while ((c=getopt(argc,argv, "c:vhV"))!=-1){
155                 switch(c){
156                         case 'v':
157                                 verbose++;
158                                 break;
159                         case 'c':
160                                 count=strtol(optarg, &tmp, 10);
161                                 if ((tmp==0)||(*tmp)){
162                                         fprintf(stderr, "bad count: -c %s\n", optarg);
163                                         goto error;
164                                 }
165                                 break;
166                         case 'V':
167                                 printf("version: %s\n", version);
168                                 printf("%s\n",id);
169                                 exit(0);
170                                 break;
171                         case 'h':
172                                 printf("version: %s\n", version);
173                                 printf("%s", help_msg);
174                                 exit(0);
175                                 break;
176                         case '?':
177                                 if (isprint(optopt))
178                                         fprintf(stderr, "Unknown option `-%c´\n", optopt);
179                                 else
180                                         fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
181                                 goto error;
182                         case ':':
183                                 fprintf(stderr, "Option `-%c´ requires an argument.\n",
184                                                 optopt);
185                                 goto error;
186                                 break;
187                         default:
188                                         abort();
189                 }
190         }
191
192         
193         /* check if all the required params are present */
194         if(count==0){
195                 fprintf(stderr, "Missing count (-c number)\n");
196                 exit(-1);
197         }else if(count<0){
198                 fprintf(stderr, "Invalid count (-c %d)\n", count);
199                 exit(-1);
200         }
201
202
203 #ifdef SYSV_SEM
204         /*init*/
205         puts("Initializing SYS V semaphores\n");
206         semid=semget(IPC_PRIVATE,1,0700);
207         if(semid==-1){
208                 fprintf(stderr, "ERROR: could not init sempahore: %s\n",
209                                 strerror(errno));
210                 goto error;
211         }
212         /*set init value to 1 (mutex)*/
213         su.val=1;
214         if (semctl(semid, 0, SETVAL, su)==-1){
215                 fprintf(stderr, "ERROR: could not set initial sempahore value: %s\n",
216                                 strerror(errno));
217                 semctl(semid, 0, IPC_RMID, (union semun)0);
218                 goto error;
219         }
220 #elif defined FLOCK
221         puts("Initializing flock\n");
222         lock_fd=open("/dev/zero", O_RDONLY);
223         if (lock_fd==-1){
224                 fprintf(stderr, "ERROR: could not open file: %s\n", strerror(errno));
225                 goto error;
226         }
227 #elif defined POSIX_SEM
228         puts("Initializing sempahores\n");
229         if (sem_init(&sem, 0, 1)<0){
230                 fprintf(stderr, "ERROR: could not initialize sempahore: %s\n",
231                                 strerror(errno));
232                 goto error;
233         }
234 #elif defined PTHREAD_MUTEX
235         puts("Initializing mutex -already initialized (statically)\n");
236         /*pthread_mutext_init(&mutex, 0 );*/
237 #elif defined FAST_LOCK
238         puts("Initializing fast lock\n");
239         init_lock(lock);
240 #endif
241
242
243         /*  loop */
244         for (r=0; r<count; r++){
245                 LOCK();
246                 if ((verbose>1)&&(r%1000))  putchar('.');
247                 UNLOCK();
248         }
249
250         printf("%d loops\n", count);
251
252 #ifdef SYSV_SEM
253         semctl(semid, 0, IPC_RMID, (union semun)0);
254 #elif defined LIN_SEM
255         sem_destroy(&sem);
256 #endif
257
258         exit(0);
259
260 error:
261         exit(-1);
262 }