void test_length (internT /* dummy */, int line, const std::mbstate_t *pstate, const std::codecvt<internT, char, std::mbstate_t> &cvt, const char *from, std::size_t nchars, int maxi, int result) { static const std::mbstate_t initial_state = std::mbstate_t (); const char* const tname = rw_any_t (internT ()).type_name (); std::mbstate_t state = pstate ? *pstate : initial_state; if (std::size_t (-1) == nchars) nchars = std::strlen (from); const int res = cvt.length (state, from, from + nchars, maxi); rw_assert (res == result, 0, line, "line %d: codecvt<%s, char, mbstate_t>::length(" "state, from=%{*s}, from + %zu, %d) == %d, got %d", __LINE__, tname, sizeof *from, from, nchars, maxi, result, res); rw_assert (!pstate || 0 == std::memcmp (pstate, &state, sizeof state), 0, line, "line %d: codecvt<%s, char, mbstate_t>::length(" "state, from=%{*s}, from + %zu, %d) unexpected state", __LINE__, tname, from, nchars, maxi); }
static int run_test (int, char**) { rw_info (0, 0, 0, "exercising the contents of the <cerrno> header"); for (unsigned i = 0; errors [i]; ++i) { rw_assert (0 == errors [i], 0, 0, "macro %s", errors [i]); } // get the type of errno const char* const errno_type = rw_any_t (errno).type_name (); // 7.5, p2 of C99: the type of errno must be int rw_assert ( 'i' == errno_type [0] && 'n' == errno_type [1] && 't' == errno_type [2] && '\0' == errno_type [3], 0, 0, "the type of errno is int, got %s", errno_type); // 7.5, p3 of C99: errno must be 0 at program startup rw_assert (0 == errno_at_startup, 0, 0, "errno == 0 at program startup, got %d", errno_at_startup); #ifndef EDOM # define EDOM 33 /* Solaris value */ #endif // EDOM // 7.5, p2 of C99: errno must be a modifiable lvalue set_errno_value (errno, int (EDOM)); rw_assert (EDOM == errno, 0, 0, "errno == %d (%{#*m}, got %d (%{#m}) " "(errno not a modifiable lvalue?)", EDOM, EDOM, errno, errno); #ifndef ERANGE # define ERANGE 34 /* Solaris value */ #endif // ERANGE set_errno_value (errno, int (ERANGE)); rw_assert (ERANGE == errno, 0, 0, "errno == %d (%{#*m}, got %d (%{#m}) " "(errno not a modifiable lvalue?)", ERANGE, ERANGE, errno, errno); #ifndef EILSEQ # define EILSEQ 84 /* Solaris value */ #endif // EILSEQ set_errno_value (errno, int (EILSEQ)); rw_assert (EILSEQ == errno, 0, 0, "errno == %d (%{#*m}, got %d (%{#m}) " "(errno not a modifiable lvalue?)", EILSEQ, EILSEQ, errno, errno); return 0; }
void run_test (intT, thr_args_base::tag_t tag) { static const char* const tname = rw_any_t (intT ()).type_name (); if (!rw_enabled (tname)) { rw_note (0, 0, 0, "%s test disabled", tname); return; } #ifdef _RWSTD_REENTRANT static const char* const fun = "__rw_atomic_exchange"; rw_info (0, 0, 0, "__rw::%s (%s&, %2$s): %d iterations in %d threads", fun, tname, rw_opt_nloops, rw_opt_nthreads); rw_thread_t tid [MAX_THREADS]; typedef thr_args<intT> Args; Args::nthreads_ = unsigned (rw_opt_nthreads); Args::type_tag_ = tag; Args::nincr_ = unsigned (rw_opt_nloops); Args::shared_ [0] = intT (1); Args::shared_ [1] = intT (1); _RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid); Args args [sizeof tid / sizeof *tid]; for (unsigned long i = 0; i != Args::nthreads_; ++i) { args [i].threadno_ = i; args [i].niter_ = 0; args [i].nxchg_ = 0; rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i), 0, __LINE__, "thread_create() failed"); } for (unsigned long i = 0; i != Args::nthreads_; ++i) { rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__, "thread_join() failed"); if (args [i].niter_) { // compute the percantage of thread iterations that resulted // in increments of one of the shared variables const unsigned long incrpcnt = (100U * Args::nincr_) / args [i].niter_; printf ("thread %lu performed %lu exchanges in %lu iterations " "(%lu%% increments)\n", args [i].threadno_, args [i].nxchg_, args [i].niter_, incrpcnt); } } // compute the expected result, "skipping" zeros by incrementing // expect twice when it overflows and wraps around to 0 (zero is // used as the lock variable in thread_routine() above) intT expect = intT (1); const unsigned long nincr = (Args::nthreads_ * Args::nincr_) / 2U; for (unsigned long i = 0; i != nincr; ++i) { if (intT () == ++expect) ++expect; } // verify that the final value of the variables shared among all // threads equals the number of increments performed by the threads rw_assert (Args::shared_ [0] == expect, 0, __LINE__, "1. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect)); rw_assert (Args::shared_ [1] == expect, 0, __LINE__, "2. %s (%s&, %2$s); %s == %s failed", fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect)); #else // if !defined (_RWSTD_REENTRANT) _RWSTD_UNUSED (tag); #endif // _RWSTD_REENTRANT }