Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / test-threads.cc
1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "platform.h"
31 #include "isolate.h"
32
33 #include "cctest.h"
34
35
36 enum Turn {
37   FILL_CACHE,
38   CLEAN_CACHE,
39   SECOND_TIME_FILL_CACHE,
40   DONE
41 };
42
43 static Turn turn = FILL_CACHE;
44
45
46 class ThreadA : public v8::internal::Thread {
47  public:
48   ThreadA() : Thread("ThreadA") { }
49   void Run() {
50     v8::Isolate* isolate = CcTest::isolate();
51     v8::Locker locker(isolate);
52     v8::Isolate::Scope isolate_scope(isolate);
53     v8::HandleScope scope(isolate);
54     v8::Handle<v8::Context> context = v8::Context::New(isolate);
55     v8::Context::Scope context_scope(context);
56
57     CHECK_EQ(FILL_CACHE, turn);
58
59     // Fill String.search cache.
60     v8::Handle<v8::Script> script = v8::Script::Compile(
61         v8::String::NewFromUtf8(
62           isolate,
63           "for (var i = 0; i < 3; i++) {"
64           "  var result = \"a\".search(\"a\");"
65           "  if (result != 0) throw \"result: \" + result + \" @\" + i;"
66           "};"
67           "true"));
68     CHECK(script->Run()->IsTrue());
69
70     turn = CLEAN_CACHE;
71     do {
72       {
73         v8::Unlocker unlocker(CcTest::isolate());
74         Thread::YieldCPU();
75       }
76     } while (turn != SECOND_TIME_FILL_CACHE);
77
78     // Rerun the script.
79     CHECK(script->Run()->IsTrue());
80
81     turn = DONE;
82   }
83 };
84
85
86 class ThreadB : public v8::internal::Thread {
87  public:
88   ThreadB() : Thread("ThreadB") { }
89   void Run() {
90     do {
91       {
92         v8::Isolate* isolate = CcTest::isolate();
93         v8::Locker locker(isolate);
94         v8::Isolate::Scope isolate_scope(isolate);
95         if (turn == CLEAN_CACHE) {
96           v8::HandleScope scope(isolate);
97           v8::Handle<v8::Context> context = v8::Context::New(isolate);
98           v8::Context::Scope context_scope(context);
99
100           // Clear the caches by forcing major GC.
101           CcTest::heap()->CollectAllGarbage(v8::internal::Heap::kNoGCFlags);
102           turn = SECOND_TIME_FILL_CACHE;
103           break;
104         }
105       }
106
107       Thread::YieldCPU();
108     } while (true);
109   }
110 };
111
112
113 TEST(JSFunctionResultCachesInTwoThreads) {
114   ThreadA threadA;
115   ThreadB threadB;
116
117   threadA.Start();
118   threadB.Start();
119
120   threadA.Join();
121   threadB.Join();
122
123   CHECK_EQ(DONE, turn);
124 }
125
126 class ThreadIdValidationThread : public v8::internal::Thread {
127  public:
128   ThreadIdValidationThread(i::Thread* thread_to_start,
129                            i::List<i::ThreadId>* refs,
130                            unsigned int thread_no,
131                            i::Semaphore* semaphore)
132     : Thread("ThreadRefValidationThread"),
133       refs_(refs), thread_no_(thread_no), thread_to_start_(thread_to_start),
134       semaphore_(semaphore) {
135   }
136
137   void Run() {
138     i::ThreadId thread_id = i::ThreadId::Current();
139     for (int i = 0; i < thread_no_; i++) {
140       CHECK(!(*refs_)[i].Equals(thread_id));
141     }
142     CHECK(thread_id.IsValid());
143     (*refs_)[thread_no_] = thread_id;
144     if (thread_to_start_ != NULL) {
145       thread_to_start_->Start();
146     }
147     semaphore_->Signal();
148   }
149
150  private:
151   i::List<i::ThreadId>* refs_;
152   int thread_no_;
153   i::Thread* thread_to_start_;
154   i::Semaphore* semaphore_;
155 };
156
157
158 TEST(ThreadIdValidation) {
159   const int kNThreads = 100;
160   i::List<ThreadIdValidationThread*> threads(kNThreads);
161   i::List<i::ThreadId> refs(kNThreads);
162   i::Semaphore semaphore(0);
163   ThreadIdValidationThread* prev = NULL;
164   for (int i = kNThreads - 1; i >= 0; i--) {
165     ThreadIdValidationThread* newThread =
166         new ThreadIdValidationThread(prev, &refs, i, &semaphore);
167     threads.Add(newThread);
168     prev = newThread;
169     refs.Add(i::ThreadId::Invalid());
170   }
171   prev->Start();
172   for (int i = 0; i < kNThreads; i++) {
173     semaphore.Wait();
174   }
175   for (int i = 0; i < kNThreads; i++) {
176     delete threads[i];
177   }
178 }
179
180
181 class ThreadC : public v8::internal::Thread {
182  public:
183   ThreadC() : Thread("ThreadC") { }
184   void Run() {
185     Join();
186   }
187 };
188
189
190 TEST(ThreadJoinSelf) {
191   ThreadC thread;
192   thread.Start();
193   thread.Join();
194 }