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
semup(int semid)30 static 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
semdown(int semid)41 static 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
mainloop(int semid)52 static 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
run(void)63 static 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
90 static struct tst_test test = {
91 .test_all = run,
92 .forks_child = 1,
93 };
94