Пример #1
0
int main(){
    size_t i;
    struct sembuf sem_start_array, sem_start_register, sem_wait_foo_end;

    for (i = 0; i<SYMBOLS_COUNT; i++){
        symbols[i] = (char)i+'a';
    }
    symbols[SYMBOLS_COUNT] = '\0';

    create_semaphores();
    sem_wait_foo_end.sem_num = SEM_FOO_END;
    sem_start_array.sem_num = SEM_ARRAY;
    sem_start_register.sem_num = SEM_REGISTER;
    sem_wait_foo_end.sem_flg = SEM_UNDO;
    sem_start_array.sem_flg = SEM_UNDO;
    sem_start_register.sem_flg = SEM_UNDO;
    sem_wait_foo_end.sem_op = -1;
    sem_start_array.sem_op = 1;
    sem_start_register.sem_op = 1;

    if (pthread_create(&reg_thr, NULL, &invert_register, NULL) != 0)
        print_error("Can't create a thread", 2, errno);
    if (pthread_create(&arr_inv_thr, NULL, &invert_array, NULL) != 0)
        print_error("Can't create a thread", 2, errno);
    signal(SIGTERM, sigterm_handler);
    signal(SIGINT, sigterm_handler);
    while (1){
        if(semop(sem_id, &sem_start_array, 1)<0)
            print_error("Can't set a semaphore", 7, errno);
        if(semop(sem_id, &sem_wait_foo_end, 1)<0)
            print_error("Can't set a semaphore", 7, errno);
        sleep(SLEEP_TIME);
        printf("%s\n", symbols);
        if(semop(sem_id, &sem_start_register, 1)<0)
            print_error("Can't set a semaphore", 7, errno);
        if(semop(sem_id, &sem_wait_foo_end, 1)<0)
            print_error("Can't set a semaphore", 7, errno);
        sleep(SLEEP_TIME);
        printf("%s\n", symbols);
    }
}
Пример #2
0
/*---------------------------------------------------------------------+
|                               main                                   |
| ==================================================================== |
|                                                                      |
| Function:  Main program  (see prolog for more details)               |
|                                                                      |
| Returns:   (0)  Successful completion                                |
|            (-1) Error occurred                                       |
|                                                                      |
+---------------------------------------------------------------------*/
int main(int argc, char **argv)
{
	int fd;			/* Misc file descriptor  */
	int i;			/* Misc loop index */
	int shmem_size;		/* Size (in bytes) of shared memory segment */
	int status;		/* Child processes exit status */
	unsigned char *ptr;	/* Misc pointer */
	unsigned char data = 0;	/* Value written into shared memory segment */
	unsigned char *shmptr;	/* Shared memory segment address */
	unsigned long cksum;	/* Shared memory segment checksum */

	/*
	 * Parse command line arguments and print out program header
	 */
	parse_args(argc, argv);
	printf("%s: IPC Shared Memory TestSuite program\n", *argv);

	/*
	 * Setup the signal handlers (in case user aborts program).
	 *
	 * Create the semaphores to insure exclusive writes to the
	 * shared memory segment.
	 *
	 * Save the parent process id and initialize the array of child
	 * process ids.
	 */
	setup_signal_handlers();
	create_semaphores();

	parent_pid = getpid();
	for (i = 0; i < num_children; i++)
		pid[i] = (pid_t) 0;

	/*
	 * Create a shared memory segment for storing the read count
	 * (number of child processes reading shared data)
	 * After creating the shared memory segment, initialize it.
	 */
	if ((fd = open("/dev/zero", O_RDWR)) < 0)
		sys_error("open failed", __LINE__);
	if ((read_count = (int *)
	     mmap(0, sizeof(int), PROT_READ | PROT_WRITE,
		  MAP_SHARED, fd, 0)) < 0)
		sys_error("mmap failed", __LINE__);
	close(fd);
	*read_count = 0;

	/*
	 * Create a shared memory segment for storing the child
	 * processes checksums by memory mapping /dev/zero.
	 * After creating the shared memory segment, initialize it.
	 */
	if ((fd = open("/dev/zero", O_RDWR)) < 0)
		sys_error("open failed", __LINE__);
	shmem_size = sizeof(unsigned long) * num_children;
	if ((checksum = (unsigned long *)
	     mmap(0, shmem_size, PROT_READ | PROT_WRITE,
		  MAP_SHARED, fd, 0)) < 0)
		sys_error("mmap failed", __LINE__);
	close(fd);

	for (i = 0; i < num_children; i++)
		*(checksum + (sizeof(unsigned long) * i)) = 0;

	/*
	 * Create the "scratch" shared memory segment for storing
	 * a series of values by memory mapping /dev/zero.
	 */
	if ((fd = open("/dev/zero", O_RDWR)) < 0)
		sys_error("open failed", __LINE__);

	printf("\n\tGet shared memory segment (%d bytes)\n", buffer_size);
	if ((shmptr = mmap(0, buffer_size, PROT_READ | PROT_WRITE,
			   MAP_SHARED, fd, 0)) < 0)
		sys_error("mmap failed", __LINE__);
	close(fd);

	/*
	 * Obtain an exclusive "write" lock on the shared memory data
	 * segment -- get lock now to insure the parent process gets
	 * first access to the segment.
	 */
	lock_resource(WRITE);

	/*
	 * Spawn all N child processes.  Each child process will compute
	 * the checksum of the shared memory segment and will store
	 * the results in the other shared memory segment accessible
	 * by the parent.
	 */
	printf("\n\tSpawning %d child processes ... \n", num_children);
	for (i = 0; i < num_children; i++) {

		if ((pid[i] = fork()) == (pid_t) 0) {
			child(i, shmptr);
			exit(0);
		} else if (pid[i] < (pid_t) 0)
			sys_error("fork failed", __LINE__);
	}

	/*
	 * Fill the "scratch" shared memory segment up with data and
	 * compute the segments checksum.  Release "write" lock after
	 * completing so that the child processes may begin to read the
	 * data.
	 */
	printf("\n\tParent: calculate shared memory segment checksum\n");
	cksum = data = 0;

	for (ptr = shmptr; ptr < (shmptr + buffer_size); ptr++) {
		*ptr = (data++) % (UCHAR_MAX + 1);
		cksum += *ptr;
	}
	printf("\t        shared memory checksum %08lx\n", cksum);
	unlock_resource(WRITE);

	/*
	 * Wait for the child processes to compute the checksums and complete.
	 * After the processes complete, check their exit status to insure
	 * that they ran to completion and then verify the corresponding
	 * checksum.
	 */
	for (i = 0; i < num_children; i++) {
		waitpid(pid[i], &status, 0);

		if (!WIFEXITED(status))
			sys_error("child process terminated abnormally",
				  __LINE__);
		if (cksum != *(checksum + (sizeof(unsigned long) * i))) {
			printf("checksum [%d] = %08lx\n", i, checksum[i]);
			error("checksums do not match", __LINE__);
		}
	}
	printf("\n\tParent: children calculated segment successfully\n");

	/*
	 * Program completed successfully, cleanup semaphores and exit.
	 */
	delete_semaphores();
	printf("\nsuccessful!\n");

	return (0);
}
Пример #3
0
Файл: bus.c Проект: uselessd/bus
/**
 * Create a new bus
 * 
 * @param   file      The pathname of the bus, `NULL` to create a random one
 * @param   flags     `BUS_EXCL` (if `file` is not `NULL`) to fail if the file
 *                    already exists, otherwise if the file exists, nothing
 *                    will happen;
 *                    `BUS_INTR` to fail if interrupted
 * @param   out_file  Output parameter for the pathname of the bus
 * @return            0 on success, -1 on error
 */
int
bus_create(const char *file, int flags, char **out_file)
{
	int fd = -1, saved_errno;
	bus_t bus;
	char buf[1 + 2 * (3 * sizeof(ssize_t) + 2)];
	size_t ptr, len;
	ssize_t wrote;
	char *genfile = NULL;
	const char *env;

	if (out_file)
		*out_file = NULL;

	bus.sem_id = -1;
	bus.key_sem = -1;
	bus.key_shm = -1;
	bus.message = NULL;
	bus.first_poll = 0;

	srand((unsigned int)time(NULL) + (unsigned int)rand());

	if (file) {
		fd = open(file, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_MODE);
		if (fd == -1) {
			if ((errno != EEXIST) || (flags & BUS_EXCL))
				return -1;
			goto done;
		}
	} else {
		env = getenv("XDG_RUNTIME_DIR");
		if (!env || !*env)
			env = "/run";
		genfile = malloc((strlen(env) + 6 + 7 + 30) * sizeof(char));
		if (!genfile)
			goto fail;
		if (out_file)
			*out_file = genfile;
		sprintf(genfile, "%s/bus", env);
		t(mkdirs(genfile, 0755));
		sprintf(genfile, "%s/bus/random.", env);
		len = strlen(genfile);
		genfile[len + 30] = '\0';
	retry:
		for (ptr = 0; ptr < 30; ptr++)
			genfile[len + ptr] = randomchar();
		fd = open(genfile, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_MODE);
		if (fd == -1) {
			if (errno == EEXIST)
				goto retry;
			return -1;
		}
	}

	t(create_semaphores(&bus));
	t(create_shared_memory(&bus));

	sprintf(buf, "%zi\n%zi\n", (ssize_t)(bus.key_sem), (ssize_t)(bus.key_shm));
	for (len = strlen(buf), ptr = 0; ptr < len;) {
		wrote = write(fd, buf + ptr, len - ptr);
		if (wrote < 0) {
			if ((errno != EINTR) || (flags & BUS_INTR))
				goto fail;
		} else {
			ptr += (size_t)wrote;
		}
	}
	close(fd);

done:
	if (out_file && !*out_file) {
		len = strlen(file) + 1;
		*out_file = malloc(len * sizeof(char));
		memcpy(*out_file, file, len * sizeof(char));
	} else if (!out_file) {
		free(genfile);
	}
	return 0;

fail:
	saved_errno = errno;
	if (bus.key_sem)
		remove_semaphores(&bus);
	if (bus.key_shm)
		remove_shared_memory(&bus);
	if (fd == -1)
		close(fd);
	if (out_file)
		*out_file = NULL;
	free(genfile);
	unlink(file);
	errno = saved_errno;
	return -1;
}