You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2005/12/17 00:03:28 UTC
svn commit: r357247 - in /incubator/stdcxx/trunk/tests/support:
atomic_add.cpp atomic_xchg.cpp
Author: sebor
Date: Fri Dec 16 15:03:10 2005
New Revision: 357247
URL: http://svn.apache.org/viewcvs?rev=357247&view=rev
Log:
2005-12-16 Martin Sebor <se...@roguewave.com>
STDCXX-4
* atomic_add.cpp: New test exercising the __rw_atomic_preincrement
and __rw_atomic_predecrement overloaded functions.
* atomic_xchg.cpp: New test exercising the __rw_atomic_exchange
overloaded functions.
Added:
incubator/stdcxx/trunk/tests/support/atomic_add.cpp (with props)
incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp (with props)
Added: incubator/stdcxx/trunk/tests/support/atomic_add.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/support/atomic_add.cpp?rev=357247&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/support/atomic_add.cpp (added)
+++ incubator/stdcxx/trunk/tests/support/atomic_add.cpp Fri Dec 16 15:03:10 2005
@@ -0,0 +1,383 @@
+/***************************************************************************
+ *
+ * atomic_add.cpp - test exercising atomic_preincrement() template
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
+ * Software division. Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0. Unless required by
+ * applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License
+ * for the specific language governing permissions and limitations under
+ * the License.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <rw/_mutex.h>
+
+#include <any.h>
+#include <cmdopt.h>
+#include <driver.h>
+#include <rwthread.h>
+
+/**************************************************************************/
+
+struct thr_args_base
+{
+ static enum tag_t {
+ Char, SChar, UChar,
+ Short, UShort, Int, UInt, Long, ULong,
+ LLong, ULLong
+ } type_tag_;
+};
+
+thr_args_base::tag_t thr_args_base::type_tag_;
+
+template <class intT>
+struct thr_args: thr_args_base
+{
+ unsigned threadno_; // thread ordinal number
+ static int inc_; // increment, decrement, or both
+ static unsigned nincr_; // number of increments
+ static intT *shared_; // shared variables
+ static unsigned nthreads_; // number of threads
+
+ static intT* get_array ();
+};
+
+template <class intT>
+int thr_args<intT>::inc_;
+
+template <class intT>
+unsigned thr_args<intT>::nincr_;
+
+template <class intT>
+intT* thr_args<intT>::shared_ = thr_args<intT>::get_array ();
+
+template <class intT>
+unsigned thr_args<intT>::nthreads_;
+
+// working around compiler bugs that prevent us from defining
+// a static array data member of a class template (PR #30009)
+template <class intT>
+intT* thr_args<intT>::get_array ()
+{
+ static intT array [2];
+ return array;
+}
+
+/**************************************************************************/
+
+
+template <class T>
+T preincrement (T &x)
+{
+#ifndef _RWSTD_REENTRANT
+
+ return ++x;
+
+#else // if defined (_RWSTD_REENTRANT)
+
+ return _RW::__rw_atomic_preincrement (x, false);
+
+#endif // _RWSTD_REENTRANT
+}
+
+
+template <class T>
+T predecrement (T &x)
+{
+#ifndef _RWSTD_REENTRANT
+
+ return --x;
+
+#else // if defined (_RWSTD_REENTRANT)
+
+ return _RW::__rw_atomic_predecrement (x, false);
+
+#endif // _RWSTD_REENTRANT
+}
+
+/**************************************************************************/
+
+
+template <class intT>
+void* thread_routine (thr_args<intT> *args)
+{
+ printf ("thread %u starting to %screment\n",
+ args->threadno_,
+ args->inc_ < 0 ? "de"
+ : args->inc_ > 0 ? "in"
+ : "decrement and in");
+
+ if (args->inc_ > 0) {
+
+ // exercise atomic_preincrement() in a tight loop
+
+ for (unsigned i = 0; i != args->nincr_; ++i) {
+ preincrement (args->shared_ [0]);
+ preincrement (args->shared_ [1]);
+ }
+ }
+ else if (args->inc_ < 0) {
+
+ // exercise atomic_predecrement() in a tight loop
+
+ for (unsigned i = 0; i != args->nincr_; ++i) {
+ predecrement (args->shared_ [0]);
+ predecrement (args->shared_ [1]);
+ }
+ }
+ else {
+
+ // exercise both atomic_preincrement() and atomic_predecrement()
+
+ for (unsigned i = 0; i != args->nincr_; ++i) {
+ preincrement (args->shared_ [0]);
+ predecrement (args->shared_ [0]);
+ preincrement (args->shared_ [1]);
+ predecrement (args->shared_ [1]);
+ }
+ }
+
+ return 0;
+}
+
+/**************************************************************************/
+
+extern "C" void* thread_routine (void *arg)
+{
+ thr_args_base* const args = (thr_args_base*)arg;
+
+ switch (args->type_tag_) {
+
+ case thr_args_base::Char:
+ return thread_routine ((thr_args<char>*)(arg));
+ case thr_args_base::SChar:
+ return thread_routine ((thr_args<signed char>*)(arg));
+ case thr_args_base::UChar:
+ return thread_routine ((thr_args<unsigned char>*)(arg));
+
+ case thr_args_base::Short:
+ return thread_routine ((thr_args<short>*)(arg));
+ case thr_args_base::UShort:
+ return thread_routine ((thr_args<unsigned short>*)(arg));
+
+ case thr_args_base::Int:
+ return thread_routine ((thr_args<int>*)(arg));
+ case thr_args_base::UInt:
+ return thread_routine ((thr_args<unsigned int>*)(arg));
+
+ case thr_args_base::Long:
+ return thread_routine ((thr_args<long>*)(arg));
+ case thr_args_base::ULong:
+ return thread_routine ((thr_args<unsigned long>*)(arg));
+
+#ifdef _RWSTD_LONG_LONG
+
+ case thr_args_base::LLong:
+ return thread_routine ((thr_args<_RWSTD_LONG_LONG>*)(arg));
+ case thr_args_base::ULLong:
+ return thread_routine ((thr_args<unsigned _RWSTD_LONG_LONG>*)(arg));
+
+#endif // _RWSTD_LONG_LONG
+
+ };
+
+ return 0;
+}
+
+/**************************************************************************/
+
+/* extern */ int rw_opt_nloops = 1024 * 1024;
+/* extern */ int rw_opt_nthreads = 4;
+
+#define MAX_THREADS 32
+
+
+template <class intT>
+void run_test (intT, thr_args_base::tag_t tag, int inc)
+{
+ static const char* const tname = rw_any_t (intT ()).type_name ();
+
+ static const char* const fun =
+ inc < 0 ? "__rw_atomic_predecrement"
+ : inc > 0 ? ":__rw_atomic_preincrement"
+ : "__rw_atomic_pre{in,de}crement";
+
+ if (!rw_enabled (tname)) {
+ rw_note (0, 0, 0, "%s test disabled", tname);
+ return;
+ }
+
+#if defined (_RWSTD_REENTRANT)
+
+ rw_info (0, 0, 0, "__rw::%s (%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_ = rw_opt_nthreads;
+ Args::type_tag_ = tag;
+ Args::inc_ = inc;
+ Args::nincr_ = unsigned (rw_opt_nloops);
+ Args::shared_ [0] = intT ();
+ Args::shared_ [1] = intT ();
+
+ _RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid);
+
+ Args args [sizeof tid / sizeof *tid];
+
+ memset (args, 0, sizeof args);
+
+ for (unsigned i = 0; i != Args::nthreads_; ++i) {
+
+ args [i].threadno_ = i;
+
+ rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i),
+ 0, __LINE__, "thread_create() failed");
+ }
+
+ for (unsigned i = 0; i != Args::nthreads_; ++i) {
+
+ rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__,
+ "thread_join() failed");
+ }
+
+ // compute the expected result
+ intT expect = intT ();
+
+ if (inc < 0) {
+ for (unsigned i = 0; i != Args::nthreads_ * Args::nincr_; ++i)
+ --expect;
+ }
+ else if (inc > 0) {
+ for (unsigned i = 0; i != Args::nthreads_ * Args::nincr_; ++i)
+ ++expect;
+ }
+
+ // verify that the final value of the variable shared among all
+ // threads equals the number of increments or decrements performed
+ // by all threads
+ rw_assert (Args::shared_ [0] == expect, 0, __LINE__,
+ "1. %s (%s&); %s == %s failed",
+ fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect));
+
+ rw_assert (Args::shared_ [1] == expect, 0, __LINE__,
+ "2. %s (%s&); %s == %s failed",
+ fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect));
+
+#else // if !defined (_RWSTD_REENTRANT)
+
+ _RWSTD_UNUSED (t);
+ _RWSTD_UNUSED (tag);
+ _RWSTD_UNUSED (inc);
+
+#endif // _RWSTD_REENTRANT
+}
+
+/**************************************************************************/
+
+static int
+run_test (int, char**)
+{
+ // check that the number of threads is valid
+ rw_fatal (-1 < rw_opt_nthreads && rw_opt_nthreads < MAX_THREADS, 0, 0,
+ "number of threads must be in the range [0, %d), got %d",
+ MAX_THREADS, rw_opt_nthreads);
+
+ // check that the number of loops is non-negative
+ rw_fatal (-1 < rw_opt_nloops, 0, 0,
+ "number of loops must be non-negative, got %d",
+ rw_opt_nloops);
+
+ // exercise atomic subtract
+ run_test ((char)0, thr_args_base::Char, -1);
+ run_test ((signed char)0, thr_args_base::SChar, -1);
+ run_test ((unsigned char)0, thr_args_base::UChar, -1);
+
+ run_test ((short)0, thr_args_base::Short, -1);
+ run_test ((unsigned short)0, thr_args_base::UShort, -1);
+
+ run_test ((int)0, thr_args_base::Int, -1);
+ run_test ((unsigned int)0, thr_args_base::UInt, -1);
+
+ run_test ((long)0, thr_args_base::Long, -1);
+ run_test ((unsigned long)0, thr_args_base::ULong, -1);
+
+#ifdef _RWSTD_LONG_LONG
+
+ run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong, -1);
+ run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong, -1);
+
+#endif // _RWSTD_LONG_LONG
+
+ // exercise atomic add
+ run_test ((char)0, thr_args_base::Char, +1);
+ run_test ((signed char)0, thr_args_base::SChar, +1);
+ run_test ((unsigned char)0, thr_args_base::UChar, +1);
+
+ run_test ((short)0, thr_args_base::Short, +1);
+ run_test ((unsigned short)0, thr_args_base::UShort, +1);
+
+ run_test ((int)0, thr_args_base::Int, +1);
+ run_test ((unsigned int)0, thr_args_base::UInt, +1);
+
+ run_test ((long)0, thr_args_base::Long, +1);
+ run_test ((unsigned long)0, thr_args_base::ULong, +1);
+
+#ifdef _RWSTD_LONG_LONG
+
+ run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong, +1);
+ run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong, +1);
+
+#endif // _RWSTD_LONG_LONG
+
+
+ // exercise both atomic add and subtract
+ run_test ((char)0, thr_args_base::Char, 0);
+ run_test ((signed char)0, thr_args_base::SChar, 0);
+ run_test ((unsigned char)0, thr_args_base::UChar, 0);
+
+ run_test ((short)0, thr_args_base::Short, 0);
+ run_test ((unsigned short)0, thr_args_base::UShort, 0);
+
+ run_test ((int)0, thr_args_base::Int, 0);
+ run_test ((unsigned int)0, thr_args_base::UInt, 0);
+
+ run_test ((long)0, thr_args_base::Long, 0);
+ run_test ((unsigned long)0, thr_args_base::ULong, 0);
+
+#ifdef _RWSTD_LONG_LONG
+
+ run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong, 0);
+ run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong, 0);
+
+#endif // _RWSTD_LONG_LONG
+
+ return 0;
+}
+
+/**************************************************************************/
+
+int main (int argc, char *argv[])
+{
+ return rw_test (argc, argv, __FILE__,
+ 0 /* no clause */,
+ 0 /* no comment */, run_test,
+ "|-nloops# "
+ "|-nthreads#",
+ &rw_opt_nloops,
+ &rw_opt_nthreads);
+}
Propchange: incubator/stdcxx/trunk/tests/support/atomic_add.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/support/atomic_add.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Added: incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp?rev=357247&view=auto
==============================================================================
--- incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp (added)
+++ incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp Fri Dec 16 15:03:10 2005
@@ -0,0 +1,365 @@
+/***************************************************************************
+ *
+ * atomic_xchg.cpp - test exercising atomic_exchange() template
+ *
+ * $Id$
+ *
+ ***************************************************************************
+ *
+ * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
+ * Software division. Licensed under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0. Unless required by
+ * applicable law or agreed to in writing, software distributed under
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ * CONDITIONS OF ANY KIND, either express or implied. See the License
+ * for the specific language governing permissions and limitations under
+ * the License.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <rw/_mutex.h>
+
+#include <any.h>
+#include <cmdopt.h>
+#include <driver.h>
+#include <rwthread.h>
+
+/**************************************************************************/
+
+struct thr_args_base
+{
+ static enum tag_t {
+ Char, SChar, UChar,
+ Short, UShort, Int, UInt, Long, ULong,
+ LLong, ULLong
+ } type_tag_;
+
+ unsigned long threadno_; // thread ordinal number
+ unsigned long niter_; // number of iterations
+ unsigned long nxchg_; // number of exchanges
+};
+
+thr_args_base::tag_t thr_args_base::type_tag_;
+
+template <class intT>
+struct thr_args: thr_args_base
+{
+ static unsigned long nincr_; // number of increments
+ static intT *shared_; // shared variables
+ static unsigned long nthreads_; // number of threads
+
+ static intT* get_array ();
+};
+
+template <class intT>
+unsigned long thr_args<intT>::nincr_;
+
+template <class intT>
+intT* thr_args<intT>::shared_ = thr_args<intT>::get_array ();
+
+template <class intT>
+unsigned long thr_args<intT>::nthreads_;
+
+// working around compiler bugs that prevent us from defining
+// a static array data member of a class template (PR #30009)
+template <class intT>
+/* static */ intT* thr_args<intT>::get_array ()
+{
+ static intT array [2];
+ return array;
+}
+
+/**************************************************************************/
+
+template <class intT>
+intT exchange (intT &x, intT y)
+{
+#ifndef _RWSTD_REENTRANT
+
+ intT save (x);
+
+ x = y;
+
+ return save;
+
+#else // if defined (_RWSTD_REENTRANT)
+
+ return _RW::__rw_atomic_exchange (x, y, false);
+
+#endif // _RWSTD_REENTRANT
+}
+
+/**************************************************************************/
+
+template <class intT>
+void* thread_routine (thr_args<intT> *args)
+{
+ // each thread operates on one of two shared values to exercise
+ // problems due to operating on adjacent bytes or half-words
+ const unsigned long inx = args->threadno_ % 2;
+
+ static volatile int failed;
+
+ // exercise atomic_exchange() in a tight loop
+
+ // perform the requested number increments, or until the
+ // shared `failed' variable is set to a non-zero value
+
+ for (unsigned long i = 0; i != args->nincr_ && !failed; ++i) {
+
+ for (unsigned long j = 0; !failed; ++j) {
+
+ // increment the number of iterations of this thread
+ ++args->niter_;
+
+ // use intT() as a special "lock" value
+ const intT old = exchange (args->shared_ [inx], intT ());
+
+ // increment the number of exchanges performed by this thread
+ ++args->nxchg_;
+
+ if (intT () != old) {
+
+ // shared variable was not locked by any other thread
+
+ // increment the value of the shared variable, taking
+ // care to avoid the special "lock" value of intT()
+ intT newval = intT (old + 1);
+
+ if (intT () == newval)
+ ++newval;
+
+ const intT lock = exchange (args->shared_ [inx], newval);
+
+ // increment the number of exchanges
+ ++args->nxchg_;
+
+ // the returned value must be the special "lock" value
+ if (intT () == lock)
+ break;
+
+ // fail by setting the shared failed variable (to
+ // prevent deadlock) if the returned value is not
+ // the special "lock" value
+
+ printf ("*** line %d: error: thread %lu failed "
+ "at increment %lu after %lu iterations\n",
+ __LINE__, args->threadno_, i, args->niter_);
+ failed = 1;
+ return 0;
+ }
+
+ if (100UL * args->nincr_ == j) {
+
+ // fail by setting the shared failed variable (to
+ // prevent deadlock) if the number of failed attempts
+ // to lock the shared variable reaches the requested
+ // number of increments * 100 (an arbitrary number)
+
+ printf ("*** line %d: error thread %lu \"timed out\" after "
+ "%lu increments and %lu iterations\n",
+ __LINE__, args->threadno_, i, args->niter_);
+ failed = 1;
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**************************************************************************/
+
+extern "C" void* thread_routine (void *arg)
+{
+ thr_args_base* const args = (thr_args_base*)arg;
+
+ printf ("thread %lu starting\n", args->threadno_);
+
+ switch (args->type_tag_) {
+
+ case thr_args_base::Char:
+ return thread_routine ((thr_args<char>*)(arg));
+ case thr_args_base::SChar:
+ return thread_routine ((thr_args<signed char>*)(arg));
+ case thr_args_base::UChar:
+ return thread_routine ((thr_args<unsigned char>*)(arg));
+
+ case thr_args_base::Short:
+ return thread_routine ((thr_args<short>*)(arg));
+ case thr_args_base::UShort:
+ return thread_routine ((thr_args<unsigned short>*)(arg));
+
+ case thr_args_base::Int:
+ return thread_routine ((thr_args<int>*)(arg));
+ case thr_args_base::UInt:
+ return thread_routine ((thr_args<unsigned int>*)(arg));
+
+ case thr_args_base::Long:
+ return thread_routine ((thr_args<long>*)(arg));
+ case thr_args_base::ULong:
+ return thread_routine ((thr_args<unsigned long>*)(arg));
+
+#ifdef _RWSTD_LONG_LONG
+
+ case thr_args_base::LLong:
+ return thread_routine ((thr_args<_RWSTD_LONG_LONG>*)(arg));
+ case thr_args_base::ULLong:
+ return thread_routine ((thr_args<unsigned _RWSTD_LONG_LONG>*)(arg));
+
+#endif // _RWSTD_LONG_LONG
+
+ };
+
+ return 0;
+}
+
+/**************************************************************************/
+
+/* extern */ int rw_opt_nloops = 1024 * 1024;
+/* extern */ int rw_opt_nthreads = 4;
+
+#define MAX_THREADS 32
+
+
+template <class intT>
+void run_test (intT, thr_args_base::tag_t tag)
+{
+ static const char* const tname = rw_any_t (intT ()).type_name ();
+ static const char* const fun = "__rw_atomic_exchange";
+
+ if (!rw_enabled (tname)) {
+ rw_note (0, 0, 0, "%s test disabled", tname);
+ return;
+ }
+
+#ifdef _RWSTD_REENTRANT
+
+ 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
+ intT expect = intT (1);
+
+ for (unsigned long i = 0; i != (Args::nthreads_ * Args::nincr_) / 2U; ++i) {
+ if (!++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 (t);
+ _RWSTD_UNUSED (tag);
+
+#endif // _RWSTD_REENTRANT
+}
+
+/**************************************************************************/
+
+static int
+run_test (int, char**)
+{
+ // check that the number of threads is valid
+ rw_fatal (-1 < rw_opt_nthreads && rw_opt_nthreads < MAX_THREADS, 0, 0,
+ "number of threads must be in the range [0, %d), got %d",
+ MAX_THREADS, rw_opt_nthreads);
+
+ // check that the number of loops is non-negative
+ rw_fatal (-1 < rw_opt_nloops, 0, 0,
+ "number of loops must be non-negative, got %d",
+ rw_opt_nloops);
+
+ // exercise atomic exchange
+ run_test ((char)0, thr_args_base::Char);
+ run_test ((signed char)0, thr_args_base::SChar);
+ run_test ((unsigned char)0, thr_args_base::UChar);
+
+ run_test ((short)0, thr_args_base::Short);
+ run_test ((unsigned short)0, thr_args_base::UShort);
+
+ run_test ((int)0, thr_args_base::Int);
+ run_test ((unsigned int)0, thr_args_base::UInt);
+
+ run_test ((long)0, thr_args_base::Long);
+ run_test ((unsigned long)0, thr_args_base::ULong);
+
+#ifdef _RWSTD_LONG_LONG
+
+ run_test ((_RWSTD_LONG_LONG)0, thr_args_base::LLong);
+ run_test ((unsigned _RWSTD_LONG_LONG)0, thr_args_base::ULLong);
+
+#endif // _RWSTD_LONG_LONG
+
+ return 0;
+
+}
+
+/**************************************************************************/
+
+int main (int argc, char *argv[])
+{
+ return rw_test (argc, argv, __FILE__,
+ 0 /* no clause */,
+ 0 /* no comment */, run_test,
+ "|-nloops# "
+ "|-nthreads#",
+ &rw_opt_nloops,
+ &rw_opt_nthreads);
+}
Propchange: incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/tests/support/atomic_xchg.cpp
------------------------------------------------------------------------------
svn:keywords = Id