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
62 #include <semaphore.h>
69 #define SEMAPHORE_KEY 0x569890
70 #define SHM_KEY 0x568698
79 static sem_t posix_sems[NSEMS];
82 static int state[NSEMS];
84 #define BUFSIZE (1024)
85 static char buf1[BUFSIZE];
86 static char buf2[BUFSIZE];
92 unsigned short *array;
97 static struct timeval tp1,tp2;
99 static void start_timer()
101 gettimeofday(&tp1,NULL);
104 static double end_timer()
106 gettimeofday(&tp2,NULL);
107 return((tp2.tv_sec - tp1.tv_sec) +
108 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
112 /************************************************************************
114 ***********************************************************************/
115 void fcntl_setup(void)
117 fcntl_fd = open("fcntl.locks", O_RDWR | O_CREAT | O_TRUNC, 0600);
118 write(fcntl_fd, state, sizeof(state));
121 void fcntl_close(void)
123 unlink("fcntl.locks");
126 void fcntl_sem_lock(int i)
131 lock.l_type = F_WRLCK;
132 lock.l_whence = SEEK_SET;
133 lock.l_start = i*sizeof(int);
134 lock.l_len = sizeof(int);
139 if (fcntl(fcntl_fd, F_SETLKW, &lock) != 0) {
145 void fcntl_sem_unlock(int i)
150 lock.l_type = F_UNLCK;
151 lock.l_whence = SEEK_SET;
152 lock.l_start = i*sizeof(int);
153 lock.l_len = sizeof(int);
158 if (fcntl(fcntl_fd, F_SETLKW, &lock) != 0) {
166 /************************************************************************
167 USING SYSV IPC SEMAPHORES
168 ***********************************************************************/
176 sem_id = semget(SEMAPHORE_KEY, NSEMS,
177 IPC_CREAT|IPC_EXCL|0600);
179 sem_id = semget(SEMAPHORE_KEY, 0, 0);
181 semctl(sem_id, 0, IPC_RMID, su);
182 sem_id = semget(SEMAPHORE_KEY, NSEMS,
183 IPC_CREAT|IPC_EXCL|0600);
191 for (i=0;i<NSEMS;i++) {
192 semctl(sem_id, i, SETVAL, su);
205 semctl(sem_id, 0, IPC_RMID, su);
209 void ipc_change(int i, int op)
215 if (semop(sem_id, &sb, 1)) {
216 fprintf(stderr,"semop(%d,%d): ", i, op);
222 void ipc_sem_lock(int i)
227 void ipc_sem_unlock(int i)
233 #ifdef HAVE_POSIX_SEM
234 /************************************************************************
235 USING POSIX semaphores
236 ***********************************************************************/
237 void posix_setup(void)
241 for (i=0;i<NSEMS;i++) {
242 if (sem_init(&posix_sems[i], 1, 1) != 0) {
243 fprintf(stderr,"failed to setup semaphore %d\n", i);
249 void posix_close(void)
253 for (i=0;i<NSEMS;i++) {
254 if (sem_close(&posix_sems[i]) != 0) {
255 fprintf(stderr,"failed to close semaphore %d\n", i);
262 void posix_lock(int i)
264 if (sem_wait(&posix_sems[i]) != 0) fprintf(stderr,"failed to get lock %d\n", i);
267 void posix_unlock(int i)
269 if (sem_post(&posix_sems[i]) != 0) fprintf(stderr,"failed to release lock %d\n", i);
274 void test_speed(char *s, void (*lock_fn)(int ), void (*unlock_fn)(int ))
279 for (i=0;i<NSEMS;i++) {
283 for (i=0;i<NPROCS;i++) {
287 srandom(mypid ^ time(NULL));
288 for (j=0;j<NUMOPS;j++) {
289 unsigned sem = random() % NSEMS;
292 memcpy(buf2, buf1, sizeof(buf1));
294 memcpy(buf1, buf2, sizeof(buf1));
307 for (i=0;i<NSEMS;i++) {
311 for (i=0;i<NPROCS;i++)
312 waitpid(pids[i], &status, 0);
314 printf("%g secs\n", end_timer());
317 int main(int argc, char *argv[])
319 srandom(getpid() ^ time(NULL));
321 printf("NPROCS=%d NSEMS=%d NUMOPS=%d\n", NPROCS, NSEMS, NUMOPS);
325 test_speed("fcntl", fcntl_sem_lock, fcntl_sem_unlock);
329 test_speed("ipc", ipc_sem_lock, ipc_sem_unlock);
332 #ifdef HAVE_POSIX_SEM
334 test_speed("posix", posix_lock, posix_unlock);