1 /* quick test of semaphore speed */
5 Results with the following defines:
10 OSF1 dominion.aquasoft.com.au V4.0 564 alpha (233 MHz)
14 Linux dominion.aquasoft.com.au 2.0.30 (alpha 233 MHz)
18 Linux 2.1.57 on a P120
22 Solaris 2.5 on a Ultra170
26 IRIX 6.4 on a Origin200
30 SunOS 4.1.3 on a 2 CPU sparc 10
34 Solaris 2.5.1 on a 4 CPU SPARCsystem-600
38 Linux 2.1.131 on K6/200
46 AIX 4.2 on 2-proc RS6k with 233MHz processors
50 Linux 2.6.27 on Core-2-duo T61 thinkpad
54 Linux 2.6.27 on Core-2-quad
65 #include <sys/types.h>
71 #include <semaphore.h>
78 #define SEMAPHORE_KEY 0x569890
79 #define SHM_KEY 0x568698
88 static sem_t posix_sems[NSEMS];
91 static int state[NSEMS];
93 #define BUFSIZE (1024)
94 static char buf1[BUFSIZE];
95 static char buf2[BUFSIZE];
100 struct semid_ds *buf;
101 unsigned short *array;
106 static struct timeval tp1,tp2;
108 static void start_timer()
110 gettimeofday(&tp1,NULL);
113 static double end_timer()
115 gettimeofday(&tp2,NULL);
116 return((tp2.tv_sec - tp1.tv_sec) +
117 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
121 /************************************************************************
123 ***********************************************************************/
124 void fcntl_setup(void)
126 fcntl_fd = open("fcntl.locks", O_RDWR | O_CREAT | O_TRUNC, 0600);
127 write(fcntl_fd, state, sizeof(state));
130 void fcntl_close(void)
132 unlink("fcntl.locks");
135 void fcntl_sem_lock(int i)
140 lock.l_type = F_WRLCK;
141 lock.l_whence = SEEK_SET;
142 lock.l_start = i*sizeof(int);
143 lock.l_len = sizeof(int);
148 if (fcntl(fcntl_fd, F_SETLKW, &lock) != 0) {
154 void fcntl_sem_unlock(int i)
159 lock.l_type = F_UNLCK;
160 lock.l_whence = SEEK_SET;
161 lock.l_start = i*sizeof(int);
162 lock.l_len = sizeof(int);
167 if (fcntl(fcntl_fd, F_SETLKW, &lock) != 0) {
175 /************************************************************************
176 USING SYSV IPC SEMAPHORES
177 ***********************************************************************/
185 sem_id = semget(SEMAPHORE_KEY, NSEMS,
186 IPC_CREAT|IPC_EXCL|0600);
188 sem_id = semget(SEMAPHORE_KEY, 0, 0);
190 semctl(sem_id, 0, IPC_RMID, su);
191 sem_id = semget(SEMAPHORE_KEY, NSEMS,
192 IPC_CREAT|IPC_EXCL|0600);
200 for (i=0;i<NSEMS;i++) {
201 semctl(sem_id, i, SETVAL, su);
214 semctl(sem_id, 0, IPC_RMID, su);
218 void ipc_change(int i, int op)
224 if (semop(sem_id, &sb, 1)) {
225 fprintf(stderr,"semop(%d,%d): ", i, op);
231 void ipc_sem_lock(int i)
236 void ipc_sem_unlock(int i)
242 #ifdef HAVE_POSIX_SEM
243 /************************************************************************
244 USING POSIX semaphores
245 ***********************************************************************/
246 void posix_setup(void)
250 for (i=0;i<NSEMS;i++) {
251 if (sem_init(&posix_sems[i], 1, 1) != 0) {
252 fprintf(stderr,"failed to setup semaphore %d\n", i);
258 void posix_close(void)
262 for (i=0;i<NSEMS;i++) {
263 if (sem_close(&posix_sems[i]) != 0) {
264 fprintf(stderr,"failed to close semaphore %d\n", i);
271 void posix_lock(int i)
273 if (sem_wait(&posix_sems[i]) != 0) fprintf(stderr,"failed to get lock %d\n", i);
276 void posix_unlock(int i)
278 if (sem_post(&posix_sems[i]) != 0) fprintf(stderr,"failed to release lock %d\n", i);
283 void test_speed(char *s, void (*lock_fn)(int ), void (*unlock_fn)(int ))
288 for (i=0;i<NSEMS;i++) {
292 for (i=0;i<NPROCS;i++) {
296 srandom(mypid ^ time(NULL));
297 for (j=0;j<NUMOPS;j++) {
298 unsigned sem = random() % NSEMS;
301 memcpy(buf2, buf1, sizeof(buf1));
303 memcpy(buf1, buf2, sizeof(buf1));
316 for (i=0;i<NSEMS;i++) {
320 for (i=0;i<NPROCS;i++)
321 waitpid(pids[i], &status, 0);
323 printf("%g secs\n", end_timer());
326 int main(int argc, char *argv[])
328 srandom(getpid() ^ time(NULL));
330 printf("NPROCS=%d NSEMS=%d NUMOPS=%d\n", NPROCS, NSEMS, NUMOPS);
334 test_speed("fcntl", fcntl_sem_lock, fcntl_sem_unlock);
338 test_speed("ipc", ipc_sem_lock, ipc_sem_unlock);
341 #ifdef HAVE_POSIX_SEM
343 test_speed("posix", posix_lock, posix_unlock);