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