• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2020 Linaro Limited. All rights reserved.
4  * Author: Viresh Kumar <viresh.kumar@linaro.org>
5  */
6 
7 #ifndef LAPI_SEMBUF_H__
8 #define LAPI_SEMBUF_H__
9 
10 #include "lapi/posix_types.h"
11 #include <sys/sem.h>
12 #include "tst_timer.h"
13 #include "ipcbuf.h"
14 
15 #ifndef HAVE_STRUCT_SEMID64_DS
16 
17 #if defined(__mips__)
18 #define HAVE_SEMID64_DS
19 /*
20  * The semid64_ds structure for the MIPS architecture.
21  * Note extra padding because this structure is passed back and forth
22  * between kernel and user space.
23  *
24  * Pad space is left for 2 miscellaneous 64-bit values on mips64,
25  * but used for the upper 32 bit of the time values on mips32.
26  */
27 #if __BITS_PER_LONG == 64
28 struct semid64_ds {
29 	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
30 	long		 sem_otime;		/* last semop time */
31 	long		 sem_ctime;		/* last change time */
32 	unsigned long	sem_nsems;		/* no. of semaphores in array */
33 	unsigned long	__unused1;
34 	unsigned long	__unused2;
35 };
36 #else
37 #define HAVE_SEMID64_DS_TIME_HIGH
38 struct semid64_ds {
39 	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
40 	unsigned long   sem_otime;		/* last semop time */
41 	unsigned long   sem_ctime;		/* last change time */
42 	unsigned long	sem_nsems;		/* no. of semaphores in array */
43 	unsigned long	sem_otime_high;
44 	unsigned long	sem_ctime_high;
45 };
46 #endif
47 #endif /* __mips__ */
48 
49 #if defined(__hppa__)
50 #define HAVE_SEMID64_DS
51 /*
52  * The semid64_ds structure for parisc architecture.
53  * Note extra padding because this structure is passed back and forth
54  * between kernel and user space.
55  *
56  * Pad space is left for:
57  * - 2 miscellaneous 32-bit values
58  */
59 struct semid64_ds {
60 	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
61 #if __BITS_PER_LONG == 64
62 	long		sem_otime;		/* last semop time */
63 	long		sem_ctime;		/* last change time */
64 #else
65 #define HAVE_SEMID64_DS_TIME_HIGH
66 	unsigned long	sem_otime_high;
67 	unsigned long	sem_otime;		/* last semop time */
68 	unsigned long	sem_ctime_high;
69 	unsigned long	sem_ctime;		/* last change time */
70 #endif
71 	unsigned long	sem_nsems;		/* no. of semaphores in array */
72 	unsigned long	__unused1;
73 	unsigned long	__unused2;
74 };
75 #endif /* __hppa__ */
76 
77 #if defined(__powerpc__) || defined(__powerpc64__)
78 #define HAVE_SEMID64_DS
79 /*
80  * The semid64_ds structure for PPC architecture.
81  * Note extra padding because this structure is passed back and forth
82  * between kernel and user space.
83  *
84  * Pad space is left for:
85  * - 2 miscellaneous 32/64-bit values
86  */
87 
88 struct semid64_ds {
89 	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
90 #ifndef __powerpc64__
91 #define HAVE_SEMID64_DS_TIME_HIGH
92 	unsigned long	sem_otime_high;
93 	unsigned long	sem_otime;	/* last semop time */
94 	unsigned long	sem_ctime_high;
95 	unsigned long	sem_ctime;	/* last change time */
96 #else
97 	long		sem_otime;	/* last semop time */
98 	long		sem_ctime;	/* last change time */
99 #endif
100 	unsigned long	sem_nsems;	/* no. of semaphores in array */
101 	unsigned long	__unused3;
102 	unsigned long	__unused4;
103 };
104 #endif /* defined(__powerpc__) || defined(__powerpc64__) */
105 
106 #if defined(__sparc__)
107 #define HAVE_SEMID64_DS
108 /*
109  * The semid64_ds structure for sparc architecture.
110  * Note extra padding because this structure is passed back and forth
111  * between kernel and user space.
112  *
113  * Pad space is left for:
114  * - 2 miscellaneous 32-bit values
115  */
116 
117 struct semid64_ds {
118 	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
119 #if defined(__arch64__)
120 	long		sem_otime;		/* last semop time */
121 	long		sem_ctime;		/* last change time */
122 #else
123 #define HAVE_SEMID64_DS_TIME_HIGH
124 	unsigned long	sem_otime_high;
125 	unsigned long	sem_otime;		/* last semop time */
126 	unsigned long	sem_ctime_high;
127 	unsigned long	sem_ctime;		/* last change time */
128 #endif
129 	unsigned long	sem_nsems;		/* no. of semaphores in array */
130 	unsigned long	__unused1;
131 	unsigned long	__unused2;
132 };
133 #endif /* __sparc__ */
134 
135 #if defined(__x86_64__)
136 #define HAVE_SEMID64_DS
137 /*
138  * The semid64_ds structure for x86 architecture.
139  * Note extra padding because this structure is passed back and forth
140  * between kernel and user space.
141  *
142  * Pad space is left for:
143  * - 2 miscellaneous 32-bit values
144  *
145  * x86_64 and x32 incorrectly added padding here, so the structures
146  * are still incompatible with the padding on x86.
147  */
148 struct semid64_ds {
149 	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
150 #ifdef __i386__
151 #define HAVE_SEMID64_DS_TIME_HIGH
152 	unsigned long	sem_otime;	/* last semop time */
153 	unsigned long	sem_otime_high;
154 	unsigned long	sem_ctime;	/* last change time */
155 	unsigned long	sem_ctime_high;
156 #else
157 	__kernel_long_t sem_otime;	/* last semop time */
158 	__kernel_ulong_t __unused1;
159 	__kernel_long_t sem_ctime;	/* last change time */
160 	__kernel_ulong_t __unused2;
161 #endif
162 	__kernel_ulong_t sem_nsems;	/* no. of semaphores in array */
163 	__kernel_ulong_t __unused3;
164 	__kernel_ulong_t __unused4;
165 };
166 #endif /* defined(__x86_64__) */
167 
168 #if defined(__xtensa__)
169 #define HAVE_SEMID64_DS
170 #define HAVE_SEMID64_DS_TIME_HIGH
171 
172 struct semid64_ds {
173 	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
174 #ifdef __XTENSA_EL__
175 	unsigned long	sem_otime;		/* last semop time */
176 	unsigned long	sem_otime_high;
177 	unsigned long	sem_ctime;		/* last change time */
178 	unsigned long	sem_ctime_high;
179 #else
180 	unsigned long	sem_otime_high;
181 	unsigned long	sem_otime;		/* last semop time */
182 	unsigned long	sem_ctime_high;
183 	unsigned long	sem_ctime;		/* last change time */
184 #endif
185 	unsigned long	sem_nsems;		/* no. of semaphores in array */
186 	unsigned long	__unused3;
187 	unsigned long	__unused4;
188 };
189 
190 #endif /* __xtensa__ */
191 
192 #ifndef HAVE_SEMID64_DS
193 /*
194  * The semid64_ds structure for most architectures (though it came
195  * from x86_32 originally). Note extra padding because this structure
196  * is passed back and forth between kernel and user space.
197  *
198  * semid64_ds was originally meant to be architecture specific, but
199  * everyone just ended up making identical copies without specific
200  * optimizations, so we may just as well all use the same one.
201  *
202  * 64 bit architectures use a 64-bit long time field here, while
203  * 32 bit architectures have a pair of unsigned long values.
204  *
205  * On big-endian systems, the padding is in the wrong place for
206  * historic reasons, so user space has to reconstruct a time_t
207  * value using
208  *
209  * user_semid_ds.sem_otime = kernel_semid64_ds.sem_otime +
210  *		((long long)kernel_semid64_ds.sem_otime_high << 32)
211  *
212  * Pad space is left for 2 miscellaneous 32-bit values
213  */
214 struct semid64_ds {
215 	struct ipc64_perm sem_perm;	/* permissions .. see ipc.h */
216 #if __BITS_PER_LONG == 64
217 	long		sem_otime;	/* last semop time */
218 	long		sem_ctime;	/* last change time */
219 #else
220 #define HAVE_SEMID64_DS_TIME_HIGH
221 	unsigned long	sem_otime;	/* last semop time */
222 	unsigned long	sem_otime_high;
223 	unsigned long	sem_ctime;	/* last change time */
224 	unsigned long	sem_ctime_high;
225 #endif
226 	unsigned long	sem_nsems;	/* no. of semaphores in array */
227 	unsigned long	__unused3;
228 	unsigned long	__unused4;
229 };
230 #endif /* semid64_ds */
231 
232 #endif /* HAVE_SEMID64_DS */
233 
234 #endif /* LAPI_SEMBUF_H__ */
235