• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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