Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/thread/test/test_tss.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 18 years ago

added boost

File size: 4.3 KB
Line 
1// Copyright (C) 2001-2003
2// William E. Kempf
3//
4// Permission to use, copy, modify, distribute and sell this software
5// and its documentation for any purpose is hereby granted without fee,
6// provided that the above copyright notice appear in all copies and
7// that both that copyright notice and this permission notice appear
8// in supporting documentation.  William E. Kempf makes no representations
9// about the suitability of this software for any purpose.
10// It is provided "as is" without express or implied warranty.
11
12#include <boost/thread/detail/config.hpp>
13
14#include <boost/thread/tss.hpp>
15#include <boost/thread/mutex.hpp>
16#include <boost/thread/thread.hpp>
17
18#include <boost/test/unit_test.hpp>
19
20#include <libs/thread/test/util.inl>
21
22#include <iostream>
23
24#if defined(BOOST_HAS_WINTHREADS)
25    #define WIN32_LEAN_AND_MEAN
26    #include <windows.h>    
27#endif
28
29boost::mutex check_mutex;
30boost::mutex tss_mutex;
31int tss_instances = 0;
32int tss_total = 0;
33
34struct tss_value_t
35{
36    tss_value_t()
37    {
38        boost::mutex::scoped_lock lock(tss_mutex);
39        ++tss_instances;
40        ++tss_total;
41        value = 0;
42    }
43    ~tss_value_t()
44    {
45        boost::mutex::scoped_lock lock(tss_mutex);
46        --tss_instances;
47    }
48    int value;
49};
50
51boost::thread_specific_ptr<tss_value_t> tss_value;
52
53void test_tss_thread()
54{
55    tss_value.reset(new tss_value_t());
56    for (int i=0; i<1000; ++i)
57    {
58        int& n = tss_value->value;
59        // Don't call BOOST_CHECK_EQUAL directly, as it doesn't appear to
60        // be thread safe. Must evaluate further.
61        if (n != i)
62        {
63            boost::mutex::scoped_lock lock(check_mutex);
64            BOOST_CHECK_EQUAL(n, i);
65        }
66        ++n;
67    }
68}
69
70#if defined(BOOST_HAS_WINTHREADS)
71    typedef HANDLE native_thread_t;
72
73    DWORD WINAPI test_tss_thread_native(LPVOID lpParameter)
74    {
75        test_tss_thread();
76        return 0;
77    }
78
79    native_thread_t create_native_thread(void)
80    {
81        return CreateThread(
82            0, //security attributes (0 = not inheritable)
83            0, //stack size (0 = default)
84            &test_tss_thread_native, //function to execute
85            0, //parameter to pass to function
86            0, //creation flags (0 = run immediately)
87            0  //thread id (0 = thread id not returned)
88            );
89    }
90
91    void join_native_thread(native_thread_t thread)
92    {
93        DWORD res = WaitForSingleObject(thread, INFINITE);
94        BOOST_CHECK(res == WAIT_OBJECT_0);
95
96        res = CloseHandle(thread);
97        BOOST_CHECK(SUCCEEDED(res));
98    }
99#endif
100
101void do_test_tss()
102{
103    tss_instances = 0;
104    tss_total = 0;
105
106    const int NUMTHREADS=5;
107    boost::thread_group threads;
108    for (int i=0; i<NUMTHREADS; ++i)
109        threads.create_thread(&test_tss_thread);
110    threads.join_all();
111
112    std::cout
113        << "tss_instances = " << tss_instances
114        << "; tss_total = " << tss_total
115        << "\n";
116    std::cout.flush();
117
118    BOOST_CHECK_EQUAL(tss_instances, 0);
119    BOOST_CHECK_EQUAL(tss_total, 5);
120
121    #if defined(BOOST_HAS_WINTHREADS)
122        tss_instances = 0;
123        tss_total = 0;
124
125        native_thread_t thread1 = create_native_thread();
126        BOOST_CHECK(thread1 != 0);
127
128        native_thread_t thread2 = create_native_thread();
129        BOOST_CHECK(thread2 != 0);
130
131        native_thread_t thread3 = create_native_thread();
132        BOOST_CHECK(thread3 != 0);
133
134        native_thread_t thread4 = create_native_thread();
135        BOOST_CHECK(thread3 != 0);
136
137        native_thread_t thread5 = create_native_thread();
138        BOOST_CHECK(thread3 != 0);
139
140        join_native_thread(thread5);
141        join_native_thread(thread4);
142        join_native_thread(thread3);
143        join_native_thread(thread2);
144        join_native_thread(thread1);
145
146        std::cout
147            << "tss_instances = " << tss_instances
148            << "; tss_total = " << tss_total
149            << "\n";
150        std::cout.flush();
151
152        BOOST_CHECK_EQUAL(tss_instances, 0);
153        BOOST_CHECK_EQUAL(tss_total, 5);
154    #endif
155}
156
157void test_tss()
158{
159    timed_test(&do_test_tss, 2);
160}
161
162boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
163{
164    boost::unit_test_framework::test_suite* test =
165        BOOST_TEST_SUITE("Boost.Threads: tss test suite");
166
167    test->add(BOOST_TEST_CASE(test_tss));
168
169    return test;
170}
Note: See TracBrowser for help on using the repository browser.