]> git.saurik.com Git - apple/libc.git/blame - libdarwin/h/stdlib.h
Libc-1272.200.26.tar.gz
[apple/libc.git] / libdarwin / h / stdlib.h
CommitLineData
70ad1dc8
A
1/*
2 * Copyright (c) 2018 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*!
25 * @header
26 * Non-standard, Darwin-specific additions to the stdlib(3) family of APIs.
27 *
28 * The os_malloc() and os_strdup() routines are wrappers to be used for small,
29 * fixed-size allocations, the assumption being that such allocation should
30 * always succeed absent other critical problems. Thus, if the requested size is
31 * is a compile-time constant, the return value is asserted to be non-NULL.
32 * Otherwise, for sizes that are not known at compile-time, the implementations
33 * loop until the allocation succeeds, assuming the failure to be due to
34 * transient resource shortages. The implementation will not loop if the program
35 * has not become multi-threaded, under the assertion that there would be no
36 * point since no other thread could possibly free up resources for the calling
37 * thread to use. Thus, in a single-threaded program, all allocations will
38 * be treated like small, fixed-size allocations and be expected to succeed.
39 *
40 * These wrappers should not be used for large allocations whose bounds cannot
41 * be determined at compile-time. For such allocations, malloc(3), calloc(3), et
42 * al. (with appropriate error handling) are the appropriate interfaces.
43 */
44#ifndef __DARWIN_STDLIB_H
45#define __DARWIN_STDLIB_H
46
47#include <os/base.h>
48#include <os/api.h>
49#include <os/assumes.h>
50#include <dispatch/private.h>
51
52#include <stdlib.h>
53#include <sys/types.h>
54#include <sys/cdefs.h>
55
56__BEGIN_DECLS;
57
58/*!
59 * @function __os_temporary_resource_shortage
60 * A function whose purpose is to appear in stack traces to indicate transient
61 * resource shortage conditions. Do not call.
62 */
63DARWIN_API_AVAILABLE_20170407
64OS_EXPORT OS_NOT_TAIL_CALLED
65void
66__os_temporary_resource_shortage(void);
67
68/*!
69 * @functiongroup
70 * Internal inline definitions.
71 */
72DARWIN_API_AVAILABLE_20170407
73OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1)
74static inline void *
75_os_malloc_loop(size_t size)
76{
77 void *ptr = NULL;
78 while (!(ptr = malloc(size))) {
79 __os_temporary_resource_shortage();
80 }
81 return ptr;
82}
83
84DARWIN_API_AVAILABLE_20170407
85OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1)
86static inline void *
87_os_malloc_known(size_t size)
88{
89 return malloc(size);
90}
91
92DARWIN_API_AVAILABLE_20170407
93OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1, 2)
94static inline void *
95_os_calloc_loop(size_t cnt, size_t size)
96{
97 void *ptr = NULL;
98 while (!(ptr = calloc(cnt, size))) {
99 __os_temporary_resource_shortage();
100 }
101 return ptr;
102}
103
104DARWIN_API_AVAILABLE_20170407
105OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC __alloc_size(1, 2)
106static inline void *
107_os_calloc_known(size_t cnt, size_t size)
108{
109 return calloc(cnt, size);
110}
111
112DARWIN_API_AVAILABLE_20170407
113OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC
114static inline char *
115_os_strdup_loop(const char *str)
116{
117 char *ptr = NULL;
118 while (!(ptr = strdup(str))) {
119 __os_temporary_resource_shortage();
120 }
121 return ptr;
122}
123
124DARWIN_API_AVAILABLE_20170407
125OS_ALWAYS_INLINE OS_WARN_RESULT OS_MALLOC
126static inline char *
127_os_strdup_known(const char *str)
128{
129 return strdup(str);
130}
131
132/*!
133 * @function os_malloc
134 * Wrapper around malloc(3) which guarantees that the allocation succeeds.
135 *
136 * @param __size
137 * The size of the allocation.
138 *
139 * @result
140 * A new object that the caller is responsible for free(3)ing.
141 *
142 * This routine will never return NULL. If the size of the allocation is known
143 * at compile-time, a failure to allocate the object will abort the caller. If
144 * the size is not known at compile-time, the routine will retry until it is
145 * successful.
146 */
147#define os_malloc(__size) ({ \
148 void *ptr = NULL; \
149 size_t _size = (__size); \
150 if (__builtin_constant_p(__size) || !_dispatch_is_multithreaded()) { \
151 ptr = _os_malloc_known(_size); \
152 os_assert_malloc("known-constant allocation", ptr, _size); \
153 } else { \
154 ptr = _os_malloc_loop(_size); \
155 } \
156 (ptr); \
157})
158
159/*!
160 * @function os_calloc
161 * Wrapper around calloc(3) which guarantees that the allocation succeeds.
162 *
163 * @param __cnt
164 * The number of elements to allocate.
165 *
166 * @param __size
167 * The size of each element to allocate.
168 *
169 * @result
170 * A new object that the caller is responsible for free(3)ing.
171 *
172 * This routine will never return NULL. If the size of the allocation is known
173 * at compile-time, a failure to allocate the object will abort the caller. If
174 * the size is not known at compile-time, the routine will retry until it is
175 * successful.
176 */
177#define os_calloc(__cnt, __size) ({ \
178 void *ptr = NULL; \
179 size_t _size = (__size); \
180 size_t _cnt = (__size); \
181 if ((__builtin_constant_p(__cnt) && __builtin_constant_p(__size)) || \
182 !_dispatch_is_multithreaded()) { \
183 ptr = _os_calloc_known(_cnt, _size); \
184 os_assert_malloc("known-constant allocation", ptr, _size); \
185 } else { \
186 ptr = _os_calloc_loop(_cnt, _size); \
187 } \
188 (ptr); \
189})
190
191/*!
192 * @function os_strdup
193 * A wrapper around strdup(3) which guarantees that the string duplication
194 * succeeds.
195 *
196 * @param __str
197 * The string to duplicate.
198 *
199 * @result
200 * A new string that the caller is responsible for free(3)ing.
201 *
202 * This routine will never return NULL. If the given string is a compile-time
203 * constant, a failure to duplicate it will abort the caller. If the string is
204 * not a compile-time constant, the routine will retry until it is successful.
205 *
206 * @discussion
207 * strdup(3) is found in the string(3) API family, but this interface is in the
208 * stdlib.h header because its semantic changes are solely related to the manner
209 * in which memory is allocated.
210 */
211#define os_strdup(__str) ({ \
212 char *ptr = NULL; \
213 const char *_str = (__str); \
214 if (__builtin_constant_p(__str) || !_dispatch_is_multithreaded()) { \
215 ptr = _os_strdup_known(_str); \
216 os_assert_malloc("known-constant allocation", ptr, strlen(_str)); \
217 } else { \
218 ptr = _os_strdup_loop(_str); \
219 } \
220 (ptr); \
221})
222
223/*!
224 * @function os_localtime_file
225 * A routine to generate a time stamp that is suitable for embedding in a file
226 * name.
227 *
228 * @param buff
229 * A pointer to a buffer where the resulting time stamp will be stored.
230 *
231 * @discussion
232 * The resulting time stamp will not include characters which require escaping
233 * in shells, such as spaces. The current implementation format is
234 *
235 * YYYY-MM-DD_HH.MM.SS.us
236 *
237 * e.g.
238 *
239 * 2017-04-24_12.45.15.045609
240 */
241DARWIN_API_AVAILABLE_20170407
242OS_EXPORT
243void
244os_localtime_file(char buff[32]);
245
246/*!
247 * @function os_simple_hash
248 * An implementation of a simple non-cryptographic hashing algorithm.
249 *
250 * @param buff
251 * A pointer to the buffer to hash.
252 *
253 * @param len
254 * The length of the buffer.
255 *
256 * @result
257 * The hashed value of the input.
258 *
259 * @discussion
260 * This routine is meant to be used as a simple way to obtain a value that can
261 * be used to choose a bucket in a simple hash table. Do not attach security
262 * assumptions to the output of this routine. Do not assume thst the computed
263 * hash is stable between hosts, OS versions, or boot sessions.
264 */
265DARWIN_API_AVAILABLE_20170407
266OS_EXPORT OS_NONNULL1
267uint64_t
268os_simple_hash(const void *buff, size_t len);
269
270/*!
271 * @function os_simple_hash_string
272 * An implementation of a simple non-cryptographic hashing algorithm.
273 *
274 * @param string
275 * A pointer to the null-terminated string to hash.
276 *
277 * @result
278 * The hashed value of the input.
279 *
280 * @discussion
281 * This routine is the moral equivalent of a call to
282 *
283 * os_simple_hash(buff, strlen(buff));
284 *
285 * All the same considerations of {@link os_simple_hash} apply.
286 */
287DARWIN_API_AVAILABLE_20170407
288OS_EXPORT OS_NONNULL1
289uint64_t
290os_simple_hash_string(const char *string);
291
292__END_DECLS;
293
294#endif // __DARWIN_STDLIB_H