~ubuntu-branches/ubuntu/trusty/mongodb/trusty-proposed

« back to all changes in this revision

Viewing changes to dbtests/threadedtests.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Antonin Kral
  • Date: 2010-01-29 19:48:45 UTC
  • Revision ID: james.westby@ubuntu.com-20100129194845-8wbmkf626fwcavc9
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// threadedtests.cpp - Tests for threaded code
 
2
//
 
3
 
 
4
/**
 
5
 *    Copyright (C) 2008 10gen Inc.
 
6
 *
 
7
 *    This program is free software: you can redistribute it and/or  modify
 
8
 *    it under the terms of the GNU Affero General Public License, version 3,
 
9
 *    as published by the Free Software Foundation.
 
10
 *
 
11
 *    This program is distributed in the hope that it will be useful,
 
12
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *    GNU Affero General Public License for more details.
 
15
 *
 
16
 *    You should have received a copy of the GNU Affero General Public License
 
17
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include "stdafx.h"
 
21
#include "../util/mvar.h"
 
22
#include "../util/thread_pool.h"
 
23
#include <boost/thread.hpp>
 
24
#include <boost/bind.hpp>
 
25
 
 
26
#include "dbtests.h"
 
27
 
 
28
namespace ThreadedTests {
 
29
 
 
30
    template <int nthreads_param=10>
 
31
    class ThreadedTest{
 
32
        public:
 
33
            virtual void setup() {} //optional
 
34
            virtual void subthread() = 0;
 
35
            virtual void validate() = 0;
 
36
 
 
37
            static const int nthreads = nthreads_param;
 
38
 
 
39
            void run(){
 
40
                setup();
 
41
 
 
42
                launch_subthreads(nthreads);
 
43
 
 
44
                validate();
 
45
            }
 
46
 
 
47
            virtual ~ThreadedTest() {}; // not necessary, but makes compilers happy
 
48
 
 
49
        private:
 
50
            void launch_subthreads(int remaining){
 
51
                if (!remaining) return;
 
52
 
 
53
                boost::thread athread(boost::bind(&ThreadedTest::subthread, this));
 
54
 
 
55
                launch_subthreads(remaining - 1);
 
56
 
 
57
                athread.join();
 
58
            }
 
59
    };
 
60
 
 
61
    // Tested with up to 30k threads
 
62
    class IsWrappingIntAtomic : public ThreadedTest<> {
 
63
        static const int iterations = 1000000;
 
64
        WrappingInt target;
 
65
 
 
66
        void subthread(){
 
67
            for(int i=0; i < iterations; i++){
 
68
                //target.x++; // verified to fail with this version
 
69
                target.atomicIncrement();
 
70
            }
 
71
        }
 
72
        void validate(){
 
73
            ASSERT_EQUALS(target.x , unsigned(nthreads * iterations));
 
74
        }
 
75
    };
 
76
 
 
77
    class MVarTest : public ThreadedTest<> {
 
78
        static const int iterations = 10000;
 
79
        MVar<int> target;
 
80
 
 
81
        public:
 
82
        MVarTest() : target(0) {}
 
83
        void subthread(){
 
84
            for(int i=0; i < iterations; i++){
 
85
                int val = target.take();
 
86
#if BOOST_VERSION >= 103500
 
87
                //increase chances of catching failure
 
88
                boost::this_thread::yield();
 
89
#endif
 
90
                target.put(val+1);
 
91
            }
 
92
        }
 
93
        void validate(){
 
94
            ASSERT_EQUALS(target.take() , nthreads * iterations);
 
95
        }
 
96
    };
 
97
 
 
98
    class ThreadPoolTest{
 
99
        static const int iterations = 10000;
 
100
        static const int nThreads = 8;
 
101
 
 
102
        WrappingInt counter;
 
103
        void increment(int n){
 
104
            for (int i=0; i<n; i++){
 
105
                counter.atomicIncrement();
 
106
            }
 
107
        }
 
108
 
 
109
        public:
 
110
        void run(){
 
111
            ThreadPool tp(nThreads);
 
112
 
 
113
            for (int i=0; i < iterations; i++){
 
114
                tp.schedule(&WrappingInt::atomicIncrement, &counter);
 
115
                tp.schedule(&ThreadPoolTest::increment, this, 2);
 
116
            }
 
117
            
 
118
            tp.join();
 
119
 
 
120
            ASSERT(counter == (unsigned)(iterations * 3));
 
121
        }
 
122
    };
 
123
 
 
124
    class All : public Suite {
 
125
    public:
 
126
        All() : Suite( "threading" ){
 
127
        }
 
128
 
 
129
        void setupTests(){
 
130
            add< IsWrappingIntAtomic >();
 
131
            add< MVarTest >();
 
132
            add< ThreadPoolTest >();
 
133
        }
 
134
    } myall;
 
135
}