diff options
Diffstat (limited to 'rubbos/app/httpd-2.0.64/test/time-sem.c')
-rw-r--r-- | rubbos/app/httpd-2.0.64/test/time-sem.c | 588 |
1 files changed, 0 insertions, 588 deletions
diff --git a/rubbos/app/httpd-2.0.64/test/time-sem.c b/rubbos/app/httpd-2.0.64/test/time-sem.c deleted file mode 100644 index bdf09316..00000000 --- a/rubbos/app/httpd-2.0.64/test/time-sem.c +++ /dev/null @@ -1,588 +0,0 @@ -/* Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -time-sem.c has the basics of the semaphores we use in http_main.c. It's -intended for timing differences between various methods on an -architecture. In practice we've found many things affect which semaphore -to be used: - - - NFS filesystems absolutely suck for fcntl() and flock() - - - uslock absolutely sucks on single-processor IRIX boxes, but - absolutely rocks on multi-processor boxes. The converse - is true for fcntl. sysvsem seems a moderate balance. - - - Under Solaris you can't have too many processes use SEM_UNDO, there - might be a tuneable somewhere that increases the limit from 29. - We're not sure what the tunable is, so there's a define - NO_SEM_UNDO which can be used to simulate us trapping/blocking - signals to be able to properly release the semaphore on a clean - child death. You'll also need to define NEED_UNION_SEMUN - under solaris. - -You'll need to define USE_SHMGET_SCOREBOARD if anonymous shared mmap() -doesn't work on your system (i.e. linux). - -argv[1] is the #children, argv[2] is the #iterations per child - -You should run each over many different #children inputs, and choose -#iter such that the program runs for at least a second or so... or even -longer depending on your patience. - -compile with: - -gcc -o time-FCNTL -Wall -O time-sem.c -DUSE_FCNTL_SERIALIZED_ACCEPT -gcc -o time-FLOCK -Wall -O time-sem.c -DUSE_FLOCK_SERIALIZED_ACCEPT -gcc -o time-SYSVSEM -Wall -O time-sem.c -DUSE_SYSVSEM_SERIALIZED_ACCEPT -gcc -o time-SYSVSEM2 -Wall -O time-sem.c -DUSE_SYSVSEM_SERIALIZED_ACCEPT -DNO_SEM_UNDO -gcc -o time-PTHREAD -Wall -O time-sem.c -DUSE_PTHREAD_SERIALIZED_ACCEPT -lpthread -gcc -o time-USLOCK -Wall -O time-sem.c -DUSE_USLOCK_SERIALIZED_ACCEPT - -not all versions work on all systems. -*/ - -#include <errno.h> -#include <sys/time.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include <signal.h> - -#if defined(USE_FCNTL_SERIALIZED_ACCEPT) - -static struct flock lock_it; -static struct flock unlock_it; - -static int fcntl_fd=-1; - -#define accept_mutex_child_init() -#define accept_mutex_cleanup() - -/* - * Initialize mutex lock. - * Must be safe to call this on a restart. - */ -void -accept_mutex_init(void) -{ - - lock_it.l_whence = SEEK_SET; /* from current point */ - lock_it.l_start = 0; /* -"- */ - lock_it.l_len = 0; /* until end of file */ - lock_it.l_type = F_WRLCK; /* set exclusive/write lock */ - lock_it.l_pid = 0; /* pid not actually interesting */ - unlock_it.l_whence = SEEK_SET; /* from current point */ - unlock_it.l_start = 0; /* -"- */ - unlock_it.l_len = 0; /* until end of file */ - unlock_it.l_type = F_UNLCK; /* set exclusive/write lock */ - unlock_it.l_pid = 0; /* pid not actually interesting */ - - printf("opening test-lock-thing in current directory\n"); - fcntl_fd = open("test-lock-thing", O_CREAT | O_WRONLY | O_EXCL, 0644); - if (fcntl_fd == -1) - { - perror ("open"); - fprintf (stderr, "Cannot open lock file: %s\n", "test-lock-thing"); - exit (1); - } - unlink("test-lock-thing"); -} - -void accept_mutex_on(void) -{ - int ret; - - while ((ret = fcntl(fcntl_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR) - continue; - - if (ret < 0) { - perror ("fcntl lock_it"); - exit(1); - } -} - -void accept_mutex_off(void) -{ - if (fcntl (fcntl_fd, F_SETLKW, &unlock_it) < 0) - { - perror ("fcntl unlock_it"); - exit(1); - } -} - -#elif defined(USE_FLOCK_SERIALIZED_ACCEPT) - -#include <sys/file.h> - -static int flock_fd=-1; - -#define FNAME "test-lock-thing" - -/* - * Initialize mutex lock. - * Must be safe to call this on a restart. - */ -void accept_mutex_init(void) -{ - - printf("opening " FNAME " in current directory\n"); - flock_fd = open(FNAME, O_CREAT | O_WRONLY | O_EXCL, 0644); - if (flock_fd == -1) - { - perror ("open"); - fprintf (stderr, "Cannot open lock file: %s\n", "test-lock-thing"); - exit (1); - } -} - -void accept_mutex_child_init(void) -{ - flock_fd = open(FNAME, O_WRONLY, 0600); - if (flock_fd == -1) { - perror("open"); - exit(1); - } -} - -void accept_mutex_cleanup(void) -{ - unlink(FNAME); -} - -void accept_mutex_on(void) -{ - int ret; - - while ((ret = flock(flock_fd, LOCK_EX)) < 0 && errno == EINTR) - continue; - - if (ret < 0) { - perror ("flock(LOCK_EX)"); - exit(1); - } -} - -void accept_mutex_off(void) -{ - if (flock (flock_fd, LOCK_UN) < 0) - { - perror ("flock(LOCK_UN)"); - exit(1); - } -} - -#elif defined (USE_SYSVSEM_SERIALIZED_ACCEPT) - -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/sem.h> - -static int sem_id = -1; -#ifdef NO_SEM_UNDO -static sigset_t accept_block_mask; -static sigset_t accept_previous_mask; -#endif - -#define accept_mutex_child_init() -#define accept_mutex_cleanup() - -void accept_mutex_init(void) -{ -#ifdef NEED_UNION_SEMUN - /* believe it or not, you need to define this under solaris */ - union semun { - int val; - struct semid_ds *buf; - ushort *array; - }; -#endif - - union semun ick; - - sem_id = semget(999, 1, IPC_CREAT | 0666); - if (sem_id < 0) { - perror ("semget"); - exit (1); - } - ick.val = 1; - if (semctl(sem_id, 0, SETVAL, ick) < 0) { - perror ("semctl"); - exit(1); - } -#ifdef NO_SEM_UNDO - sigfillset(&accept_block_mask); - sigdelset(&accept_block_mask, SIGHUP); - sigdelset(&accept_block_mask, SIGTERM); - sigdelset(&accept_block_mask, SIGUSR1); -#endif -} - -void accept_mutex_on() -{ - struct sembuf op; - -#ifdef NO_SEM_UNDO - if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { - perror("sigprocmask(SIG_BLOCK)"); - exit (1); - } - op.sem_flg = 0; -#else - op.sem_flg = SEM_UNDO; -#endif - op.sem_num = 0; - op.sem_op = -1; - if (semop(sem_id, &op, 1) < 0) { - perror ("accept_mutex_on"); - exit (1); - } -} - -void accept_mutex_off() -{ - struct sembuf op; - - op.sem_num = 0; - op.sem_op = 1; -#ifdef NO_SEM_UNDO - op.sem_flg = 0; -#else - op.sem_flg = SEM_UNDO; -#endif - if (semop(sem_id, &op, 1) < 0) { - perror ("accept_mutex_off"); - exit (1); - } -#ifdef NO_SEM_UNDO - if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { - perror("sigprocmask(SIG_SETMASK)"); - exit (1); - } -#endif -} - -#elif defined (USE_PTHREAD_SERIALIZED_ACCEPT) - -/* note: pthread mutexes aren't released on child death, hence the - * signal goop ... in a real implementation we'd do special things - * during hup, term, usr1. - */ - -#include <pthread.h> - -static pthread_mutex_t *mutex; -static sigset_t accept_block_mask; -static sigset_t accept_previous_mask; - -#define accept_mutex_child_init() -#define accept_mutex_cleanup() - -void accept_mutex_init(void) -{ - pthread_mutexattr_t mattr; - int fd; - - fd = open ("/dev/zero", O_RDWR); - if (fd == -1) { - perror ("open(/dev/zero)"); - exit (1); - } - mutex = (pthread_mutex_t *)mmap ((caddr_t)0, sizeof (*mutex), - PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (mutex == (void *)(caddr_t)-1) { - perror ("mmap"); - exit (1); - } - close (fd); - if (pthread_mutexattr_init(&mattr)) { - perror ("pthread_mutexattr_init"); - exit (1); - } - if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED)) { - perror ("pthread_mutexattr_setpshared"); - exit (1); - } - if (pthread_mutex_init(mutex, &mattr)) { - perror ("pthread_mutex_init"); - exit (1); - } - sigfillset(&accept_block_mask); - sigdelset(&accept_block_mask, SIGHUP); - sigdelset(&accept_block_mask, SIGTERM); - sigdelset(&accept_block_mask, SIGUSR1); -} - -void accept_mutex_on() -{ - if (sigprocmask(SIG_BLOCK, &accept_block_mask, &accept_previous_mask)) { - perror("sigprocmask(SIG_BLOCK)"); - exit (1); - } - if (pthread_mutex_lock (mutex)) { - perror ("pthread_mutex_lock"); - exit (1); - } -} - -void accept_mutex_off() -{ - if (pthread_mutex_unlock (mutex)) { - perror ("pthread_mutex_unlock"); - exit (1); - } - if (sigprocmask(SIG_SETMASK, &accept_previous_mask, NULL)) { - perror("sigprocmask(SIG_SETMASK)"); - exit (1); - } -} - -#elif defined (USE_USLOCK_SERIALIZED_ACCEPT) - -#include <ulocks.h> - -static usptr_t *us = NULL; -static ulock_t uslock = NULL; - -#define accept_mutex_child_init() -#define accept_mutex_cleanup() - -void accept_mutex_init(void) -{ - ptrdiff_t old; - /* default is 8 */ -#define CONF_INITUSERS_MAX 15 - if ((old = usconfig(CONF_INITUSERS, CONF_INITUSERS_MAX)) == -1) { - perror("usconfig"); - exit(-1); - } - if ((old = usconfig(CONF_LOCKTYPE, US_NODEBUG)) == -1) { - perror("usconfig"); - exit(-1); - } - if ((old = usconfig(CONF_ARENATYPE, US_SHAREDONLY)) == -1) { - perror("usconfig"); - exit(-1); - } - if ((us = usinit("/dev/zero")) == NULL) { - perror("usinit"); - exit(-1); - } - if ((uslock = usnewlock(us)) == NULL) { - perror("usnewlock"); - exit(-1); - } -} -void accept_mutex_on() -{ - switch(ussetlock(uslock)) { - case 1: - /* got lock */ - break; - case 0: - fprintf(stderr, "didn't get lock\n"); - exit(-1); - case -1: - perror("ussetlock"); - exit(-1); - } -} -void accept_mutex_off() -{ - if (usunsetlock(uslock) == -1) { - perror("usunsetlock"); - exit(-1); - } -} -#endif - - -#ifndef USE_SHMGET_SCOREBOARD -static void *get_shared_mem(apr_size_t size) -{ - void *result; - - /* allocate shared memory for the shared_counter */ - result = (unsigned long *)mmap ((caddr_t)0, size, - PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); - if (result == (void *)(caddr_t)-1) { - perror ("mmap"); - exit (1); - } - return result; -} -#else -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/shm.h> - -static void *get_shared_mem(apr_size_t size) -{ - key_t shmkey = IPC_PRIVATE; - int shmid = -1; - void *result; -#ifdef MOVEBREAK - char *obrk; -#endif - - if ((shmid = shmget(shmkey, size, IPC_CREAT | SHM_R | SHM_W)) == -1) { - perror("shmget"); - exit(1); - } - -#ifdef MOVEBREAK - /* - * Some SysV systems place the shared segment WAY too close - * to the dynamic memory break point (sbrk(0)). This severely - * limits the use of malloc/sbrk in the program since sbrk will - * refuse to move past that point. - * - * To get around this, we move the break point "way up there", - * attach the segment and then move break back down. Ugly - */ - if ((obrk = sbrk(MOVEBREAK)) == (char *) -1) { - perror("sbrk"); - } -#endif - -#define BADSHMAT ((void *)(-1)) - if ((result = shmat(shmid, 0, 0)) == BADSHMAT) { - perror("shmat"); - } - /* - * We must avoid leaving segments in the kernel's - * (small) tables. - */ - if (shmctl(shmid, IPC_RMID, NULL) != 0) { - perror("shmctl(IPC_RMID)"); - } - if (result == BADSHMAT) /* now bailout */ - exit(1); - -#ifdef MOVEBREAK - if (obrk == (char *) -1) - return; /* nothing else to do */ - if (sbrk(-(MOVEBREAK)) == (char *) -1) { - perror("sbrk 2"); - } -#endif - return result; -} -#endif - -#ifdef _POSIX_PRIORITY_SCHEDULING -/* don't ask */ -#define _P __P -#include <sched.h> -#define YIELD sched_yield() -#else -#define YIELD do { struct timeval zero; zero.tv_sec = zero.tv_usec = 0; select(0,0,0,0,&zero); } while(0) -#endif - -void main (int argc, char **argv) -{ - int num_iter; - int num_child; - int i; - struct timeval first; - struct timeval last; - long ms; - int pid; - unsigned long *shared_counter; - - if (argc != 3) { - fprintf (stderr, "Usage: time-sem num-child num iter\n"); - exit (1); - } - - num_child = atoi (argv[1]); - num_iter = atoi (argv[2]); - - /* allocate shared memory for the shared_counter */ - shared_counter = get_shared_mem(sizeof(*shared_counter)); - - /* initialize counter to 0 */ - *shared_counter = 0; - - accept_mutex_init (); - - /* parent grabs mutex until done spawning children */ - accept_mutex_on (); - - for (i = 0; i < num_child; ++i) { - pid = fork(); - if (pid == 0) { - /* child, do our thing */ - accept_mutex_child_init(); - for (i = 0; i < num_iter; ++i) { - unsigned long tmp; - - accept_mutex_on (); - tmp = *shared_counter; - YIELD; - *shared_counter = tmp + 1; - accept_mutex_off (); - } - exit (0); - } else if (pid == -1) { - perror ("fork"); - exit (1); - } - } - - /* a quick test to see that nothing is screwed up */ - if (*shared_counter != 0) { - puts ("WTF! shared_counter != 0 before the children have been started!"); - exit (1); - } - - gettimeofday (&first, NULL); - /* launch children into action */ - accept_mutex_off (); - for (i = 0; i < num_child; ++i) { - if (wait(NULL) == -1) { - perror ("wait"); - } - } - gettimeofday (&last, NULL); - - if (*shared_counter != num_child * num_iter) { - printf ("WTF! shared_counter != num_child * num_iter!\n" - "shared_counter = %lu\nnum_child = %d\nnum_iter=%d\n", - *shared_counter, - num_child, num_iter); - } - - last.tv_sec -= first.tv_sec; - ms = last.tv_usec - first.tv_usec; - if (ms < 0) { - --last.tv_sec; - ms += 1000000; - } - last.tv_usec = ms; - printf ("%8lu.%06lu\n", last.tv_sec, last.tv_usec); - - accept_mutex_cleanup(); - - exit(0); -} - |