// SPDX-License-Identifier: GPL-2.0+
/*
* Helper functions to sync execution between parent and child processes .
*
* Copyright 2018 , Thiago Jung Bauermann , IBM Corporation .
*/
#include <stdio.h>
#include <stdbool.h>
#include <semaphore.h>
/*
* Information in a shared memory location for synchronization between child and
* parent .
*/
struct child_sync {
/* The parent waits on this semaphore. */
sem_t sem_parent;
/* If true, the child should give up as well. */
bool parent_gave_up;
/* The child waits on this semaphore. */
sem_t sem_child;
/* If true, the parent should give up as well. */
bool child_gave_up;
};
#define CHILD_FAIL_IF(x, sync) \
do { \
if (x) { \
fprintf(stderr, \
"[FAIL] Test FAILED on line %d\n" , __LINE__); \
(sync)->child_gave_up = true ; \
prod_parent(sync); \
return 1 ; \
} \
} while (0 )
#define PARENT_FAIL_IF(x, sync) \
do { \
if (x) { \
fprintf(stderr, \
"[FAIL] Test FAILED on line %d\n" , __LINE__); \
(sync)->parent_gave_up = true ; \
prod_child(sync); \
return 1 ; \
} \
} while (0 )
#define PARENT_SKIP_IF_UNSUPPORTED(x, sync, msg) \
do { \
if ((x) == -1 && (errno == ENODEV || errno == EINVAL)) { \
(sync)->parent_gave_up = true ; \
prod_child(sync); \
SKIP_IF_MSG(1 , msg); \
} \
} while (0 )
int init_child_sync(struct child_sync *sync)
{
int ret;
ret = sem_init(&sync->sem_parent, 1 , 0 );
if (ret) {
perror("Semaphore initialization failed" );
return 1 ;
}
ret = sem_init(&sync->sem_child, 1 , 0 );
if (ret) {
perror("Semaphore initialization failed" );
return 1 ;
}
return 0 ;
}
void destroy_child_sync(struct child_sync *sync)
{
sem_destroy(&sync->sem_parent);
sem_destroy(&sync->sem_child);
}
int wait_child(struct child_sync *sync)
{
int ret;
/* Wait until the child prods us. */
ret = sem_wait(&sync->sem_parent);
if (ret) {
perror("Error waiting for child" );
return 1 ;
}
return sync->child_gave_up;
}
int prod_child(struct child_sync *sync)
{
int ret;
/* Unblock the child now. */
ret = sem_post(&sync->sem_child);
if (ret) {
perror("Error prodding child" );
return 1 ;
}
return 0 ;
}
int wait_parent(struct child_sync *sync)
{
int ret;
/* Wait until the parent prods us. */
ret = sem_wait(&sync->sem_child);
if (ret) {
perror("Error waiting for parent" );
return 1 ;
}
return sync->parent_gave_up;
}
int prod_parent(struct child_sync *sync)
{
int ret;
/* Unblock the parent now. */
ret = sem_post(&sync->sem_parent);
if (ret) {
perror("Error prodding parent" );
return 1 ;
}
return 0 ;
}
Messung V0.5 in Prozent C=98 H=94 G=95
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-10-12)
¤
*© Formatika GbR, Deutschland