1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 * Copyright (C) 2003-2023 Linux Test Project, Inc. 5 * Author: 2001 Paul Larson <plars@us.ibm.com> 6 * Modified: 2001 Manoj Iyer <manjo@ausin.ibm.com> 7 */ 8 9/*\ 10 * [Description] 11 * 12 * Creates a semaphore and two processes. The processes 13 * each go through a loop where they semdown, delay for a 14 * random amount of time, and semup, so they will almost 15 * always be fighting for control of the semaphore. 16 */ 17 18#include <unistd.h> 19#include <stdlib.h> 20#include <stdio.h> 21#include <sys/types.h> 22#include <sys/ipc.h> 23#include "lapi/sem.h" 24#include "tst_test.h" 25#include "tst_safe_sysv_ipc.h" 26 27#define LOOPS 1000 28#define SEED 123 29 30static void semup(int semid) 31{ 32 struct sembuf semops; 33 34 semops.sem_num = 0; 35 semops.sem_op = 1; 36 semops.sem_flg = SEM_UNDO; 37 38 SAFE_SEMOP(semid, &semops, 1); 39} 40 41static void semdown(int semid) 42{ 43 struct sembuf semops; 44 45 semops.sem_num = 0; 46 semops.sem_op = -1; 47 semops.sem_flg = SEM_UNDO; 48 49 SAFE_SEMOP(semid, &semops, 1); 50} 51 52static void mainloop(int semid) 53{ 54 int i; 55 56 for (i = 0; i < LOOPS; i++) { 57 semdown(semid); 58 usleep(1 + ((100.0 * rand()) / RAND_MAX)); 59 semup(semid); 60 } 61} 62 63static void run(void) 64{ 65 int semid; 66 union semun semunion; 67 pid_t pid; 68 69 /* set up the semaphore */ 70 semid = SAFE_SEMGET((key_t) 9142, 1, 0666 | IPC_CREAT); 71 72 semunion.val = 1; 73 74 SAFE_SEMCTL(semid, 0, SETVAL, semunion); 75 76 tst_res(TINFO, "srand seed is %d", SEED); 77 srand(SEED); 78 79 pid = SAFE_FORK(); 80 81 if (pid) { 82 mainloop(semid); 83 tst_reap_children(); 84 TST_EXP_POSITIVE(semctl(semid, 0, IPC_RMID, semunion)); 85 } else { 86 mainloop(semid); 87 } 88} 89 90static struct tst_test test = { 91 .test_all = run, 92 .forks_child = 1, 93}; 94