root/tools/testing/selftests/powerpc/ptrace/child.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. init_child_sync
  2. destroy_child_sync
  3. wait_child
  4. prod_child
  5. wait_parent
  6. prod_parent

   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  */
  15 struct 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)                             \
  52         do {                                                            \
  53                 if ((x) == -1 && (errno == ENODEV || errno == EINVAL)) { \
  54                         (sync)->parent_gave_up = true;                  \
  55                         prod_child(sync);                               \
  56                         SKIP_IF(1);                                     \
  57                 }                                                       \
  58         } while (0)
  59 
  60 int 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 
  79 void destroy_child_sync(struct child_sync *sync)
  80 {
  81         sem_destroy(&sync->sem_parent);
  82         sem_destroy(&sync->sem_child);
  83 }
  84 
  85 int 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 
  99 int 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 
 113 int 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 
 127 int 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 }

/* [<][>][^][v][top][bottom][index][help] */