source: CIVL/text/include/pthread-c.cvl@ aef8b11

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

Modified pthread_mutex_lock to work without the need for a state function, as well as modifying pthread_cond_wait to be in line with the specification.

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

  • Property mode set to 100644
File size: 23.7 KB
Line 
1extern void *value = NULL;
2__pthread_pool_t _pool={.len = 0};
3
4/*void _add_thread(__pthread_pool_t* pool, pthread_t* thread){
5 $atomic{
6 int len = pool->len;
7 pthread_t** newThreads = (pthread_t**) malloc(sizeof(pthread_t*) * (len+1));
8
9 if(pool->threads != NULL)
10 for(int i = 0; i < len - 1; i++)
11 *(newThreads+i) = *(pool->threads+i);
12 *(newThreads+len) = thread;
13 pool->threads = newThreads;
14 pool->len = len + 1;
15 }
16}*/
17
18/**
19 * Initializes an attribute with the default values defined for it by an implementation.
20 * Corresponding specification: p. 1532-4
21 *
22 * @param *attr
23 * The attribute to be initialized.
24 * @return Returns 0 upon successful completion
25 */
26
27int pthread_attr_init(pthread_attr_t *attr){
28 attr->detachstate = PTHREAD_CREATE_DETACHED;
29 //attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
30 attr->contentionscope = PTHREAD_SCOPE_SYSTEM;
31 //attr->schedpolicy = SCHED_OTHER;
32 return 0;
33}
34
35/**
36 * Uninitializes the specified attr variable.
37 * Corresponding specification: p. 1532-4
38 *
39 * @param *attr
40 * The attribute to be uninitialized.
41 * @return Returns 0 upon successful completion
42 */
43
44int pthread_attr_destroy(pthread_attr_t *attr)
45{
46 pthread_attr_t blank;
47
48 *attr = blank;
49 return 0;
50}
51
52
53/**
54 * Sets the detachstate field of the attribute
55 * Corresponding specification: p. 1535-6
56 *
57 * @param *attr
58 * The attribute to have it's detachstate set
59 * @param detachstate
60 * The detachstate to which the attribute's detachstate is set
61 * @return Returns 0 upon successful completion
62 */
63
64int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
65{
66 attr->detachstate = detachstate;
67 return 0;
68}
69
70/**
71 * Stores the detachstate value of the attribute in an alternate location
72 * Corresponding specification: p. 1535-6
73 *
74 * @param *attr
75 * The attribute whose detachstate is to be stored
76 * @param *detachstate
77 * The location at which the detachstate is to be stored
78 * @return Returns 0 upon successful completion
79 */
80
81int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
82{
83 *detachstate = attr->detachstate;
84 return 0;
85}
86
87/**
88 * Set scheduling inheritance
89 * Corresponding specification: p. 1540-1
90 *
91 * @param *attr
92 * The attribute to have it's inheritsched set
93 * @param inheritsched
94 * The inheritsched to which the attribute's inheritsched is set
95 * @return Returns 0 upon successful completion
96 */
97
98int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
99{
100 attr->inheritsched = inheritsched;
101 return 0;
102}
103
104/**
105 * Stores the inheritsched value of the attribute in an alternate location
106 * Corresponding specification: p. 1540-1
107 *
108 * @param *attr
109 * The attribute whose inheritsched is to be stored
110 * @param *intheritsched
111 * The location at which the attribute's inheritsched is to be stored
112 * @return Returns 0 upon successful completion
113 */
114
115int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
116{
117 *inheritsched = attr->inheritsched;
118 return 0;
119}
120
121/**
122 * Set contentionscope field of the attribute
123 * Corresponding specification: p. 1546-7
124 *
125 * @param *attr
126 * The attribute to have it's contentionscope set
127 * @param contentionscope
128 * The contentionscope to which the attribute's contentionscope is set
129 * @return Returns 0 upon successful completion
130 */
131
132int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
133{
134 attr->contentionscope = contentionscope;
135 return 0;
136}
137
138/**
139 * Stores the contentionscope value of the attribute in an alternate location
140 * Corresponding specification: p. 1546-7
141 *
142 * @param *attr
143 * The attribute whose contentionscope is to be stored
144 * @param *contentionscope
145 * The location at which the attribute's contentionscope is to be stored
146 * @return Returns 0 upon successful completion
147 */
148
149int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
150{
151 *contentionscope = attr->contentionscope;
152 return 0;
153}
154
155/**
156 * Sets the scheduling policy field of the attribute
157 * Corresponding specification: p. 1544-45
158 *
159 * @param *attr
160 * The attribute to have it's scheduling policy set
161 * @param policy
162 * The scheduling policy to which the attribute's scheduling policy is set
163 * @return Returns 0 upon successful completion
164 */
165
166int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
167{
168 attr->schedpolicy = policy;
169 return 0;
170}
171
172/**
173 * Stores the scheduling policy value in an alternate location
174 * Corresponding specification: p. 1544-45
175 *
176 * @param *attr
177 * The attribute whose scheduling policy is to be stored
178 * @param *policy
179 * The location at which the attribute's scheduling policy is to be stored
180 * @return Returns 0 upon successful completion
181 */
182
183int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
184{
185 *policy = attr->schedpolicy;
186 return 0;
187}
188
189/**
190 * Initializes an attribute with the default values defined for it by an implementation.
191 * Corresponding specification: p. 1647-51
192 *
193 * @param *attr
194 * The attribute to be initialized.
195 * @return Returns 0 upon successful completion
196 */
197
198int pthread_mutexattr_init(pthread_mutexattr_t *attr){
199 attr->robust = 0;
200 attr->pshared = 0;
201 attr->protocol = 0;
202 attr->type = 0;
203 attr->prioceiling = 0;
204 return 0;
205}
206
207/**
208 * Uninitializes the specified attr variable.
209 * Corresponding specification: p. 1647-51
210 *
211 * @param *attr
212 * The attribute to be uninitialized.
213 * @return Returns 0 upon successful completion
214 */
215
216int pthread_mutexattr_destroy(pthread_mutexattr_t *attr){
217 pthread_mutexattr_t blank;
218
219 *attr = blank;
220 return 0;
221}
222
223/**
224 * Stores the robustness value in an alternate location
225 * Corresponding specification: p. 1659-1660
226 *
227 * @param *attr
228 * The attribute whose robustness is to be stored
229 * @param *robust
230 * The location at which the attribute's robustness is to be stored
231 * @return Returns 0 upon successful completion
232 */
233
234int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robust){
235 *robust = attr->robust;
236 return 0;
237}
238
239/**
240 * Sets the robustness field of the attribute
241 * Corresponding specification: p. 1659-1660
242 *
243 * @param *attr
244 * The attribute to have it's robustness set
245 * @param robust
246 * The robustness to which the attribute's robustness is set
247 * @return Returns 0 upon successful completion
248 */
249
250int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust){
251 attr->robust = robust;
252 return 0;
253}
254
255/**
256 * Stores the process shared variable in an alternate location
257 * Corresponding specification: p. 1657-8
258 *
259 * @param *attr
260 * The attribute whose process shared variable is to be stored
261 * @param *detachstate
262 * The location at which the attribute's process shared variable is to be stored
263 * @return Returns 0 upon successful completion
264 */
265
266int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared){
267 *pshared = attr->pshared;
268 return 0;
269}
270
271/**
272 * Sets the process shared variable field of the attribute
273 * Corresponding specification: p. 1657-8
274 *
275 * @param *attr
276 * The attribute to have it's process shared variable set
277 * @param detachstate
278 * The process shared variable to which the attribute's process shared variable is set
279 * @return Returns 0 upon successful completion
280 */
281
282int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared){
283 attr->pshared = pshared;
284 return 0;
285}
286
287/**
288 * Stores the protocol value in an alternate location
289 * Corresponding specification: p. 1654-56
290 *
291 * @param *attr
292 * The attribute whose protocol is to be stored
293 * @param *detachstate
294 * The location at which the attribute's protocol is to be stored
295 * @return Returns 0 upon successful completion
296 */
297
298int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol){
299 *protocol = attr->protocol;
300 return 0;
301}
302
303/**
304 * Sets the protocol field of the attribute
305 * Corresponding specification: p. 1654-56
306 *
307 * @param *attr
308 * The protocol to have it's protocol set
309 * @param detachstate
310 * The protocol to which the attribute's protocol is set
311 * @return Returns 0 upon successful completion
312 */
313int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol){
314 attr->protocol = protocol;
315 return 0;
316}
317
318/**
319 * Stores the type value in an alternate location
320 * Corresponding specification: p. 1709-10
321 *
322 * @param *attr
323 * The attribute whose type is to be stored
324 * @param *detachstate
325 * The location at which the attribute's type is to be stored
326 * @return Returns 0 upon successful completion
327 */
328int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type){
329 *type = attr->type;
330 return 0;
331}
332
333/**
334 * Sets the type field of the attribute
335 * Corresponding specification: p. 1709-10
336 *
337 * @param *attr
338 * The attribute to have it's type set
339 * @param detachstate
340 * The type to which the attribute's type is set
341 * @return Returns 0 upon successful completion
342 */
343int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type){
344 attr->type = type;
345 return 0;
346}
347
348/**
349 * Stores the priority ceiling value in an alternate location
350 * Corresponding specification: p. 1700-1
351 *
352 * @param *attr
353 * The attribute whose priority ceiling is to be stored
354 * @param *detachstate
355 * The location at which the attribute's priority ceiling is to be stored
356 * @return Returns 0 upon successful completion
357 */
358
359int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling){
360 *prioceiling = attr->prioceiling;
361 return 0;
362}
363
364/**
365 * Sets the priority ceiling field of the attribute
366 * Corresponding specification: p. 1700-1
367 *
368 * @param *attr
369 * The attribute to have it's priority ceiling set
370 * @param detachstate
371 * The priority ceiling to which the attribute's priority ceiling is set
372 * @return Returns 0 upon successful completion
373 */
374
375int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling){
376 attr->prioceiling = prioceiling;
377 return 0;
378}
379
380
381/**
382 * Initializes a mutex with the default values defined for it by an implementation
383 * or with the values defined by the mutex attribute parameter
384 * Corresponding specification: p. 1676-81
385 *
386 * @param *mutex
387 * The mutex to be initialized.
388 * @param *attr
389 * The mutex attribute which the mutex shall take as it's field. May also
390 * be null for default values to be initialized.
391 * @return Returns 0 upon successful completion
392 */
393
394int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr){
395 if(attr == NULL){
396 mutex->attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
397 mutex->attr->robust = 0;
398 mutex->attr->pshared = 0;
399 mutex->attr->protocol = 0;
400 mutex->attr->type = PTHREAD_MUTEX_NORMAL;
401 mutex->attr->prioceiling = 0;
402 }
403 else{
404 mutex->attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
405 mutex->attr = attr;
406 }
407 mutex->lock = 0;
408 mutex->count = 0;
409 mutex->owner = $proc_null;
410 return 0;
411}
412
413/**
414 * Uninitializes the specified mutex variable.
415 * Corresponding specification: p. 1676-81
416 *
417 * @param *mutex
418 * The mutex to be uninitialized.
419 * @return Returns 0 upon successful completion
420 */
421
422int pthread_mutex_destroy(pthread_mutex_t *mutex){
423 pthread_mutex_t blank;
424
425 *mutex = blank;
426 return 0;
427}
428
429/**
430 * Initializes an condition with the default values defined for it by an implementation.
431 * Corresponding specification: p. 1630-32
432 *
433 * @param *cond
434 * The condition to be initialized.
435 * @param *arg
436 * Should be changed to condition attribute
437 * @return Returns 0 upon successful completion
438 */
439
440int pthread_cond_init(pthread_cond_t *cond, void *arg){
441 cond->proccount = 0;
442 cond->signal = 0;
443 return 0;
444}
445
446
447/**
448 * Uninitializes the specified cond variable.
449 * Corresponding specification: p. 1630-2
450 *
451 * @param *cond
452 * The condition to be uninitialized.
453 * @return Returns 0 upon successful completion
454 */
455
456int pthread_cond_destroy(pthread_cond_t *cond){
457 if(cond->proccount != 0){
458 $assert($false, "ERROR: Threads still waiting on specified condition variable");
459 }
460 else{
461 pthread_cond_t blank;
462 *cond = blank;
463 }
464 return 0;
465}
466
467/**
468 * Defines a pthread_t by assigning it an attribute value (by value so the original attribute's state is
469 * irrelevant), and spawning a process as the thr field with arguments void *arg
470 * Corresponding specification: p. 1649-51
471 *
472 * @param *thread
473 * The thread to be created with fields set from the other parameters.
474 * @param *attr
475 * The attribute to be assigned to the thread
476 * @param *startroutine
477 * The process to be spawned as the thread's actual 'thread'
478 * @param *arg
479 * The argument to be passed to the spawned function
480 *
481 * @return Returns 0 upon successful completion
482 */
483
484int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg){
485 $atomic{
486 thread->thr = $spawn start_routine(arg);
487 if(attr == NULL){
488 thread->attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
489 thread->attr->detachstate = 1;
490 thread->attr->inheritsched = 0;
491 thread->attr->contentionscope = 0;
492 thread->attr->schedpolicy = 0;
493 }
494 else{
495 thread->attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
496 thread->attr->detachstate = attr->detachstate;
497 thread->attr->inheritsched = attr->inheritsched;
498 thread->attr->contentionscope = attr->contentionscope;
499 thread->attr->schedpolicy = attr->schedpolicy;
500 }
501 _add_thread(&_pool, thread);
502 }
503 return 0;
504}
505
506/**
507 * Causes current thread to wait on thread specified as a parameter. If specified thread's detachstate field is set as PTHREAD_CREATE_DETACHED,
508 * error will be returned stating the the thread cannot be joined. The value_ptr of pthread_exit shall be passed to any joining thread to the
509 * terminated thread using pthread_join's value_ptr
510 * Corresponding specification: p. 1617-9
511 *
512 * @param thread
513 * The thread to be waited on by the current thread.
514 * @param **value_ptr
515 * The location at which the pthread_exit output is accessible
516 *
517 * @return Returns 0 upon successful completion
518 */
519
520int pthread_join(pthread_t thread, void **value_ptr){
521 if(thread.attr != NULL){
522 if(thread.attr->detachstate == 0){
523 $assert($false, "Thread is designated as unjoinable");
524 return 1;
525 }
526 }
527 $wait(thread.thr);
528 if(value_ptr!=NULL)
529 value_ptr = &value;
530 return 0;
531}
532
533/**
534 * Causes current thread to immediately terminate; if currently in the main method as specified by the
535 * isMain parameter, the main method will wait for each thread to terminate before it terminates. The value
536 * value_ptr will be made accessible in the location stated in pthread_join
537 * Corresponding specification: p. 1655-6
538 *
539 * @param *value_ptr
540 * The value to be stored in the location stated by pthread_join
541 * @param isMain
542 * Is this thread the main thread?
543 * @param *arr
544 * The array of threads which need to be waited upon by the main thread
545 * @param len
546 * The length of the array of threads to be waited upon
547 * @return Returns 0 upon successful completion
548 */
549
550int _pthread_exit(void *value_ptr, _Bool isMain){
551 if(isMain){
552 for(int i = 0; i<_pool.len; i++)
553 if($proc_defined(_pool.threads[i]->thr))
554 $wait(_pool.threads[i]->thr);
555 $exit();
556 return 0;
557 }
558 else{
559 value = value_ptr;
560 $exit();
561 return 0;
562 }
563}
564
565//Unimplemented
566int pthread_detach(pthread_t thread);
567
568/**
569 * Takes in a mutex variable and acts accordingly to its current state and type
570 * PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already locked and behaves accordingly
571 * locked and owner: Relock error, returns 0
572 * locked and not owner: Waits until mutex is unlocked and then locks and becomes owner
573 * unlocked and not owner: Locks the mutex and becomes owner
574 * PTHREAD_MUTEX_RECURSIVE: A recursive mutex increments its count when it is locked and decremented when
575 * it is unlocked and the lock is released when the count reaches 0.
576 * PTHREAD_MUTEX_ERRORCHECK: Implemented similarly to PTHREAD_MUTEX_NORMAL, but notifies the user of errors
577 * Corresponding specification: p. 1686-9
578 *
579 * @param *mutex
580 * The mutex to be locked
581 * @return Returns 0 upon successful completion, EOWNERDEAD upon termination of owner,
582 */
583
584/*
585int pthread_mutex_lock(pthread_mutex_t *mutex){
586 $choose{
587 $when((mutex->attr->type == PTHREAD_MUTEX_NORMAL || mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner == $proc_null && mutex->attr->robust == PTHREAD_MUTEX_ROBUST && mutex->lock == 0)
588 {
589 $atomic{
590 mutex->lock = 1;
591 mutex->count = 1;
592 mutex->owner = $self;
593 }
594 }
595 $when((mutex->attr->type == PTHREAD_MUTEX_NORMAL || mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner != $proc_null && mutex->owner != $self && mutex->lock == 0)
596 {
597 $atomic{
598 mutex->lock = 1;
599 mutex->count = 1;
600 mutex->owner = $self;
601 }
602 }
603 $when((mutex->attr->type != PTHREAD_MUTEX_NORMAL && mutex->attr->type != PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner != $self && mutex->owner != $proc_null && mutex->lock == 0)
604 {
605 $atomic{
606 mutex->lock = 1;
607 mutex->count = 1;
608 mutex->owner = $self;
609 }
610 }
611 $when((mutex->attr->type == PTHREAD_MUTEX_NORMAL || mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK) && mutex->lock == 0 && mutex->owner == $proc_null)
612 {
613 $atomic{
614 mutex->lock = 1;
615 mutex->count = 1;
616 mutex->owner = $self;
617 }
618 }
619 $when((mutex->attr->type == PTHREAD_MUTEX_NORMAL || mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner == $proc_null && mutex->attr->robust != PTHREAD_MUTEX_ROBUST)
620 {
621 $assert($false, "Owner terminated without releasing mutex and was not robust");
622 return EOWNERDEAD;
623 }
624 $when((mutex->attr->type == PTHREAD_MUTEX_NORMAL || mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner != $proc_null && mutex->owner== $self)
625 {
626 $assert($false, "Attempting to relock locked lock");
627 return EDEADLK;
628 }
629 $when((mutex->attr->type != PTHREAD_MUTEX_NORMAL && mutex->attr->type != PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner == $self)
630 {
631 mutex->count++;
632 }
633 $when((mutex->attr->type != PTHREAD_MUTEX_NORMAL && mutex->attr->type != PTHREAD_MUTEX_ERRORCHECK) && mutex->lock != 0 && mutex->owner != $self && mutex->owner == $proc_null && mutex->attr->robust != PTHREAD_MUTEX_ROBUST)
634 {
635 $assert($false, "Attempting to relock locked lock");
636 return EDEADLK;
637 }
638 }
639 return 0;
640}
641*/
642/**
643 * Takes in a mutex variable and acts similarly to pthread_mutex_lock except that
644 * if the mutex is locked, it will return immeditately. In the case of a recursive mutex, the count will
645 * be incremented and will return successfully.
646 * Corresponding specification: p. 1686-9
647 *
648 * @param *mutex
649 * The mutex to be locked
650 * @return Returns 0 upon successful completion
651 */
652
653int pthread_mutex_trylock(pthread_mutex_t *mutex){
654 $atomic{
655 if (mutex->attr->type == PTHREAD_MUTEX_NORMAL){
656 if (mutex->lock != 0) {
657 return EBUSY;
658 }
659 mutex->owner = $self;
660 mutex->lock = 1;
661 }
662 else {
663 int tmp = mutex->lock;
664
665 mutex->lock = 1;
666 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
667 mutex->count = 1;
668 mutex->owner = $self;
669 }
670 else {
671 //Checks for ownership, otherwise returns error
672 if(mutex->owner == $self){
673 // Checks for recursive mutex, otherwise returns an error
674 if (mutex->attr->type == PTHREAD_MUTEX_RECURSIVE) {
675 mutex->count++;
676 }
677 else {
678 $assert($false);
679 return 0;
680 }
681 }
682 else {
683 return EBUSY;
684 }
685 }
686 }
687 return 0;
688 }
689}
690
691/**
692 * Takes in a mutex variable and acts accordingly to its current state and type
693 * PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already unlocked and behaves accordingly
694 * unlocked: returns error
695 * locked: unlocks
696 * PTHREAD_MUTEX_RECURSIVE: A recursive mutex increments its count when it is locked and decremented when
697 * it is unlocked and the lock is released when the count reaches 0.
698 * PTHREAD_MUTEX_ERRORCHECK: Currently implemented similarly to PTHREAD_MUTEX_NORMAL
699 * Corresponding specification: p. 1686-9
700 *
701 * @param *mutex
702 * The mutex to be unlocked
703 * @return Returns 0 upon successful completion
704 */
705
706int pthread_mutex_unlock(pthread_mutex_t *mutex){
707 $atomic{
708 if (mutex->attr->type == 0 || mutex->attr->type == 2) {
709 // Attempts unlock, if already unlocked, returns error
710 if (mutex->lock == 0) {
711 $assert($false, "Attempting to unlock unlocked lock\n");
712 return 0;
713 }
714 else {
715 mutex->lock = 0;
716 mutex->owner = $proc_null;
717 }
718 }
719 else {
720 //Checks for ownership of thread, if not, returns error
721 if(mutex->owner == $self)
722 {
723 if (--mutex->count == 0){
724 mutex->lock = 0;
725 mutex->owner = $proc_null;
726 }
727 }
728 else {
729 $assert($false);
730 return 0;
731 }
732 }
733 return 0;
734 }
735}
736
737/**
738 * Checks for robustness of mutex: if robust, the mutex is unlocked, otherwise an error is caused
739 * and EINVAL is returned
740 * Corresponding specification: p. 1674-5
741 *
742 * @param *mutex
743 * The mutex to be marked as consistent
744 * @return Returns 0 upon successful completion, EINVAL upon non-robust mutex input
745 */
746
747int pthread_mutex_consistent(pthread_mutex_t *mutex){
748 if(mutex->attr->robust == PTHREAD_MUTEX_ROBUST){
749 mutex->lock = 0;
750 return 0;
751 }
752 $assert($false);
753 return EINVAL;
754}
755
756/**
757 * Checks for calling thread as owner of the mutex, then increments proccount, unlocks the mutex
758 * and sleeps. Awakens upon signal and decrements proccount and locks mutex.
759 * Corresponding specification: p. 1634-9
760 *
761 * @param *cond
762 * The condition to be waited upon until a signal is given
763 * @param *mutex
764 * The mutex used to lock other threads out
765 * @return Returns 0 upon successful completion, EINVAL upon non-robust mutex input
766 */
767
768int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex){
769 if(mutex->owner != $self){
770 printf("Mutex not owned by thread");
771 $assert($false);
772 return 0;
773 }
774
775 cond->proccount= cond->proccount+1;
776 pthread_mutex_unlock(mutex);
777
778 cond->signal = false;
779 $when(cond->signal);
780 cond->signal = false;
781 --cond->proccount;
782 $when(mutex->lock == 0){pthread_mutex_lock(mutex);}
783 return 0;
784}
785
786/**
787 * Signals the condition by setting the signal to true
788 * Corresponding specification: p. 1627-30
789 *
790 * @param *cond
791 * The condition to be signalled
792 * @return Returns 0 upon successful completion
793 */
794
795int pthread_cond_signal(pthread_cond_t *cond){
796 cond->signal = true;
797 return 0;
798}
799
800/**
801 * Repeated signals the condition until all processes waiting have been signalled and awoken
802 * Corresponding specification: p. 1627-30
803 *
804 * @param *cond
805 * The condition to be signalled repeatedly
806 * @return Returns 0 upon successful completion
807 */
808
809int pthread_cond_broadcast(pthread_cond_t *cond){
810 while(cond->proccount > 0){
811 cond->signal = true;
812 }
813 return 0;
814}
Note: See TracBrowser for help on using the repository browser.