File Index
Files and directories
Sign in
FILE

child.h

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/powerpc/ptrace/child.h 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 and
 13 * 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}
~/ Read-only file preview.