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