Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
22.locale.cons.mt.cpp
Go to the documentation of this file.
1
29#include <locale> // for locale
30
31#include <cstring> // for strlen()
32
33#include <rw_locale.h>
34#include <rw_thread.h> // for rw_get_processors (), rw_thread_pool()
35#include <rw_driver.h>
36
37
38// maximum number of threads allowed by the command line interface
39#define MAX_THREADS 32
40
41// default number of threads (will be adjusted to the number
42// of processors/cores later)
44
45// the number of times each thread should iterate (unless specified
46// otherwise on the command line)
47int opt_nloops = 20000;
48
49// tristate flag set in response to the --no-combine/--enable-combine
50// command line option
52
53// default timeout used by each threaded section of this test
54int opt_timeout = 60;
55
56
58// array of locale names to use for testing
59static const char*
61
62// number of locale names in the array
63static std::size_t
65
66
68extern "C" {
69
70static void*
71test_ctors (void*)
72{
73 static const std::locale::category cats[] = {
74 std::locale::all,
75 std::locale::collate,
76 std::locale::ctype,
77 std::locale::messages,
78 std::locale::monetary,
79 std::locale::numeric,
80 std::locale::time,
81 std::locale::none
82 };
83
84 static const std::size_t ncats = sizeof cats / sizeof *cats;
85
86 // the next locale "advanced" in each iteration of the loop
87 std::locale next (locales [0]);
88
89 for (int i = 0; i != opt_nloops; ++i) {
90
92 break;
93
94 // compute an index into the array of locales
95 const std::size_t linx = i % nlocales;
96
97 // create two locale objects from the same name and verify
98 // they are equal
99 const std::locale first (next.name ().c_str ());
100 const std::locale second (next.name ().c_str ());
101
102 RW_ASSERT (first == second);
103
104 // create another locale object as a copy of one of the two
105 // above and verify it's equal to the other
106 const std::locale third (first);
107
108 RW_ASSERT (second == third);
109
110 // compute the next index into the array of locales
111 const std::size_t ninx = (i + 1) % nlocales;
112 const char* const next_name = locales [ninx];
113
114 // create the next locale from a name
115 next = std::locale (next_name);
116
117 if (0 <= opt_combine) {
118 // compute an index into the array of categories
119 const std::size_t cinx = i % ncats;
120 const std::locale::category cat = cats [cinx];
121
122 // create a locale from another object and the name of yet
123 // another locale, combining some (none, one, or all) of their
124 // categories
125 const std::locale combined (first, next_name, cat);
126
127 // verify that the locales were created correctly
128 if ( std::locale::none == cat
129#if defined (_MSC_VER) || defined (__MINGW32__)
130 || std::locale::messages == cat
131#endif
132 || first == next) {
133 RW_ASSERT (combined == first);
134 }
135 else if (std::locale::all == cat)
136 RW_ASSERT (combined == next);
137 else
138 RW_ASSERT (combined != first && combined != next);
139
140 // repeat the step above but with a locale object
141 const std::locale combined_2 (first, next, cat);
142
143 if ( std::locale::none == cat
144#if defined (_MSC_VER) || defined (__MINGW32__)
145 || std::locale::messages == cat
146#endif
147 || first == next) {
148 RW_ASSERT (combined_2 == first);
149 }
150 else if (std::locale::all == cat)
151 RW_ASSERT (combined_2 == next);
152 else
153 RW_ASSERT (combined_2 != first && combined_2 != next);
154 }
155 }
156
157 return 0;
158}
159
160} // extern "C"
161
162
164static int
165run_test (int, char**)
166{
167 // find all installed locales for which setlocale(LC_ALL) succeeds
168 const char* const locale_list =
169 rw_opt_locales ? rw_opt_locales : rw_locales (_RWSTD_LC_ALL);
170
171 const std::size_t maxinx = sizeof locales / sizeof *locales;
172
173 for (const char *name = locale_list; *name; name += std::strlen (name) +1) {
174
175 locales [nlocales++] = name;
176
177 if (nlocales == maxinx)
178 break;
179 }
180
181 int result;
182
183 rw_info (0, 0, 0,
184 "testing std::locale ctors with %d thread%{?}s%{;}, "
185 "%d iteration%{?}s%{;} each, in %zu locales { %{ .*A@} }",
188 nlocales, int (nlocales), "%#s", locales);
189
190 // create and start a pool of threads and wait for them to finish
191 result = rw_thread_pool (0, std::size_t (opt_nthreads), 0,
192 test_ctors, 0, std::size_t (opt_timeout));
193
194 rw_error (result == 0, 0, __LINE__,
195 "rw_thread_pool(0, %d, 0, %{#f}, 0) failed",
197
198 return result;
199}
200
201
203int main (int argc, char *argv[])
204{
205#ifdef _RWSTD_REENTRANT
206
207 // set nthreads to the greater of the number of processors
208 // and 2 (for uniprocessor systems) by default
210 if (opt_nthreads < 2)
211 opt_nthreads = 2;
212
213#endif // _RWSTD_REENTRANT
214
215 return rw_test (argc, argv, __FILE__,
216 "lib.locale.cons",
217 "thread safety", run_test,
218 "|-combine~ "
219 "|-soft-timeout#0 " // must be non-negative
220 "|-nloops#0 " // must be non-negative
221 "|-nthreads#0-* " // must be in [0, MAX_THREADS]
222 "|-locales=", // must be provided
225 &opt_nloops,
226 int (MAX_THREADS),
229}
#define i
Definition 17.names.cpp:126
volatile int result
int opt_timeout
int opt_nloops
int opt_combine
#define MAX_THREADS
int opt_nthreads
const char * locale_list
void test_ctors()
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define main
const unsigned nlocales
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_error(int, const char *, int, const char *,...)
Definition driver.cpp:1613
_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
#define RW_ASSERT(expr)
_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