ASC-4041: Skip two spidermonkey regression tests due to stack overflow when compiling...
[tamarin-stm.git] / extensions / ST_mmgc_threads.st
blob005670e193471ffe10970ff9bb8457d787371b52
1 // -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*-
2 // vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 //
4 // ***** BEGIN LICENSE BLOCK *****
5 // Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 //
7 // The contents of this file are subject to the Mozilla Public License Version
8 // 1.1 (the "License"); you may not use this file except in compliance with
9 // the License. You may obtain a copy of the License at
10 // http://www.mozilla.org/MPL/
12 // Software distributed under the License is distributed on an "AS IS" basis,
13 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 // for the specific language governing rights and limitations under the
15 // License.
17 // The Original Code is [Open Source Virtual Machine.].
19 // The Initial Developer of the Original Code is
20 // Adobe System Incorporated.
21 // Portions created by the Initial Developer are Copyright (C) 2004-2006
22 // the Initial Developer. All Rights Reserved.
24 // Contributor(s):
25 //   Adobe AS3 Team
27 // Alternatively, the contents of this file may be used under the terms of
28 // either the GNU General Public License Version 2 or later (the "GPL"), or
29 // the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 // in which case the provisions of the GPL or the LGPL are applicable instead
31 // of those above. If you wish to allow use of your version of this file only
32 // under the terms of either the GPL or the LGPL, and not to allow others to
33 // use your version of this file under the terms of the MPL, indicate your
34 // decision by deleting the provisions above and replace them with the notice
35 // and other provisions required by the GPL or the LGPL. If you do not delete
36 // the provisions above, a recipient may use your version of this file under
37 // the terms of any one of the MPL, the GPL or the LGPL.
39 // ***** END LICENSE BLOCK ***** */
41 %%component mmgc
42 %%category threads
43 %%ifdef     VMCFG_WORKERTHREADS
45 %%methods
46 using namespace MMgc;
48 class RCObjectNotifier : public RCObject
50 public:
51         RCObjectNotifier(bool *isDead) : isDead(isDead) {}
52         ~RCObjectNotifier() { *isDead = true; isDead = NULL; }
53         bool *isDead;
56 %%decls
58 private:
59     MMgc::GC *gc;
60     MMgc::FixedAlloc *fa;
61     MMgc::FixedMalloc *fm;
62     bool waiting;
63     bool result;
64     bool isDead;
65     pthread_t pthread;
66     pthread_mutex_t pmutex;
67     pthread_cond_t pcond;
69     static void* slaveRunner(void *arg)
70     {
71         ((ST_mmgc_threads*)arg)->slaveRun();
72         return NULL;
73     }
75     void slaveRun()
76     {
77         wait();
78         {
79       MMGC_ENTER_VOID;
80          MMGC_GCENTER(gc);
81          result &= !isDead;
82          gc->ReapZCT();
83          result &= !isDead;
84          gc->Collect();
85          result &= !isDead;
86         }
87         kick();
88     }
90     void startSlave()
91     {
92        pthread_create(&pthread, NULL, slaveRunner, this);
93     }
95     void kick()
96     {
97         pthread_mutex_lock (&pmutex);
98         while(!waiting) {
99             pthread_mutex_unlock (&pmutex);
100             usleep(100);
101             pthread_mutex_lock (&pmutex);
102         }
103         pthread_cond_signal (&pcond);
104         while(waiting) {
105             pthread_mutex_unlock (&pmutex);
106             usleep(100);
107             pthread_mutex_lock (&pmutex);
108         }
109         pthread_mutex_unlock (&pmutex);
110     }
112     void wait()
113     {
114         pthread_mutex_lock (&pmutex);
115         GCAssert(waiting == false);
116         waiting = true;
117         pthread_cond_wait (&pcond, &pmutex);
118         waiting = false;
119         pthread_mutex_unlock (&pmutex);
120     }
122     static void kickAndWait(void* arg)
123     {
124         ST_mmgc_threads* self = (ST_mmgc_threads*)arg;
125         self->kick();
126         self->wait();
127     }
129 %%prologue
130     gc=new MMgc::GC(MMgc::GCHeap::GetGCHeap(), MMgc::GC::kIncrementalGC);
131     if (gc==NULL) {
132         MMgc::GCHeap::Init();
133         gc=new MMgc::GC(MMgc::GCHeap::GetGCHeap(), MMgc::GC::kIncrementalGC);
134     }
135     pthread_mutex_init(&pmutex, NULL);
136     pthread_cond_init(&pcond, NULL);
137     result = true;
138     isDead = false;
139     waiting = false;
141 %%epilogue
142     pthread_mutex_destroy(&pmutex);
143     pthread_cond_destroy(&pcond);
144     delete gc;
146 %%test mmgc_gc_root_thread
147        startSlave();
148        MMGC_GCENTER(gc);
149        RCObjectNotifier *obj = new (gc) RCObjectNotifier(&isDead);
150        {
151           gc->CreateRootFromCurrentStack(kickAndWait, this);
152        }
154        %%verify result
156        %%verify !isDead
157        gc->ReapZCT();
158        %%verify !isDead
159        gc->Collect();
160        %%verify !isDead
162        pthread_join(pthread, NULL);
164        printf("Ignore this: %d\n", *obj->isDead);