Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
20.temp.buffer.mt.cpp
Go to the documentation of this file.
1
31#include <memory> // for get_temporary_buffer
32#include <utility> // for pair
33
34#include <cassert> // for assert
35#include <cstddef> // for ptrdiff_t
36#include <cstdio> // for printf()
37#include <cstring> // for memset()
38
39#include <rw_driver.h> // for rw_test(), ...
40#include <rw_thread.h> // for rw_thread_create(), ...
41
42
44#ifndef _RWSTD_REENTRANT
45# define MAX_THREADS 0
46#else
47# define MAX_THREADS 32
48#endif
49
50/* extern */ unsigned rw_opt_nthreads = 4 <= MAX_THREADS ? 4 : MAX_THREADS;
51/* extern */ unsigned rw_opt_nloops = 1024 * 1024;
52
53
55struct thr_args
56{
57 unsigned threadno_; // thread ordinal number
58 unsigned ngets_; // number of calls to get_temporary_buffer
59 unsigned nreturns_; // number of calls to return_temporary_buffer
60};
61
62
64template <class T>
65std::pair<T*, std::ptrdiff_t>
66test_get_buffer (thr_args *args, T*, unsigned nobjs)
67{
68 ++args->ngets_;
69
70 std::pair<T*, std::ptrdiff_t> buf =
71 std::get_temporary_buffer<T>(std::ptrdiff_t (nobjs));
72
73// std::printf ("T%u: get %s: { %p, %d } == %u\n",
74// args->threadno_, type_name (T ()),
75// buf.first, buf.second, buf.second * sizeof (T));
76
77 if (buf.first && buf.second) {
78
79 const std::size_t nbytes = buf.second * sizeof (T);
80
81 std::memset (buf.first, args->threadno_ + 1, nbytes);
82
83 *((char*)buf.first + nbytes - 1) = '\0';
84 }
85
86 return buf;
87}
88
89
91template <class T>
92void
93test_return_buffer (thr_args *args, std::pair<T*, std::ptrdiff_t> &buf)
94{
95 ++args->nreturns_;
96
97 std::size_t len = 0;
98
99 if (buf.first) {
100
101 typedef unsigned char UChar;
102
103 for (const UChar *pb = (const UChar*)buf.first; ; ++pb, ++len) {
104
105 if (*pb != (args->threadno_ + 1)) {
106 if (0 == *pb)
107 ++len;
108 break;
109 }
110 }
111 }
112
113// std::printf ("T%u: return %s: { %p, %d } == %u\n",
114// args->threadno_, type_name (T ()),
115// buf.first, buf.second, len);
116
117 assert (len == buf.second * sizeof (T));
118
119 std::return_temporary_buffer<T>(buf.first);
120 buf.first = 0;
121}
122
123
125extern "C" void* thr_func (void *arg)
126{
127 thr_args* const targs = (thr_args*)arg;
128
129 std::printf ("thread %u starting...\n", targs->threadno_);
130
131#ifndef _RWSTD_INT64_T
132
133 typedef char Type64 [8];
134
135#else // if defined (_RWSTD_INT64_T)
136
137 typedef _RWSTD_INT64_T Type64;
138
139#endif // _RWSTD_INT64_T
140
141 std::pair<_RWSTD_INT8_T*, std::ptrdiff_t> buf0;
142 std::pair<_RWSTD_INT16_T*, std::ptrdiff_t> buf1;
143 std::pair<_RWSTD_INT32_T*, std::ptrdiff_t> buf2;
144 std::pair<Type64*, std::ptrdiff_t> buf3;
145
146 for (unsigned i = 0; i != rw_opt_nloops; ++i) {
147
148 const unsigned nelems = (i + targs->threadno_) % 32;
149
150 switch ((i + targs->threadno_) % 8) {
151
152 case 0:
153 buf0 = test_get_buffer (targs, (_RWSTD_INT8_T*)0, nelems);
154 break;
155
156 case 1:
157 buf1 = test_get_buffer (targs, (_RWSTD_INT16_T*)0, nelems);
158 break;
159
160 case 2:
161 buf2 = test_get_buffer (targs, (_RWSTD_INT32_T*)0, nelems);
162 break;
163
164 case 3:
165 buf3 = test_get_buffer (targs, (Type64*)0, nelems);
166 break;
167
168 case 4:
169 test_return_buffer (targs, buf0);
170 break;
171
172 case 5:
173 test_return_buffer (targs, buf2);
174 break;
175
176 case 6:
177 test_return_buffer (targs, buf1);
178 break;
179
180 case 7:
181 test_return_buffer (targs, buf3);
182 break;
183 }
184 }
185
186 // free any buffers that remain allocated
187 if (buf0.first) test_return_buffer (targs, buf0);
188 if (buf1.first) test_return_buffer (targs, buf1);
189 if (buf2.first) test_return_buffer (targs, buf2);
190 if (buf3.first) test_return_buffer (targs, buf3);
191
192 return 0;
193}
194
195
197static int
198run_test (int, char*[])
199{
200 rw_info (0, 0, 0, "std::get_temporary_buffer(ptrdiff_t)");
201 rw_info (0, 0, 0, "std::return_temporary_buffer(ptrdiff_t)");
202
203 if (0 < rw_opt_nthreads) {
204
205 rw_thread_t tid [MAX_THREADS + 1];
206
207 thr_args targs [MAX_THREADS + 1];
208
209 std::memset (targs, 0, sizeof targs);
210
211 for (unsigned i = 0; i != rw_opt_nthreads; ++i) {
212
213 targs [i].threadno_ = i;
214
215 rw_fatal (0 == rw_thread_create (tid + i, 0, thr_func, targs + i),
216 0, 0, "thread_create() failed");
217 }
218
219 for (unsigned i = 0; i != rw_opt_nthreads; ++i) {
220
221 rw_error (0 == rw_thread_join (tid [i], 0), 0, 0,
222 "thread_join() failed");
223 }
224 }
225 else {
226
227 thr_args targs;
228
229 std::memset (&targs, 0, sizeof targs);
230
231 thr_func (&targs);
232
233 }
234
235 return 0;
236}
237
238
240int main (int argc, char *argv[])
241{
242 return rw_test (argc, argv, __FILE__,
243 "lib.temporary.buffer",
244 0 /* no comment */,
245 run_test,
246 "|-nloops#0 " // must be non-negative
247 "|-nthreads#0-*", // must be in specified range
249 int (MAX_THREADS),
251}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define buf
Definition 17.names.cpp:452
#define len
Definition 17.names.cpp:488
unsigned rw_opt_nthreads
unsigned rw_opt_nloops
#define MAX_THREADS
void test_return_buffer(thr_args *args, std::pair< T *, std::ptrdiff_t > &buf)
std::pair< T *, std::ptrdiff_t > test_get_buffer(thr_args *args, T *, unsigned nobjs)
void * thr_func(void *arg)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
#define assert(expr)
Definition _cassert.h:40
_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 *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_fatal(int expr, const char *filename, int line, const char *fmtspec,...)
Definition driver.cpp:1596
_TEST_EXPORT int rw_error(int, const char *, int, const char *,...)
Definition driver.cpp:1613
_TEST_EXPORT int rw_thread_create(rw_thread_t *, rw_thread_attr_t *, rw_thread_proc *, void *)
Definition thread.cpp:379
_TEST_EXPORT int rw_thread_join(rw_thread_t, void **)
Definition thread.cpp:391
unsigned char UChar
Definition collate.cpp:122
unsigned threadno_
unsigned nreturns_
int arg
Definition locale.cpp:2806