brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · df62ff0 Raw
140 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Helper functions to sync execution between parent and child processes.4 *5 * Copyright 2018, Thiago Jung Bauermann, IBM Corporation.6 */7#include <stdio.h>8#include <stdbool.h>9#include <semaphore.h>10 11/*12 * Information in a shared memory location for synchronization between child and13 * parent.14 */15struct child_sync {16	/* The parent waits on this semaphore. */17	sem_t sem_parent;18 19	/* If true, the child should give up as well. */20	bool parent_gave_up;21 22	/* The child waits on this semaphore. */23	sem_t sem_child;24 25	/* If true, the parent should give up as well. */26	bool child_gave_up;27};28 29#define CHILD_FAIL_IF(x, sync)						\30	do {								\31		if (x) {						\32			fprintf(stderr,					\33				"[FAIL] Test FAILED on line %d\n", __LINE__); \34			(sync)->child_gave_up = true;			\35			prod_parent(sync);				\36			return 1;					\37		}							\38	} while (0)39 40#define PARENT_FAIL_IF(x, sync)						\41	do {								\42		if (x) {						\43			fprintf(stderr,					\44				"[FAIL] Test FAILED on line %d\n", __LINE__); \45			(sync)->parent_gave_up = true;			\46			prod_child(sync);				\47			return 1;					\48		}							\49	} while (0)50 51#define PARENT_SKIP_IF_UNSUPPORTED(x, sync, msg)			\52	do {								\53		if ((x) == -1 && (errno == ENODEV || errno == EINVAL)) { \54			(sync)->parent_gave_up = true;			\55			prod_child(sync);				\56			SKIP_IF_MSG(1, msg);				\57		}							\58	} while (0)59 60int init_child_sync(struct child_sync *sync)61{62	int ret;63 64	ret = sem_init(&sync->sem_parent, 1, 0);65	if (ret) {66		perror("Semaphore initialization failed");67		return 1;68	}69 70	ret = sem_init(&sync->sem_child, 1, 0);71	if (ret) {72		perror("Semaphore initialization failed");73		return 1;74	}75 76	return 0;77}78 79void destroy_child_sync(struct child_sync *sync)80{81	sem_destroy(&sync->sem_parent);82	sem_destroy(&sync->sem_child);83}84 85int wait_child(struct child_sync *sync)86{87	int ret;88 89	/* Wait until the child prods us. */90	ret = sem_wait(&sync->sem_parent);91	if (ret) {92		perror("Error waiting for child");93		return 1;94	}95 96	return sync->child_gave_up;97}98 99int prod_child(struct child_sync *sync)100{101	int ret;102 103	/* Unblock the child now. */104	ret = sem_post(&sync->sem_child);105	if (ret) {106		perror("Error prodding child");107		return 1;108	}109 110	return 0;111}112 113int wait_parent(struct child_sync *sync)114{115	int ret;116 117	/* Wait until the parent prods us. */118	ret = sem_wait(&sync->sem_child);119	if (ret) {120		perror("Error waiting for parent");121		return 1;122	}123 124	return sync->parent_gave_up;125}126 127int prod_parent(struct child_sync *sync)128{129	int ret;130 131	/* Unblock the parent now. */132	ret = sem_post(&sync->sem_parent);133	if (ret) {134		perror("Error prodding parent");135		return 1;136	}137 138	return 0;139}140