source: CIVL/examples/pthread/pthread.cvh@ 77be3db

1.23 2.0 main test-branch
Last change on this file since 77be3db was 2beb8ff, checked in by John Edenhofner <johneden@…>, 12 years ago

Modified some examples and a Makefile

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@1009 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 9.2 KB
Line 
1#include <civlc.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <assert.h>
5#include <stdbool.h>
6
7//Mutex types
8#define PTHREAD_MUTEX_DEFAULT 0
9#define PTHREAD_MUTEX_NORMAL 0
10#define PTHREAD_MUTEX_RECURSIVE 1
11#define PTHREAD_MUTEX_ERRORCHECK 2
12
13//Attribute Constants
14#define PTHREAD_CREATE_DETACHED 0
15#define PTHREAD_CREATE_JOINABLE 1
16
17
18//Mutex initializer
19#define PTHREAD_MUTEX_INITIALIZER \
20{0,0,0,PTHREAD_MUTEX_NORMAL,__LOCK_INITIALIZER}
21#define __LOCK_INITIALIZER { 0, 0 }
22#define PTHREAD_COND_INITIALIZER {__LOCK_INITIALIZER,0}
23
24typedef struct {
25 void *stackaddr;
26 size_t stacksize;
27 size_t guardsize;
28 int detachstate;
29 int inheritsched;
30 int contentionscope;
31 int policy;
32} pthread_attr_t;
33
34/* pthread_t struct definition
35Contains a $proc and a pthread_attr_t which describes how it interacts with other threads and certain methods
36*/
37typedef struct {
38 $proc thr;
39 const pthread_attr_t *attr;
40} pthread_t;
41
42/* pthread_mutex_t struct definition
43Fields: count - used for recursive mutex, incremented when locked, decremented when unlocked, mutex released when count is 0
44owner - current process owner of the mutex
45lock - int of 0 or 1, respectively 0 if unlocked, 1 if locked
46kind - type of mutex, types defined at beginning of this file
47*/
48typedef struct {
49 int count;
50 $proc owner;
51 int lock;
52 int kind;
53} pthread_mutex_t;
54
55/* pthread_attr_t struct definition
56
57
58*/
59
60
61/* pthread_mutexattr_t struct definition
62Fields: robust: defines the robustness of the mutex
63
64
65
66typedef struct {
67 int robust;
68 int pshared;
69 int protocol;
70 int type;
71 int prioceiling;
72}pthread_mutexattr_t;
73*/
74/*
75typedef struct {
76 int pshared;
77 clockid_t clock_id;
78}pthread_condattr_t;
79*/
80
81/* pthread_cond_t struct definition
82Fields: procount - specifies the number of processes/threads still waiting on this condition variable
83signal - Boolean value stating whether the condition is satisfied (indicated by 1) or not (0)
84*/
85typedef struct {
86 int proccount;
87 _Bool signal;
88} pthread_cond_t;
89
90int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg){
91 thread->thr = $spawn start_routine(arg);
92 thread->attr = attr;
93 return 0;
94}
95
96/* Causes current thread to wait on thread specified as a paremeter. If specified thread's detachstate field is set as PTHREAD_CREATE_DETACHED,
97 error will be returned stating the the thread cannot be joined.
98*/
99int pthread_join(pthread_t thread, void **value_ptr) {
100 if(thread.attr != NULL){
101 if(thread.attr->detachstate == 0){
102 $assert($false, "Thread is designated as unjoinable");
103 return 1;
104 }
105 }
106 $wait(thread.thr);
107 return 0;
108}
109
110/* Calls CIVL $exit method causing the current thread to immediately terminate
111
112*/
113int pthread_exit(void *arg){
114 $exit();
115 return 0;
116}
117
118int pthread_detach(pthread_t thread);
119
120/* Initializes the condition variable so that it begins with 0 processes waiting on it as well as a signal set to be zero
121 **Needs to be modified to work with condition attributes as the second parameter
122*/
123void pthread_cond_init(pthread_cond_t *cond, void *arg){
124 cond->proccount = 0;
125 cond->signal = 0;
126}
127
128/* Unitializes the condition parameter and then frees the data used to store it. If certains threads are still waiting when
129 pthread_cond_destroy is called, an error will be triggered.
130*/
131void pthread_cond_destroy(pthread_cond_t *cond){
132 if(cond->proccount != 0){
133 $assert($false, "ERROR: Threads still waiting on specified condition variable");
134 }
135 else{
136 pthread_cond_t blank;
137 *cond = blank;
138 }
139}
140
141//Initializes mutex as unlocked and kind as defined by int m
142void pthread_mutex_init(pthread_mutex_t *mutex, int m){
143 mutex->kind = m;
144 mutex->lock = 0;
145 mutex->count = 0;
146 mutex->owner = $proc_null;
147}
148
149void pthread_mutex_destroy(pthread_mutex_t *mutex){
150 pthread_mutex_t blank;
151 *mutex = blank;
152}
153
154
155/* pthread_mutex_lock takes in a mutex variable and acts accordingly to its current state and type
156 PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already locked and behaves accordingly
157 locked and owner: Relock error, returns 0
158 locked and not owner: Waits until mutex is unlocked and then locks and becomes owner
159 unlocked and not owner: Locks the mutex and becomes owner
160 PTHREAD_MUTEX_RECURSIVE
161*/
162int pthread_mutex_lock(pthread_mutex_t *mutex) {
163 $atomic{
164 if (mutex->kind == PTHREAD_MUTEX_NORMAL){
165 if (mutex->lock != 0)
166 {
167 if(mutex->owner == $proc_null){
168 $when(mutex->lock == 0);
169 }
170 else{
171 if(mutex->owner == $self){
172 $assert($false, "ERROR: Relock attempted");
173 return 0;
174 }
175 else{
176 $when(mutex->lock == 0);
177 }
178 }
179 }
180 mutex->owner = $self;
181 mutex->lock = 1;
182 }
183 else {
184 int tmp = mutex->lock;
185 mutex->lock = 1;
186 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
187 mutex->count = 1;
188 mutex->owner = $self;
189 }
190 else {
191 //Checks for ownership, otherwise returns error
192 if(mutex->owner == $self)
193 {
194 // Checks for recursive mutex, otherwise returns an error
195 if (mutex->kind == 1) {
196 mutex->count++;
197 if(mutex->count==0){
198 mutex->lock = 0;
199 mutex->owner = $proc_null;
200 }
201 }
202 else {
203 $assert($false);
204 return 0;
205 }
206 }
207 else {
208 $assert($false);
209 return 0;
210 }
211 }
212 }
213 return 0;
214 }
215}
216
217
218int pthread_mutex_unlock(pthread_mutex_t *mutex) {
219 $atomic{
220 if (mutex->kind == 0 || mutex->kind == 2) {
221 int idx;
222 // Attempts unlock, if already unlocked, returns error
223 if (mutex->lock == 0) {
224 $assert($false, "Attempting to unlock unlocked lock\n");
225 return 0;
226 }
227 else {
228 mutex->lock = 0;
229 mutex->owner = $proc_null;
230 }
231 }
232 else {
233 //Checks for ownership of thread, if not, returns error
234 if(mutex->owner == $self)
235 {
236 //Checks for recursive mutex
237 _Bool tmp = !(mutex->kind == 1);
238 if (--mutex->count == 0){
239 mutex->lock = 0;
240 mutex->owner = $proc_null;
241 }
242 }
243 else {
244 $assert($false);
245 return 0;
246 }
247 }
248 return 0;
249 }
250}
251
252
253int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex){
254 if(mutex->owner != $self)
255 {
256 printf("Mutex not owned by thread");
257 $assert($false);
258 return 0;
259 }
260 cond->proccount= cond->proccount+1;
261 pthread_mutex_unlock(mutex);
262 $when(cond->signal);
263 cond->signal = 0;
264 --cond->proccount;
265 $when(mutex->lock == 0){pthread_mutex_lock(mutex);}
266 return 0;
267}
268
269int pthread_cond_signal(pthread_cond_t *cond){
270 cond->signal = 1;
271 return 0;
272}
273
274int pthread_cond_broadcast(pthread_cond_t *cond){
275 while(cond->proccount > 0){
276 cond->signal = 1;
277 }
278 return 0;
279}
280
281int pthread_attr_init(pthread_attr_t *attr){
282 attr->stacksize = 0;
283 attr->guardsize = 0;
284 attr->detachstate = PTHREAD_CREATE_DETACHED;
285 //attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
286 //attr->scope = PTHREAD_SCOPE_SYSTEM;
287 attr->stackaddr = NULL;
288 //attr->policy = SCHED_OTHER;
289 return 0;
290}
291
292
293//Destroy thread attribute
294int pthread_attr_destroy(pthread_attr_t *attr)
295{
296 pthread_attr_t *tmp = attr;
297 pthread_attr_t blank;
298 *attr = blank;
299 $free(tmp);
300
301}
302
303//Set the detachstate attribute
304int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
305{
306 attr->detachstate = detachstate;
307 return 0;
308}
309
310//Return the detachstate attribute
311int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
312{
313 *detachstate = attr->detachstate;
314 return 0;
315}
316
317//Set scheduling inheritance
318int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
319{
320 attr->inheritsched = inheritsched;
321 return 0;
322}
323
324//Return the scheduling inheritance
325int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
326{
327 *inheritsched = attr->inheritsched;
328 return 0;
329}
330
331/*Set scheduling contention scope
332int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
333{
334 attr->scope = contentionscope;
335 return 0;
336}
337
338//Return the scheduling contention scope
339int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
340{
341 *contentionscope = attr->scope;
342 return 0;
343}
344*/
345
346//Set the starting address of the stack of the thread
347int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
348{
349 attr->stackaddr = stackaddr;
350 return 0;
351}
352
353//Return the address for the stack
354int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
355{
356 *stackaddr = attr->stackaddr;
357 return 0;
358}
359
360//Set stack size
361int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
362{
363 attr->stacksize = stacksize;
364 return 0;
365}
366
367//Return the stack size
368int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
369{
370 *stacksize = attr->stacksize;
371 return 0;
372}
373
374//Set guard size
375int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
376{
377 attr->guardsize = guardsize;
378 return 0;
379}
380
381// Return guard size
382int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
383{
384 *guardsize = attr->guardsize;
385 return 0;
386}
387
388//Set scheduling policy
389int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
390{
391 attr->policy = policy;
392 return 0;
393}
394
395// Return scheduling policy
396int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
397{
398 *policy = attr->policy;
399 return 0;
400}
401
402
403
404
405
Note: See TracBrowser for help on using the repository browser.