source: CIVL/examples/pthread/pthread.cvh@ 00dbbe9

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

Added support for robust mutex, get/sets for pthread_mutexattr_t fields, pthread_mutex_trylock, and multiple new competition code examples

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

  • Property mode set to 100644
File size: 20.9 KB
RevLine 
[6fe2cd9]1/*
[f72f577]2 All specification references correspond to pages in the Standard for Information Technology
3Portable Operating System Interface (POSIX)IEEE Computer Society Base Specifications, Issue 7.
[6fe2cd9]4
5Standard modifications to each translation:
6header files are altered
7errors are changed to assertion violations with appropriate messages
8appropriate definitions are changed to input variables
9*/
10
[f741886]11#include <civlc.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <assert.h>
15#include <stdbool.h>
16
17//Mutex types
18#define PTHREAD_MUTEX_DEFAULT 0
19#define PTHREAD_MUTEX_NORMAL 0
20#define PTHREAD_MUTEX_RECURSIVE 1
21#define PTHREAD_MUTEX_ERRORCHECK 2
22
[761eb6f]23//Mutex Robustness Types
24#define PTHREAD_MUTEX_STALLED 0
25#define PTHREAD_MUTEX_ROBUST 1
26
[f741886]27//Attribute Constants
28#define PTHREAD_CREATE_DETACHED 0
29#define PTHREAD_CREATE_JOINABLE 1
30
31//Mutex initializer
[8090425]32#define __LOCK_INITIALIZER 0
33#define PTHREAD_MUTEX_INITIALIZER {0,0,0,PTHREAD_MUTEX_NORMAL,__LOCK_INITIALIZER}
[f741886]34#define PTHREAD_COND_INITIALIZER {__LOCK_INITIALIZER,0}
35
[f72f577]36//Error definitions
37#define EINVAL 1 //Designates an invalid value
38#define ENOTSUP 2
39#define EOWNERDEAD 3 //Designates the termination of the owning thread
40
41
42
43
[6fe2cd9]44/* Struct definitions */
45
[068c228]46/* pthread_attr_t struct definition
[6fe2cd9]47 Description: This struct corresponds to the pthread_attr_t which is the attribute of a pthread_t. It's fields
48 define the way the pthread_t is able to interact (join/detach), (memory capacity), (scope) etc.
49
50 Fields: void * stackaddr: The address of the attr's stack in memory
51 size_t stacksize: The memory capacity for the attr's stack
[f72f577]52 size_t guardsize: The guardsize attribute controls the size of the guard area for the created thread' stack. The
[6fe2cd9]53 guardsize attribute provides protection against overflow of the stack pointer.
54 int detachstate: Defines a threads ability to join with two values: PTHREAD_CREATE_DETACHED and PTHREAD_CREATE_JOINABLE
55 int inheritsched: The inheritance scheduling policy of the thread
56 int contentionscope: Defines the contention scope of the thread
57 int schedpolicy: Determines the scheduling policy of the thread
58
[068c228]59*/
[6fe2cd9]60
[f741886]61typedef struct {
62 void *stackaddr;
63 size_t stacksize;
64 size_t guardsize;
65 int detachstate;
66 int inheritsched;
67 int contentionscope;
[6fe2cd9]68 int schedpolicy;
[f741886]69} pthread_attr_t;
70
[6fe2cd9]71/* pthread_mutexattr_t struct definition
72 Description: The pthread_mutexattr_t defines multiple attributes of a mutex and controls its interactions with threads
73 Fields: robust: defines the robustness of the mutex; if robust and the owning thread terminates, it will notify the
74 next thread of this to prevent deadlocks and other errors
75 pshared: defines the process shared element of the thread and which processes can interact with the mutex
76 protocol: defines the priority protocol of the mutex and which threads may interact first
77 type: defines the type of the mutex as either PTHREAD_MUTEX_DEFAULT/NORMAL, PTHREAD_MUTEX_ERRORCHECK, or
78 PTHREAD_MUTEX_RECURSIVE, each explained in pthread_mutex_lock below
79 prioceiling: defines the lowest priority the mutex's critical section can be at
80*/
81
82typedef struct {
83 int robust;
84 int pshared;
85 int protocol;
86 int type;
87 int prioceiling;
88}pthread_mutexattr_t;
89
90/* pthread_mutex_t struct definition
91 Description: The pthread_mutex_t is a locking mechanism for threads to interact with in order to control the scheduling
92 of the threads. It can be locked, which allows for blocking of other threads waiting on the mutex and unlocked, allowing
93 access. It has a pthread_mutexattr_t which defines its behavior.
94 Fields: count - used for recursive mutex, incremented when locked, decremented when unlocked, mutex released when count is 0
95 owner - current process owner of the mutex
96 lock - int of 0 or 1, respectively 0 if unlocked, 1 if locked
97 prioceiling - allows locking without adherence to the priority ceiling
98 attr - see above
99*/
100
101typedef struct {
102 int count;
103 $proc owner;
104 int lock;
105 int prioceiling;
106 pthread_mutexattr_t *attr;
107} pthread_mutex_t;
108
109//Unimplemented
110/*
111typedef struct {
112 int pshared;
113 clockid_t clock_id;
114}pthread_condattr_t;
115*/
116
117/* pthread_cond_t struct definition
118 Description: The pthread_cond_t is another locking mechanism which interacts with the mutex variable. When
119 the mutex is locked, the condition can be accessed, leading the accessing thread to unlock it, and sleep
120 until the signal is given
121 Fields: proccount - specifies the number of processes/threads still waiting on this condition variable
122 signal - Boolean value stating whether the condition is satisfied (indicated by 1) or not (0)
123*/
124
125typedef struct {
126 int proccount;
127 _Bool signal;
128} pthread_cond_t;
129
[f741886]130/* pthread_t struct definition
[6fe2cd9]131 Description: The pthread_t is a struct containing a $proc variable as well as a thread attribute which defines
132 its interactions with other threads. It encapsulates the $proc and allows attributes to apply to it.
133 Fields: thr: the $proc variable that is the heart of the thread
134 attr: see above
[f741886]135*/
[6fe2cd9]136
[f741886]137typedef struct {
138 $proc thr;
139 const pthread_attr_t *attr;
140} pthread_t;
141
[761eb6f]142/* pthread_attr_init method definition
[6fe2cd9]143 The pthread_attr_init() initializes an attribute with the default values defined for it by an implementation.
144 At the moment, the pthread_attr_t is very basic, only supporting joining/detaching but will be improved
145 upon at a later date.
146 Corresponding specification: p. 153
[761eb6f]147*/
[6fe2cd9]148
[068c228]149int pthread_attr_init(pthread_attr_t *attr){
150 attr->stacksize = 0;
151 attr->guardsize = 0;
152 attr->detachstate = PTHREAD_CREATE_DETACHED;
153 //attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
154 //attr->scope = PTHREAD_SCOPE_SYSTEM;
155 attr->stackaddr = NULL;
[6fe2cd9]156 //attr->schedpolicy = SCHED_OTHER;
[068c228]157 return 0;
158}
[f741886]159
[761eb6f]160/* pthread_attr_destroy method definition
[6fe2cd9]161 This implementation effectively uninitializes the attr variable, which works accordingly with the specification's requirements.
162 Corresponding specification: p. 153/4
[761eb6f]163*/
[068c228]164int pthread_attr_destroy(pthread_attr_t *attr)
165{
166 pthread_attr_t blank;
[6fe2cd9]167
[068c228]168 *attr = blank;
169 return 0;
170}
171
[6fe2cd9]172//Set the detachstate attribute
173//Corresponding specification: p. 153/4
[068c228]174int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
175{
176 attr->detachstate = detachstate;
177 return 0;
178}
179
180//Return the detachstate attribute
[6fe2cd9]181//Corresponding specification: p. 153/4
[068c228]182int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
183{
184 *detachstate = attr->detachstate;
185 return 0;
186}
[f741886]187
[068c228]188//Set scheduling inheritance
[6fe2cd9]189//Corresponding specification: p. 153/4
[068c228]190int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
191{
192 attr->inheritsched = inheritsched;
193 return 0;
194}
195
196//Return the scheduling inheritance
[6fe2cd9]197//Corresponding specification: p. 153/4
[068c228]198int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
199{
200 *inheritsched = attr->inheritsched;
201 return 0;
202}
203
204/*Set scheduling contention scope
[6fe2cd9]205//Corresponding specification: p. 153/4
[068c228]206int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
207{
208 attr->scope = contentionscope;
209 return 0;
210}
[f741886]211
[068c228]212//Return the scheduling contention scope
[6fe2cd9]213//Corresponding specification: p. 153/4
[068c228]214int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
215{
216 *contentionscope = attr->scope;
217 return 0;
218}
[f741886]219*/
220
[f72f577]221// Set the stack size and stack address of the specified pthread_attr_t
222// Corresponding specification p.1548
223int pthread_attr_setstack(pthread_attr_t *attr, void * stackaddr, size_t stacksize){
224 attr->stackaddr = stackaddr;
[068c228]225 attr->stacksize = stacksize;
226 return 0;
227}
[f741886]228
[f72f577]229// Get the stack size and stack address of the specified pthread_attr_t
230// Corresponding specification p.1548
231int pthread_attr_getstack(const pthread_attr_t *attr, void ** stackaddr, size_t *stacksize){
[068c228]232{
[f72f577]233 *stackaddr = attr->stackaddr;
[068c228]234 *stacksize = attr->stacksize;
235 return 0;
236}
237
238//Set guard size
[6fe2cd9]239//Corresponding specification: p. 153/4
[068c228]240int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
241{
242 attr->guardsize = guardsize;
243 return 0;
244}
[f741886]245
[068c228]246// Return guard size
[6fe2cd9]247//Corresponding specification: p. 153/4
[068c228]248int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
249{
250 *guardsize = attr->guardsize;
251 return 0;
252}
253
254//Set scheduling policy
[6fe2cd9]255//Corresponding specification: p. 153/4
[068c228]256int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
257{
[6fe2cd9]258 attr->schedpolicy = policy;
[068c228]259 return 0;
260}
261
262// Return scheduling policy
[6fe2cd9]263//Corresponding specification: p. 153/4
[068c228]264int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
265{
[6fe2cd9]266 *policy = attr->schedpolicy;
[068c228]267 return 0;
268}
[f741886]269
[6fe2cd9]270/* pthread_mutexattr_init method definition
271 This method defines the default values for each of the mutexattr's field
272 //Corresponding specification: p. 165
[068c228]273*/
274
275int pthread_mutexattr_init(pthread_mutexattr_t *attr){
276 attr->robust = 0;
277 attr->pshared = 0;
278 attr->protocol = 0;
279 attr->type = 0;
280 attr->prioceiling = 0;
281 return 0;
282}
283
[6fe2cd9]284/* pthread_mutexattr_destroy method definition
285 This implementation effectively uninitializes the attr variable, which works accordingly with the specification's requirements.
286 //Corresponding specification: p. 165
287*/
288
[068c228]289int pthread_mutexattr_destroy(pthread_mutexattr_t *attr){
290 pthread_mutexattr_t blank;
[6fe2cd9]291
[068c228]292 *attr = blank;
293 return 0;
294}
295
[f72f577]296int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robust){
297 *robust = attr->robust;
298 return 0;
299}
300
301int pthread mutexattr_setrobust(pthread_mutexattr_t *attr, int robust){
302 attr->robust = robust;
303 return 0;
304}
305
306int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared){
307 *pshared = attr->pshared;
308 return 0;
309}
310
311int pthread mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared){
312 attr->pshared = pshared;
313 return 0;
314}
315
316int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol){
317 *protocol = attr->protocol;
318 return 0;
319}
320
321int pthread mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol){
322 attr->protocol = protocol;
323 return 0;
324}
325
326int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type){
327 *type = attr->type;
328 return 0;
329}
330
331int pthread mutexattr_settype(pthread_mutexattr_t *attr, int type){
332 attr->type = type;
333 return 0;
334}
335
336int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling){
337 *prioceiling = attr->prioceiling;
338 return 0;
339}
340
341int pthread mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling){
342 attr->prioceiling = prioceiling;
343 return 0;
344}
345
346
[6fe2cd9]347/* pthread_mutex_init method definition
348 This method initializes each of the mutex's default values as well as being able to take values from another attribute
349 if desired, otherwise the attribute field may be NULL
350 //Corresponding specification: p. 164
[f741886]351*/
[068c228]352
353int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr){
[cf74da3]354 if(attr == NULL){
355 mutex->attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
356 mutex->attr->robust = 0;
357 mutex->attr->pshared = 0;
358 mutex->attr->protocol = 0;
359 mutex->attr->type = PTHREAD_MUTEX_DEFAULT;
360 mutex->attr->prioceiling = 0;
361 }
362 else{
363 mutex->attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
364 mutex->attr = attr;
365 }
[068c228]366 mutex->lock = 0;
367 mutex->count = 0;
368 mutex->owner = $proc_null;
369 return 0;
370}
371
[6fe2cd9]372/* pthread_mutex_destroy method definition
373 This implementation effectively uninitializes the mutex variable, which works accordingly with the specification's requirements.
374 //Corresponding specification: p. 164
375*/
376
[068c228]377int pthread_mutex_destroy(pthread_mutex_t *mutex){
378 pthread_mutex_t blank;
[6fe2cd9]379
[068c228]380 *mutex = blank;
381 return 0;
382}
383
[6fe2cd9]384/* pthread_cond_init method definition
385 Initializes the condition variable so that it begins with 0 processes waiting on it as well as a signal set to be zero
[068c228]386 **Needs to be modified to work with condition attributes as the second parameter
[6fe2cd9]387 //Corresponding specification: p. 158
[068c228]388*/
[6fe2cd9]389
[068c228]390void pthread_cond_init(pthread_cond_t *cond, void *arg){
391 cond->proccount = 0;
392 cond->signal = 0;
393}
394
[6fe2cd9]395
396
397/* pthread_cond_destroy method definition
398 This implementation effectively uninitializes the cond variable, which works accordingly with the specification's requirements.
399 If any threads are still waiting on the condition upon destruction, an error is returned.
400 //Corresponding specification: p. 158
[068c228]401*/
[6fe2cd9]402
[068c228]403int pthread_cond_destroy(pthread_cond_t *cond){
404 if(cond->proccount != 0){
405 $assert($false, "ERROR: Threads still waiting on specified condition variable");
406 }
407 else{
408 pthread_cond_t blank;
409 *cond = blank;
410 }
411 return 0;
412}
413
[6fe2cd9]414/* pthread_create method definition
415 Description: Defines a pthread_t by assigning it an attribute value (by value so the original attribute's state is
416 irrelevant), and spawning a process as the thr field with arguments void *arg
417 //Corresponding specification: p. 160
418*/
419
[f741886]420int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg){
421 thread->thr = $spawn start_routine(arg);
[cf74da3]422 if(attr == NULL){
423 thread->attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
424 thread->attr->stackaddr = NULL;
425 thread->attr->stacksize = 0;
426 thread->attr->guardsize = 0;
427 thread->attr->detachstate = 1;
428 thread->attr->inheritsched = 0;
429 thread->attr->contentionscope = 0;
[6fe2cd9]430 thread->attr->schedpolicy = 0;
[cf74da3]431 }
432 else{
433 thread->attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
434 thread->attr->stackaddr = attr->stackaddr;
435 thread->attr->stacksize = attr->stacksize;
436 thread->attr->guardsize = attr->guardsize;
437 thread->attr->detachstate = attr->detachstate;
438 thread->attr->inheritsched = attr->inheritsched;
439 thread->attr->contentionscope = attr->contentionscope;
[6fe2cd9]440 thread->attr->schedpolicy = attr->schedpolicy;
[cf74da3]441 }
[f741886]442 return 0;
443}
444
[6fe2cd9]445/* pthread_join method definition
446 Description: Causes current thread to wait on thread specified as a parameter. If specified thread's detachstate field is set as PTHREAD_CREATE_DETACHED,
447 error will be returned stating the the thread cannot be joined.
448 //Corresponding specification: p. 160
[f741886]449*/
[6fe2cd9]450
451int pthread_join(pthread_t thread, void **value_ptr){
[2beb8ff]452 if(thread.attr != NULL){
453 if(thread.attr->detachstate == 0){
454 $assert($false, "Thread is designated as unjoinable");
455 return 1;
456 }
[f741886]457 }
458 $wait(thread.thr);
459 return 0;
460}
461
[6fe2cd9]462/* pthread_exit method definition
463 Description: Causes current thread to immediately terminate; if currently in the main method as specified by the
464 isMain parameter, the main method will wait for each thread to terminate before it terminates
465 //Corresponding specification: p. 160
[f741886]466*/
[6fe2cd9]467
[cf74da3]468int pthread_exit(void *arg, _Bool isMain, pthread_t *arr, int len){
469 if(isMain){
470 for(int i = 0; i<len; i++)
471 $wait(arr[i].thr);
472 }
[f741886]473 $exit();
474 return 0;
475}
476
[6fe2cd9]477//Unimplemented
[f741886]478int pthread_detach(pthread_t thread);
479
[6fe2cd9]480/* pthread_mutex_lock method definition
481 Description: pthread_mutex_lock takes in a mutex variable and acts accordingly to its current state and type
482 PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already locked and behaves accordingly
483 locked and owner: Relock error, returns 0
484 locked and not owner: Waits until mutex is unlocked and then locks and becomes owner
485 unlocked and not owner: Locks the mutex and becomes owner
486 PTHREAD_MUTEX_RECURSIVE: A recursive mutex increments its count when it is locked and decremented when
487 it is unlocked and the lock is released when the count reaches 0.
488 PTHREAD_MUTEX_ERRORCHECK: Currently implemented similarly to PTHREAD_MUTEX_NORMAL
489 //Corresponding specification: p. 163
[f741886]490*/
[6fe2cd9]491
492int pthread_mutex_lock(pthread_mutex_t *mutex){
[f741886]493 $atomic{
[6fe2cd9]494 if (mutex->attr->type == PTHREAD_MUTEX_NORMAL){
495 if (mutex->lock != 0) {
496 if(mutex->owner == $proc_null){
[f72f577]497 if(mutex->attr->robust == PTHREAD_MUTEX_ROBUST){
498 $when(mutex->lock == 0);
499 }
500 else{
501 $assert($false);
502 return EOWNERDEAD;
503 }
[f741886]504 }
505 else{
[6fe2cd9]506 if(mutex->owner == $self){
[f72f577]507 $assert($false);
[6fe2cd9]508 return 0;
509 }
510 else{
511 $when(mutex->lock == 0);
512 }
[f741886]513 }
514 }
515 mutex->owner = $self;
[6fe2cd9]516 mutex->lock = 1;
[f741886]517 }
518 else {
[6fe2cd9]519 int tmp = mutex->lock;
[f72f577]520
[6fe2cd9]521 mutex->lock = 1;
522 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
523 mutex->count = 1;
524 mutex->owner = $self;
525 }
526 else {
527 //Checks for ownership, otherwise returns error
528 if(mutex->owner == $self){
529 // Checks for recursive mutex, otherwise returns an error
[f72f577]530 if (mutex->attr->type == PTHREAD_MUTEX_RECURSIVE) {
531 mutex->count++;
532 }
533 else {
534 $assert($false);
535 return 0;
536 }
537 }
538 else {
539 $assert($false, "ERROR: Relock attempted on non-recursive mutex\n");
540 return 0;
541 }
542 }
543 }
544 return 0;
545 }
546}
547
548/* pthread_mutex_lock method definition
549 Description: pthread_mutex_trylock takes in a mutex variable and acts similarly to pthread_mutex_lock except that
550 if the mutex is locked, success will be returned immediately. In the case of a recursive mutex, the count will
551 be incremented and will return successfully.
552 //Corresponding specification: p. 163
553*/
554
555int pthread_mutex_trylock(pthread_mutex_t *mutex){
556 $atomic{
557 if (mutex->attr->type == PTHREAD_MUTEX_NORMAL){
558 if (mutex->lock != 0) {
559 return 0;
560 }
561 mutex->owner = $self;
562 mutex->lock = 1;
563 }
564 else {
565 int tmp = mutex->lock;
566
567 mutex->lock = 1;
568 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
569 mutex->count = 1;
570 mutex->owner = $self;
571 }
572 else {
573 //Checks for ownership, otherwise returns error
574 if(mutex->owner == $self){
575 // Checks for recursive mutex, otherwise returns an error
576 if (mutex->attr->type == PTHREAD_MUTEX_RECURSIVE) {
[6fe2cd9]577 mutex->count++;
578 }
579 else {
580 $assert($false);
581 return 0;
[f741886]582 }
583 }
584 else {
585 return 0;
586 }
587 }
588 }
[6fe2cd9]589 return 0;
[f741886]590 }
591}
592
[6fe2cd9]593/* pthread_mutex_lock method definition
594 Description: pthread_mutex_lock takes in a mutex variable and acts accordingly to its current state and type
595 PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already unlocked and behaves accordingly
596 unlocked: returns error
597 locked: unlocks
598 PTHREAD_MUTEX_RECURSIVE: A recursive mutex increments its count when it is locked and decremented when
599 it is unlocked and the lock is released when the count reaches 0.
600 PTHREAD_MUTEX_ERRORCHECK: Currently implemented similarly to PTHREAD_MUTEX_NORMAL
601 //Corresponding specification: p. 163
602*/
[f741886]603
[6fe2cd9]604int pthread_mutex_unlock(pthread_mutex_t *mutex){
[f741886]605 $atomic{
[6fe2cd9]606 if (mutex->attr->type == 0 || mutex->attr->type == 2) {
607 int idx;
[f72f577]608
[6fe2cd9]609 // Attempts unlock, if already unlocked, returns error
[f72f577]610 if (mutex->lock == 0 && mutex->attr->type == PTHREAD_MUTEX_DEFAULT) {
611 $assert($false);
612 return 0;
613 }
614 else if (mutex->lock == 0 && mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK){
[6fe2cd9]615 $assert($false, "Attempting to unlock unlocked lock\n");
616 return 0;
[f72f577]617 }
[6fe2cd9]618 else {
[f741886]619 mutex->lock = 0;
620 mutex->owner = $proc_null;
621 }
[6fe2cd9]622 }
[f741886]623 else {
[6fe2cd9]624 //Checks for ownership of thread, if not, returns error
625 if(mutex->owner == $self)
626 {
627 //Checks for recursive mutex
628 _Bool tmp = !(mutex->attr->type == 1);
[f72f577]629
[6fe2cd9]630 if (--mutex->count == 0){
631 mutex->lock = 0;
632 mutex->owner = $proc_null;
633 }
634 }
635 else {
636 $assert($false);
637 return 0;
638 }
[f741886]639 }
[6fe2cd9]640 return 0;
[f741886]641 }
642}
643
[f72f577]644/* pthread_mutex_consistent method definition
645 Description: Checks for robustness of mutex: if robust, the mutex is unlocked, otherwise an error is caused
646 and EINVAL is returned
647*/
648int pthread_mutex_consistent(pthread_mutex_t *mutex){
649 if(mutex->attr->robust == PTHREAD_MUTEX_ROBUST){
650 mutex->lock = 0;
651 return 0;
652 }
653 $assert($false);
654 return EINVAL;
655}
656
[6fe2cd9]657/* pthread_cond_wait method definition
658 Description: Checks for calling thread as owner of the mutex, then increments proccount, unlocks the mutex
659 and sleeps. Awakens upon signal and decrements proccount and locks mutex.
660 //Corresponding specification: p. 158
661*/
[f741886]662
663int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex){
[6fe2cd9]664 if(mutex->owner != $self){
[f741886]665 printf("Mutex not owned by thread");
666 $assert($false);
667 return 0;
668 }
[f72f577]669
[f741886]670 cond->proccount= cond->proccount+1;
671 pthread_mutex_unlock(mutex);
[6fe2cd9]672
[f741886]673 $when(cond->signal);
[37bfb99]674 cond->signal = false;
[f741886]675 --cond->proccount;
676 $when(mutex->lock == 0){pthread_mutex_lock(mutex);}
677 return 0;
678}
679
[6fe2cd9]680/* pthread_cond_signal method definition
681 Description: Signals the condition by setting the signal to true
682 //Corresponding specification: p. 158
683*/
684
[f741886]685int pthread_cond_signal(pthread_cond_t *cond){
[37bfb99]686 cond->signal = true;
[f741886]687 return 0;
688}
689
[6fe2cd9]690/* pthread_cond_broadcast method definition
691 Description: Repeated signals the condition until all processes waiting have been signalled and awoken
692 //Corresponding specification: p. 157
693*/
694
[f741886]695int pthread_cond_broadcast(pthread_cond_t *cond){
696 while(cond->proccount > 0){
[37bfb99]697 cond->signal = true;
[f741886]698 }
699 return 0;
700}
701
702
703
704
705
Note: See TracBrowser for help on using the repository browser.