source: CIVL/examples/pthread/pthread.cvh@ 8090425

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

Updated headers for examples

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

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