Finish the replace
[scilab.git] / scilab / modules / core / src / cpp / jitter.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "jitter.hxx"
14
15 __threadLock Jitter::m_lock;
16 __threadSignal Jitter::m_awakeScilab;
17 __threadSignalLock Jitter::m_awakeScilabLock;
18
19 void Jitter::init()
20 {
21     __InitSignal(&m_awakeScilab);
22     __InitSignalLock(&m_awakeScilabLock);
23 }
24
25 void *Jitter::launch(void *args)
26 {
27     bool bdoUnlock = false;
28     //try to lock locker ( waiting parent thread register me )
29     __Lock(&m_lock);
30     //just release locker
31     __UnLock(&m_lock);
32
33     //exec !
34     Jitter *me = (Jitter *)args;
35     try
36     {
37         me->getProgram()->accept(*(me->getVisitor()));
38         ConfigVariable::clearLastError();
39     }
40     catch(ScilabException se)
41     {
42         scilabErrorW(se.GetErrorMessage().c_str());
43     }
44
45     __threadKey currentThreadKey = __GetCurrentThreadKey();
46
47     //change thread status
48     ThreadId* pThread = ConfigVariable::getThread(currentThreadKey);
49     if(pThread->getStatus() != ThreadId::Aborted)
50     {
51         pThread->setStatus(ThreadId::Done);
52         bdoUnlock = true;
53     }
54
55     //unregister thread
56     ConfigVariable::deleteThread(currentThreadKey);
57
58     delete me;
59
60     if(bdoUnlock)
61     {
62         UnlockPrompt();
63     }
64     return NULL;
65 }
66
67 void Jitter::LockPrompt()
68 {
69     __LockSignal(&m_awakeScilabLock);
70     //free locker to release thread
71     __UnLock(&m_lock);
72     __Wait(&m_awakeScilab, &m_awakeScilabLock);
73     __UnLockSignal(&m_awakeScilabLock);
74 }
75
76 void Jitter::UnlockPrompt()
77 {
78     __LockSignal(&m_awakeScilabLock);
79     __Signal(&m_awakeScilab);
80     __UnLockSignal(&m_awakeScilabLock);
81 }
82
83
84 void Jitter::execAndWait(ast::Exp* _theProgram, ast::JITVisitor *_visitor)
85 {
86     try
87     {
88         Jitter *runMe = new Jitter(_theProgram, _visitor);
89         __threadKey threadKey;
90         __threadId threadId;
91
92         //init locker
93         __InitLock(&m_lock);
94         //lock locker
95         __Lock(&m_lock);
96         //launch thread but is can't really start since locker is locked
97         __CreateThreadWithParams(&threadId, &threadKey, &Jitter::launch, runMe);
98         runMe->setThreadId(threadId);
99         runMe->setThreadKey(threadKey);
100
101         //register thread
102         ConfigVariable::addThread(new ThreadId(threadId, threadKey));
103         //free locker to release thread && wait and of thread execution
104         LockPrompt();
105
106         types::ThreadId* pExecThread = ConfigVariable::getThread(threadKey);
107         if(pExecThread == NULL)
108         {//call pthread_join to clean stack allocation
109             __WaitThreadDie(threadId);
110         }
111     }
112     catch(ScilabException se)
113     {
114         throw se;
115     }
116 }
117
118 void Jitter::exec(ast::Exp* _theProgram, ast::JITVisitor *_visitor)
119 {
120     m_theProgram = _theProgram;
121     m_visitor = _visitor;
122     __CreateThreadWithParams(&m_threadId, &m_threadKey, &Jitter::launch, this);
123 }