Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
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
}