45#ifndef _RWSTD_NO_SETRLIMIT
48# include <sys/resource.h>
66 typedef unsigned char UChar;
85 rw_info (0, 0, __LINE__,
"std::get_temporary_buffer<%s>(ptrdiff_t)",
92 static const unsigned pa_size = 32;
96 std::pair<T*, std::ptrdiff_t> pa [pa_size];
101 std::pair<T*, std::ptrdiff_t>*
const pa =
102 new std::pair<T*, std::ptrdiff_t>[pa_size];
109 pa [0] = std::get_temporary_buffer<T>(0);
113 std::memset (pa [0].first, ~0
U, pa [0].second *
sizeof (
T));
115 pa [1] = std::get_temporary_buffer<T>(0);
118 std::memset (pa [1].first, ~1U, pa [1].second *
sizeof (
T));
120 rw_assert (pa [0].first != pa [1].first, 0, __LINE__,
121 "get_temporary_buffer<%s>(0).first not unique: "
122 "got %#p and %#p", tname, pa [0].first, pa [1].first);
125 rw_assert (0 == pa [0].second, 0, __LINE__,
126 "get_temporary_buffer<%s>(0) == { 0, 0 }, got "
127 "{ %#p, %td }", tname, pa [0].first, pa [0].second);
130 pa [2] = std::get_temporary_buffer<T>(2);
132 rw_assert (0 != pa [2].first, 0, __LINE__,
133 "get_temporary_buffer<%s>(2).first != 0, got 0", tname);
135 if (0 == pa [2].first)
138 std::memset (pa [2].first, ~2U, pa [2].second *
sizeof (
T));
140 rw_assert (2 <= pa [2].second, 0, __LINE__,
141 "get_temporary_buffer<%s>(2).second >= 2, got %td",
142 tname, pa [2].second);
144 pa [3] = std::get_temporary_buffer<T>(3);
147 rw_assert (0 != pa [3].first, 0, __LINE__,
148 "get_temporary_buffer<%s>(3).first != 0, got 0", tname);
153 rw_assert (3 <= pa [3].second, 0, __LINE__,
154 "get_temporary_buffer<%s>(3).second >= 3, got %td",
155 tname, pa [3].second);
159 pa [3].first [0] =
T ();
160 pa [3].first [1] =
T ();
161 pa [3].first [2] =
T ();
163 std::memset (pa [3].first, ~3U, pa [3].second *
sizeof (
T));
167 for (
unsigned i = 4;
i != pa_size; ++
i) {
169 const std::ptrdiff_t
size =
172 pa [
i] = std::get_temporary_buffer<T>(
size);
175 std::memset (pa [
i].first, ~
i, pa [
i].second *
sizeof (
T));
179 for (
unsigned i = 0;
i < pa_size; ++
i) {
180 for (
unsigned j = 0;
j < pa_size; ++
j) {
182 i !=
j && pa [
i].first
183 && pa [
i].first >= pa [
j].first
184 && pa [
i].first < pa [
j].first + pa [
j].second;
187 "pair { %#p, %td } returned from call %u overlaps "
188 "pair { %#p, %td } returned from call %u",
189 pa [
i].first, pa [
i].second,
i,
190 pa [
j].first, pa [
j].second,
j);
194 i =
j = unsigned (-1);
200 "std::return_temporary_buffer<%s>(%1$s*)", tname);
205 for (
unsigned i = 0;
i < pa_size; ++
i) {
207 std::return_temporary_buffer (pa [
i].first);
209 for (
unsigned j =
i + 1;
j < pa_size; ++
j) {
212 0 ==
compare (pa [
j].first, pa [
j].first + pa [
j].second, ~
j);
215 "return_temporary_buffer<%s>(%#p) corrupted "
216 "a buffer designated by { %#p %td }",
217 tname, pa [
i].first, pa [
j].first, pa [
j].second);
221 i =
j = unsigned (-1);
230 rw_assert (!nblocks && !nbytes, 0, __LINE__,
231 "temporary buffer leaked %d bytes in %d blocks",
248 static char buf [40];
254 "std::get_temporary_buffer<%s>(ptrdiff_t) on arithmetic overflow",
257 std::ptrdiff_t nelems = -1;
259 std::pair<T*, std::ptrdiff_t> pa;
261 pa = std::get_temporary_buffer<T>(nelems);
263 rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__,
264 "std::get_temporary_buffer<%s>(%td) == { 0, 0 }, "
266 tname, nelems, pa.first, pa.second);
268 for (std::size_t
i = 2;
i &&
i <
sizeof (
T);
i <<= 1) {
274 nelems = (_RWSTD_PTRDIFF_MAX /
i) + 1;
276 pa = std::get_temporary_buffer<T>(nelems);
278 rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__,
279 "get_temporary_buffer<%s>(%ld) == { 0, 0 }, "
281 tname, nelems, pa.first, pa.second);
284#ifndef _RWSTD_NO_SETRLIMIT
291 struct rlimit rlim_old;
292 if (getrlimit (RLIMIT_DATA, &rlim_old)) {
294 "getrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu}) "
295 "failed: %{#m}: %m", rlim_old.rlim_max, rlim_old.rlim_cur);
300 struct rlimit rlim_new = rlim_old;
308 const char*
const brk_min = (
char*)_edata;
309 const char*
const brk_cur = (
char*)sbrk (0);
311 rlim_new.rlim_cur = brk_cur - brk_min;
314 rlim_new.rlim_cur = 0;
324 if (setrlimit (RLIMIT_DATA, &rlim_new)) {
326 "setrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu}) "
327 "failed to lower the soft limit: %{#m}: %m",
328 rlim_new.rlim_max, rlim_new.rlim_cur);
332 std::size_t nbytes = rlim_old.rlim_max;
334#if 0 < _RWSTD_TMPBUF_SIZE
346 if (nbytes < _RWSTD_SIZE_MAX)
349 if (nbytes <= std::size_t (_RWSTD_PTRDIFF_MAX))
350 nelems = std::ptrdiff_t (nbytes);
352 nelems = _RWSTD_PTRDIFF_MAX;
354 nelems /=
sizeof (
T);
358 getrlimit (RLIMIT_DATA, &rlim_new);
361 "std::get_temporary_buffer<%s>(%td) in low memory conditions "
362 ": { .rlim_max = %zu, .rlim_cur = %zu }",
363 tname, nelems, rlim_new.rlim_max, rlim_new.rlim_cur);
366 pa = std::get_temporary_buffer<T>(nelems);
371 if (setrlimit (RLIMIT_DATA, &rlim_old)) {
373 "setrlimit(RLIMIT_DATA, { .rlim_max=%zu, .rlim_cur=%zu }) "
374 "failed to restore the soft limit: %{#m}: %m",
375 rlim_old.rlim_max, rlim_old.rlim_cur);
378 rw_assert (0 == pa.first && 0 == pa.second, 0, __LINE__,
379 "get_temporary_buffer<%s>(%td) == { 0, 0 } "
380 "in low memory conditions, got { %#p, %td }",
381 tname, nbytes, pa.first, pa.second);
394template <std::
size_t N>
417#ifdef _RWSTD_LONG_LONG
427#ifndef _RWSTD_NO_LONG_DOUBLE
446#if (!defined (__IBMCPP__) || __IBMCPP__ > 700) \
447 && !defined (__HP_aCC)
450 const std::size_t MAX_SIZE = _RWSTD_PTRDIFF_MAX;
454 const std::size_t MAX_SIZE =
INT_MAX;
468 rw_warn (0, 0, __LINE__,
"get_temp_buffer<large-struct>() "
469 "not tested due to a compiler bug");
478int main (
int argc,
char *argv[])
483 _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG);
486 return rw_test (argc, argv, __FILE__,
487 "lib.temporary.buffer",
void test_get_temporary_buffer(T *dummy, const char *tname)
void(MyStruct::* MemberPointer)()
void test_success(T *, const char *tname)
void(* FunctionPointer)()
void test_failure(T *, const char *tname)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define _RWSTD_TMPBUF_SIZE
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
_TEST_EXPORT _RWSTD_SIZE_T rwt_check_leaks(_RWSTD_SIZE_T *, const rwt_free_store *)
_TEST_EXPORT int rw_sprintf(char *, const char *,...)