Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
22.locale.statics.mt.cpp
Go to the documentation of this file.
1
31#include <locale> // for locale
32#include <cstring> // for strlen()
33
34#include <rw_locale.h> // for rw_locales()
35#include <rw_thread.h> // for rw_get_processors(), rw_thread_pool()
36#include <rw_driver.h> // for rw_test()
37
38
39// maximum number of threads allowed by the command line interface
40#define MAX_THREADS 16
41
42// default number of threads (will be adjusted to the number
43// of processors/cores later)
45
46// the number of times each thread should iterate (unless specified
47// otherwise on the command line)
48int opt_nloops = 20000;
49
52
53// default timeout used by each threaded section of this test
54int opt_timeout = 60;
55
56
58// array of locale objects to use for testing
59static std::locale
61
62// number of locale names in the array
63static std::size_t
65
66
68extern "C" {
69
70static void*
71test_classic (void*)
72{
73 static volatile int nthreads;
74
75 // cast nthreads to int& (see STDCXX-792)
76 // casting should be removed after fixing STDCXX-794
77 _RWSTD_ATOMIC_PREINCREMENT (_RWSTD_CONST_CAST (int&, nthreads), false);
78
79 // spin until all threads have been created in order to icrease
80 // the odds that at least two of them will hit the tested function
81 // (and the lazy one-time initialization done by it) at the same
82 // time
83 while (nthreads < opt_nthreads);
84
85 const std::locale classic (std::locale::classic ());
86
87 _RWSTD_UNUSED (classic);
88
89 return 0;
90}
91
92
93static void*
94test_global (void*)
95{
96 for (std::size_t i = 0; i != std::size_t (opt_nloops); ++i) {
97
99 break;
100
101 const std::size_t inx = i % nlocales;
102
103 const std::locale last (std::locale::global (locales [inx]));
104
106
107 // FIXME: verify the consistency of the returned locale
108 // by making sure that it matches the locale passed to
109 // global() made by the last call to the function by
110 // the last thread
111 }
112
113 return 0;
114}
115
116} // extern "C"
117
118
120static int
121run_test (int, char**)
122{
123 int result = 0;
124
125 if (rw_note (0 <= opt_classic, 0, __LINE__,
126 "std::locale::classic() test disabled")) {
127
128 rw_info (0, 0, 0,
129 "testing std::locale::classic() with %d thread%{?}s%{;}",
131
132 // create and start a pool of threads and wait for them to finish
133 result = rw_thread_pool (0, std::size_t (opt_nthreads), 0,
134 test_classic, 0, std::size_t (opt_timeout));
135 }
136
137 if (rw_note (0 <= opt_global, 0, __LINE__,
138 "std::locale::global(const std::locale&) test disabled")) {
139
140
141 // find all installed locales for which setlocale(LC_ALL) succeeds
142 const char* const locale_list =
143 rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL);
144
145 const std::size_t maxinx = sizeof locales / sizeof *locales;
146
147 const char* locale_names [MAX_THREADS];
148
149 for (const char *name = locale_list;
150 *name;
151 name += std::strlen (name) + 1) {
152
153 locale_names [nlocales] = name;
154 locales [nlocales++] = std::locale (name);
155
156 if (nlocales == maxinx)
157 break;
158 }
159
160 rw_info (0, 0, 0,
161 "testing std::locale::global(const std::locale&) with "
162 "%d thread%{?}s%{;}, %d iteration%{?}s%{;} each, in "
163 "%zu locales { %{ .*A@} }",
166 nlocales, int (nlocales), "%#s", locale_names);
167
168 // create and start a pool of threads and wait for them to finish
169 result = rw_thread_pool (0, std::size_t (opt_nthreads), 0,
170 test_global, 0, std::size_t (opt_timeout));
171 }
172
173 return result;
174}
175
176
178int main (int argc, char *argv[])
179{
180#ifdef _RWSTD_REENTRANT
181
182 // set nthreads to the greater of the number of processors
183 // and 2 (for uniprocessor systems) by default
185 if (opt_nthreads < 2)
186 opt_nthreads = 2;
187
188#endif // _RWSTD_REENTRANT
189
190 return rw_test (argc, argv, __FILE__,
191 "lib.locale.statics",
192 "thread safety",
193 run_test,
194 "|-classic~ "
195 "|-global~ "
196 "|-soft-timeout#0 " // must be non-negative
197 "|-nloops#0 " // arg must be non-negative
198 "|-nthreads#0-* " // arg must be in [0, MAX_THREADS]
199 "|-locales= ", // argument must be provided
201 &opt_global,
203 &opt_nloops,
204 int (MAX_THREADS),
207}
#define i
Definition 17.names.cpp:126
#define last
Definition 17.names.cpp:487
#define inx
Definition 17.names.cpp:484
volatile int result
const char * locale_list
int opt_timeout
int opt_nloops
int opt_classic
#define MAX_THREADS
int opt_global
int opt_nthreads
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
const unsigned nlocales
#define _RWSTD_ATOMIC_PREINCREMENT(x, ignore)
Definition _defs.h:699
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
const struct @19 locales[]
const char * name
Definition codecvt1.cpp:72
_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_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_opt_setlocales(int, char *[])
Definition locale.cpp:866
_TEST_EXPORT const char *const & rw_opt_locales
Definition locale.cpp:862
_TEST_EXPORT char * rw_locales(int=_UNUSED_CAT, const char *=0, bool=true)
Definition locale.cpp:368
_TEST_EXPORT int rw_thread_pool(rw_thread_t *, _RWSTD_SIZE_T, rw_thread_attr_t *, rw_thread_proc *, void **, _RWSTD_SIZE_T=0)
_TEST_EXPORT int rw_get_cpus()
Definition thread.cpp:402
_TEST_EXPORT int rw_thread_pool_timeout_expired()
Definition thread.cpp:65