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