From stdcxx-commits-return-1406-apmail-incubator-stdcxx-commits-archive=incubator.apache.org@incubator.apache.org Mon Jun 18 22:48:23 2007 Return-Path: Delivered-To: apmail-incubator-stdcxx-commits-archive@www.apache.org Received: (qmail 90169 invoked from network); 18 Jun 2007 22:48:22 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 18 Jun 2007 22:48:22 -0000 Received: (qmail 78063 invoked by uid 500); 18 Jun 2007 22:48:26 -0000 Delivered-To: apmail-incubator-stdcxx-commits-archive@incubator.apache.org Received: (qmail 78042 invoked by uid 500); 18 Jun 2007 22:48:26 -0000 Mailing-List: contact stdcxx-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-commits@incubator.apache.org Received: (qmail 78029 invoked by uid 99); 18 Jun 2007 22:48:26 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 18 Jun 2007 15:48:26 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 18 Jun 2007 15:48:22 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id CCECC1A981A; Mon, 18 Jun 2007 15:48:01 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r548519 - /incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp Date: Mon, 18 Jun 2007 22:48:01 -0000 To: stdcxx-commits@incubator.apache.org From: sebor@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070618224801.CCECC1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sebor Date: Mon Jun 18 15:48:01 2007 New Revision: 548519 URL: http://svn.apache.org/viewvc?view=rev&rev=548519 Log: 2007-06-18 Martin Sebor STDCXX-4 * 22.locale.time.put.mt.cpp: Test exercising the thread safety of the required specializations of the std::time_put facet. Added: incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp (with props) Added: incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp?view=auto&rev=548519 ============================================================================== --- incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp (added) +++ incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp Mon Jun 18 15:48:01 2007 @@ -0,0 +1,251 @@ +/************************************************************************ + * + * 22.locale.time.put.mt.cpp + * + * test exercising the thread safety of the time_put facet + * + * $Id$ + * + *************************************************************************** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you 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. + * + * Copyright 2002-2007 Rogue Wave Software. + * + **************************************************************************/ + +#include // for ios +#include // for ostreambuf_iterator +#include // for locale, time_put + +#include // for strlen() +#include // for tm + +#include +#include +#include + + +#define MAX_THREADS 32 +#define MAX_LOOPS 100000 + + +#ifdef _RWSTD_REENTRANT +int rw_opt_nthreads = 4; +#else // if !defined (_RWSTD_REENTRANT) +// in non-threaded builds use just one thread +int rw_opt_nthreads = 1; +#endif // _RWSTD_REENTRANT + +// the number of times each thread should iterate +int rw_opt_nloops = MAX_LOOPS; + +/**************************************************************************/ + +// array of locale names to use for testing +static const char* +locales [MAX_THREADS]; + +// number of locale names in the array +static std::size_t +nlocales; + +/**************************************************************************/ + +extern "C" { + +bool test_char; // exercise time_put +bool test_wchar; // exercise time_put + + +static void* +thread_func (void *arg) +{ + const rw_thread_t* const pthread = (rw_thread_t*)arg; + + // get the 0-based thread number + const std::size_t threadno = std::size_t (pthread->threadno); + + std::tm tmb = std::tm (); + + const char cvtspecs[] = "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%"; + + // dummy streambuf-derived object the doesn't do anything + // but allows ostreambuf_iterator to "think" it can write + // to it + struct NarrowBuf: std::streambuf { + int_type overflow (int_type c) { return c; } + } sb; + +#ifndef _RWSTD_NO_WCHAR_T + + struct WideBuf: std::wstreambuf { + int_type overflow (int_type c) { return c; } + } wsb; + +#endif // _RWSTD_NO_WCHAR_T + + struct Ios: std::ios { + } io; + + int j = 0; + + for (int i = 0; i != rw_opt_nloops; ++i, ++j) { + + // initialize tm with random but valid values + tmb.tm_sec = ++j % 61; + tmb.tm_min = ++j % 60; + tmb.tm_min = ++j % 60; + tmb.tm_wday = ++j % 7; + tmb.tm_mon = ++j % 12; + tmb.tm_year = ++j; + + // generate a "random" conversion specifier from the set + // of valid specifiers recognized by the facet to exercise + // all (or most) code paths + const char cvt = cvtspecs [i % (sizeof cvtspecs - 1)]; + + // save the name of the locale + const char* const locale_name = locales [i % nlocales]; + + // construct a named locale, get a reference to the time_put + // facet from it and use it to format a random time value + // using a random conversion specifier + const std::locale loc (locale_name); + + if (test_char) { + // exercise the narrow char specialization of the facet + + const std::time_put &tp = + std::use_facet >(loc); + + // format a "random" but valid tm value using the random + // format specifier + tp.put (std::ostreambuf_iterator(&sb), + io, ' ', &tmb, cvt); + + } + + // both specializations may be tested at the same time + + if (test_wchar) { + // exercise the wide char specialization of the facet + +#ifndef _RWSTD_NO_WCHAR_T + + const std::time_put &wtp = + std::use_facet >(loc); + + wtp.put (std::ostreambuf_iterator(&wsb), + io, L' ', &tmb, cvt); + +#endif // _RWSTD_NO_WCHAR_T + + } + } + + return 0; +} + +} // extern "C" + +/**************************************************************************/ + +static int +run_test (int, char**) +{ + char* const locale_list = rw_locales (); + + const std::size_t maxinx = sizeof locales / sizeof *locales; + + for (char *name = locale_list; *name; name += std::strlen (name) + 1) { + locales [nlocales++] = name; + + if (nlocales == maxinx) + break; + } + + rw_info (0, 0, 0, + "testing std::time_put with %d thread%{?}s%{;}, " + "%zu iteration%{?}s%{;} each, in locales { %{ .*A@} }", + rw_opt_nthreads, 1 != rw_opt_nthreads, + rw_opt_nloops, 1 != rw_opt_nloops, + int (nlocales), "%#s", locales); + + rw_info (0, 0, 0, "exercising std::time_put"); + + test_char = true; + test_wchar = false; + + // create and start a pool of threads and wait for them to finish + int result = + rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0); + + rw_error (result == 0, 0, __LINE__, + "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", + rw_opt_nthreads, thread_func); + +#ifndef _RWSTD_NO_WCHAR_T + + rw_info (0, 0, 0, "exercising std::time_put"); + + test_char = false; + test_wchar = true; + + // start a pool of threads to exercise wstring thread safety + result = + rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0); + + rw_error (result == 0, 0, __LINE__, + "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", + rw_opt_nthreads, thread_func); + + // exercise bothe the char and the wchar_t specializations + // at the same time + + rw_info (0, 0, 0, + "exercising both std::time_put and std::time_put"); + + test_char = true; + test_wchar = true; + + // start a pool of threads to exercise wstring thread safety + result = + rw_thread_pool (0, std::size_t (rw_opt_nthreads), 0, thread_func, 0); + + rw_error (result == 0, 0, __LINE__, + "rw_thread_pool(0, %d, 0, %{#f}, 0) failed", + rw_opt_nthreads, thread_func); + +#endif // _RWSTD_NO_WCHAR_T + + return result; +} + +/**************************************************************************/ + +int main (int argc, char *argv[]) +{ + return rw_test (argc, argv, __FILE__, + "lib.locale.time.put", + "thread safety", run_test, + "|-nloops#0 " // must be non-negative + "|-nthreads#0-*", // must be in [0, MAX_THREADS] + &rw_opt_nloops, + int (MAX_THREADS), + &rw_opt_nthreads); +} Propchange: incubator/stdcxx/trunk/tests/localization/22.locale.time.put.mt.cpp ------------------------------------------------------------------------------ svn:keywords = Id