1 /* threads.h                                       -*- mode:c; coding:utf-8; -*-
2  *
3  * multi thread extensions
4  *
5  *   Copyright (c) 2010-2015  Takashi Kato <ktakashi@ymail.com>
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *   1. Redistributions of source code must retain the above copyright
12  *      notice, this list of conditions and the following disclaimer.
13  *
14  *   2. Redistributions in binary form must reproduce the above copyright
15  *      notice, this list of conditions and the following disclaimer in the
16  *      documentation and/or other materials provided with the distribution.
17  *
18  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *  $Id: $
31  */
32 #ifndef SAGITTARIUS_THREADS_H_
33 #define SAGITTARIUS_THREADS_H_
34 
35 #include <sagittarius.h>
36 
37 SG_CLASS_DECL(Sg_ConditionVariableClass);
38 #define SG_CLASS_CONDITION_VARIABLE (&Sg_ConditionVariableClass)
39 
40 typedef struct SgConditionVariableRec
41 {
42   SG_INSTANCE_HEADER;
43   SgInternalCond cv;
44   SgObject name;
45   SgObject specific;
46 } SgConditionVariable;
47 
48 
49 #define SG_CONDITION_VARIABLE(obj) ((SgConditionVariable *)obj)
50 #define SG_CONDITION_VARIABLE_P(obj) SG_XTYPEP(obj, SG_CLASS_CONDITION_VARIABLE)
51 
52 SG_CLASS_DECL(Sg_MutexClass);
53 #define SG_CLASS_MUTEX     (&Sg_MutexClass)
54 typedef struct SgMutexRec
55 {
56   SG_INSTANCE_HEADER;
57   SgInternalMutex mutex;
58   SgInternalCond  cv;
59   SgObject name;
60   SgObject specific;
61   int locked;
62   SgVM *owner;
63 } SgMutex;
64 
65 #define SG_MUTEX(obj)     ((SgMutex *)obj)
66 #define SG_MUTEXP(obj)   SG_XTYPEP(obj, SG_CLASS_MUTEX)
67 
68 /* conditions */
69 SG_CLASS_DECL(Sg_ThreadExceptionClass);
70 SG_CLASS_DECL(Sg_JoinTimeoutExceptionClass);
71 SG_CLASS_DECL(Sg_AbondanedMutexExceptionClass);
72 SG_CLASS_DECL(Sg_TerminatedThreadExceptionClass);
73 SG_CLASS_DECL(Sg_UncaughtExceptionClass);
74 SG_CLASS_DECL(Sg_ThreadInterruptExceptionClass);
75 
76 #define SG_CLASS_THREAD_EXCEPTION            (&Sg_ThreadExceptionClass)
77 #define SG_CLASS_JOIN_TIMEOUT_EXCEPTION      (&Sg_JoinTimeoutExceptionClass)
78 #define SG_CLASS_ABONDANED_MUTEX_EXCEPTION   (&Sg_AbondanedMutexExceptionClass)
79 #define SG_CLASS_TERMINATED_THREAD_EXCEPTION (&Sg_TerminatedThreadExceptionClass)
80 #define SG_CLASS_UNCAUGHT_EXCEPTION          (&Sg_UncaughtExceptionClass)
81 #define SG_CLASS_THREAD_INTERRUPT_EXCEPTION  (&Sg_ThreadInterruptExceptionClass)
82 
83 typedef struct SgThreadExceptionRec
84 {
85   SG_INSTANCE_HEADER;
86   SgObject thread;
87 } SgThreadException;
88 #define SG_THREAD_EXCEPTION(o)  ((SgThreadException *)o)
89 #define SG_THREAD_EXCEPTIONP(o) SG_ISA(o, SG_CLASS_THREAD_EXCEPTION)
90 
91 typedef struct SgAbondanedMutexExceptionRec
92 {
93   SgThreadException parent;
94   SgObject mutex;
95 } SgAbondanedMutexException;
96 #define SG_ABONDANED_MUTEX_EXCEPTION(o)	((SgAbondanedMutexException *)o)
97 #define SG_ABONDANED_MUTEX_EXCEPTIONP(o)	\
98   SG_ISA(o, SG_CLASS_ABONDANED_MUTEX_EXCEPTION)
99 
100 typedef struct SgTerminatedThreadExceptionRec
101 {
102   SgThreadException parent;
103   SgObject terminator;
104 } SgTerminatedThreadException;
105 #define SG_TERMINATED_THREAD_EXCEPTION(o) ((SgTerminatedThreadException *)o)
106 #define SG_TERMINATED_THREAD_EXCEPTIONP(o)		\
107   SG_ISA(o, SG_CLASS_TERMINATED_THREAD_EXCEPTION)
108 
109 typedef struct SgUncaughtExceptionRec
110 {
111   SgThreadException parent;
112   SgObject reason;
113 } SgUncaughtException;
114 #define SG_UNCAUGHT_EXCEPTION(o)  ((SgUncaughtException *)o)
115 #define SG_UNCAUGHT_EXCEPTIONP(o) SG_ISA(o, SG_CLASS_UNCAUGHT_EXCEPTION)
116 
117 /* semaphore
118 
119    For now we expose native functionality with thin wrapper.
120  */
121 SG_CLASS_DECL(Sg_SemaphoreClass);
122 #define SG_CLASS_SEMAPHORE     (&Sg_SemaphoreClass)
123 typedef struct SgSemaphoreRec
124 {
125   SG_INSTANCE_HEADER;
126   SgInternalSemaphore *semaphore;
127 } SgSemaphore;
128 
129 #define SG_SEMAPHORE(obj)    ((SgSemaphore *)obj)
130 #define SG_SEMAPHOREP(obj)   SG_XTYPEP(obj, SG_CLASS_SEMAPHORE)
131 
132 
133 SG_CDECL_BEGIN
134 /*
135   Scheme level thread API
136  */
137 
138 extern SgObject Sg_MakeThread(SgProcedure *thunk, SgObject name);
139 extern SgObject Sg_ThreadStart(SgVM *vm);
140 extern SgObject Sg_ThreadJoin(SgVM *vm, SgObject timeout, SgObject timeoutval);
141 extern SgObject Sg_ThreadSuspend(SgVM *vm, SgObject timeout, SgObject timeoutval);
142 extern SgObject Sg_ThreadResume(SgVM *vm);
143 extern SgObject Sg_ThreadSleep(SgObject timeout);
144 extern SgObject Sg_ThreadTerminate(SgVM *vm);
145 extern SgObject Sg_ThreadInterrupt(SgVM *vm);
146 extern unsigned long Sg_SysNanosleep(double nanosecond);
147 
148 SgObject Sg_MakeConditionVariable(SgObject name);
149 SgObject Sg_ConditionVariableSignal(SgConditionVariable *cond);
150 SgObject Sg_ConditionVariableBroadcast(SgConditionVariable *cond);
151 
152 SgObject Sg_MakeMutex(SgObject name);
153 SgObject Sg_MutexState(SgMutex *mutex);
154 SgObject Sg_MutexLock(SgMutex *mutex, SgObject timeout, SgVM *owner);
155 SgObject Sg_MutexUnlock(SgMutex *mutex, SgConditionVariable *cv, SgObject timeout);
156 
157 /* thread exceptions */
158 SgObject Sg_MakeJoinTimeoutException(SgVM *vm);
159 SgObject Sg_MakeAbandonedMutexException(SgVM *vm, SgMutex *mutex);
160 SgObject Sg_MakeTerminatedThreadException(SgVM *vm, SgVM *terminator);
161 SgObject Sg_MakeUncaughtException(SgVM *vm, SgObject reason);
162 SgObject Sg_MakeThreadInterruptException(SgVM *vm);
163 
164 /* semaphore */
165 /* values <=0 means retriving */
166 SgObject Sg_MakeSemaphore(SgObject name, int value);
167 int      Sg_SemaphoreWait(SgSemaphore *sem, SgObject timeout);
168 int      Sg_SemaphorePost(SgSemaphore *sem);
169 void     Sg_SemaphoreClose(SgSemaphore *sem);
170 void     Sg_SemaphoreDestroy(SgSemaphore *sem);
171 
172 
173 SG_CDECL_END
174 #endif /* ! SAGITTARIUS_THREADS_H_ */
175 
176 /*
177   end of file
178   Local Variables:
179   coding: utf-8-unix
180   End:
181 */
182