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

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

Updated examples

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@1026 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*/
131int 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 return 0;
140}
141
142//Initializes mutex as unlocked and kind as defined by int m
143void pthread_mutex_init(pthread_mutex_t *mutex, int m){
144 mutex->kind = m;
145 mutex->lock = 0;
146 mutex->count = 0;
147 mutex->owner = $proc_null;
148}
149
150int pthread_mutex_destroy(pthread_mutex_t *mutex){
151 pthread_mutex_t blank;
152 *mutex = blank;
153 return 0;
154}
155
156
157/* pthread_mutex_lock takes in a mutex variable and acts accordingly to its current state and type
158 PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already locked and behaves accordingly
159 locked and owner: Relock error, returns 0
160 locked and not owner: Waits until mutex is unlocked and then locks and becomes owner
161 unlocked and not owner: Locks the mutex and becomes owner
162 PTHREAD_MUTEX_RECURSIVE
163*/
164int pthread_mutex_lock(pthread_mutex_t *mutex) {
165 $atomic{
166 if (mutex->kind == PTHREAD_MUTEX_NORMAL){
167 if (mutex->lock != 0)
168 {
169 if(mutex->owner == $proc_null){
170 $when(mutex->lock == 0);
171 }
172 else{
173 if(mutex->owner == $self){
174 $assert($false, "ERROR: Relock attempted");
175 return 0;
176 }
177 else{
178 $when(mutex->lock == 0);
179 }
180 }
181 }
182 mutex->owner = $self;
183 mutex->lock = 1;
184 }
185 else {
186 int tmp = mutex->lock;
187 mutex->lock = 1;
188 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
189 mutex->count = 1;
190 mutex->owner = $self;
191 }
192 else {
193 //Checks for ownership, otherwise returns error
194 if(mutex->owner == $self)
195 {
196 // Checks for recursive mutex, otherwise returns an error
197 if (mutex->kind == 1) {
198 mutex->count++;
199 if(mutex->count==0){
200 mutex->lock = 0;
201 mutex->owner = $proc_null;
202 }
203 }
204 else {
205 $assert($false);
206 return 0;
207 }
208 }
209 else {
210 $assert($false);
211 return 0;
212 }
213 }
214 }
215 return 0;
216 }
217}
218
219
220int pthread_mutex_unlock(pthread_mutex_t *mutex) {
221 $atomic{
222 if (mutex->kind == 0 || mutex->kind == 2) {
223 int idx;
224 // Attempts unlock, if already unlocked, returns error
225 if (mutex->lock == 0) {
226 $assert($false, "Attempting to unlock unlocked lock\n");
227 return 0;
228 }
229 else {
230 mutex->lock = 0;
231 mutex->owner = $proc_null;
232 }
233 }
234 else {
235 //Checks for ownership of thread, if not, returns error
236 if(mutex->owner == $self)
237 {
238 //Checks for recursive mutex
239 _Bool tmp = !(mutex->kind == 1);
240 if (--mutex->count == 0){
241 mutex->lock = 0;
242 mutex->owner = $proc_null;
243 }
244 }
245 else {
246 $assert($false);
247 return 0;
248 }
249 }
250 return 0;
251 }
252}
253
254
255int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex){
256 if(mutex->owner != $self)
257 {
258 printf("Mutex not owned by thread");
259 $assert($false);
260 return 0;
261 }
262 cond->proccount= cond->proccount+1;
263 pthread_mutex_unlock(mutex);
264 $when(cond->signal);
265 cond->signal = 0;
266 --cond->proccount;
267 $when(mutex->lock == 0){pthread_mutex_lock(mutex);}
268 return 0;
269}
270
271int pthread_cond_signal(pthread_cond_t *cond){
272 cond->signal = 1;
273 return 0;
274}
275
276int pthread_cond_broadcast(pthread_cond_t *cond){
277 while(cond->proccount > 0){
278 cond->signal = 1;
279 }
280 return 0;
281}
282
283int pthread_attr_init(pthread_attr_t *attr){
284 attr->stacksize = 0;
285 attr->guardsize = 0;
286 attr->detachstate = PTHREAD_CREATE_DETACHED;
287 //attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
288 //attr->scope = PTHREAD_SCOPE_SYSTEM;
289 attr->stackaddr = NULL;
290 //attr->policy = SCHED_OTHER;
291 return 0;
292}
293
294
295//Destroy thread attribute
296int pthread_attr_destroy(pthread_attr_t *attr)
297{
298 pthread_attr_t blank;
299 *attr = blank;
300 return 0;
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.