source: CIVL/text/include/pthread.cvh@ 1a54e12

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

Changed location of pthread.cvh, and updated files to use pthread.h (which includes pthread.cvh). New translations from pthread-atomic, and updated pthread.cvh

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

  • Property mode set to 100644
File size: 30.2 KB
RevLine 
[7c7ed59]1/*
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.
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
11#include <civlc.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <assert.h>
15#include <stdbool.h>
16
17//Mutex types
[8d512ae]18enum{
19PTHREAD_MUTEX_NORMAL,
20PTHREAD_MUTEX_RECURSIVE,
21PTHREAD_MUTEX_ERRORCHECK
22};
23
24enum{
25PTHREAD_MUTEX_STALLED,
26PTHREAD_MUTEX_ROBUST
27};
28
29enum{
30PTHREAD_CREATE_DETACHED,
31PTHREAD_CREATE_JOINABLE
32};
33
34enum{
35PTHREAD_SCOPE_SYSTEM,
36PTHREAD_SCOPE_PROCESS
37};
38
39enum{
40PTHREAD_INHERIT_SCHED,
41PTHREAD_EXPLICIT_SCHED
42};
[7c7ed59]43
44//Mutex initializer
45#define __LOCK_INITIALIZER 0
46#define PTHREAD_MUTEX_INITIALIZER {0,0,0,PTHREAD_MUTEX_NORMAL,__LOCK_INITIALIZER}
47#define PTHREAD_COND_INITIALIZER {__LOCK_INITIALIZER,0}
48
49//Error definitions
[8d512ae]50enum{
51EINVAL, //Designates an invalid value
52ENOTSUP,
53EOWNERDEAD, //Designates the termination of the owning thread
54EBUSY, //Mutex is already locked
55EDEADLK, //If mutex type is errorcheck and already owns the mutex
56EPERM //If mutex is robust or errorcheck and does not own the mutex
57};
[7c7ed59]58
59extern void *value = NULL;
60
61
62/* Struct definitions */
63
64/* pthread_attr_t struct definition
65 Description: This struct corresponds to the pthread_attr_t which is the attribute of a pthread_t. It's fields
66 define the way the pthread_t is able to interact (join/detach), (memory capacity), (scope) etc.
67
68 Fields: void * stackaddr: The address of the attr's stack in memory
69 size_t stacksize: The memory capacity for the attr's stack
70 size_t guardsize: The guardsize attribute controls the size of the guard area for the created thread' stack. The
71 guardsize attribute provides protection against overflow of the stack pointer.
72 int detachstate: Defines a threads ability to join with two values: PTHREAD_CREATE_DETACHED and PTHREAD_CREATE_JOINABLE
73 int inheritsched: The inheritance scheduling policy of the thread
74 int contentionscope: Defines the contention scope of the thread
75 int schedpolicy: Determines the scheduling policy of the thread
76
77*/
78
79typedef struct {
80 void *stackaddr;
81 size_t stacksize;
82 size_t guardsize;
83 int detachstate;
84 int inheritsched;
85 int contentionscope;
86 int schedpolicy;
87} pthread_attr_t;
88
89/* pthread_mutexattr_t struct definition
90 Description: The pthread_mutexattr_t defines multiple attributes of a mutex and controls its interactions with threads
91 Fields: robust: defines the robustness of the mutex; if robust and the owning thread terminates, it will notify the
92 next thread of this to prevent deadlocks and other errors
93 pshared: defines the process shared element of the thread and which processes can interact with the mutex
94 protocol: defines the priority protocol of the mutex and which threads may interact first
95 type: defines the type of the mutex as either PTHREAD_MUTEX_DEFAULT/NORMAL, PTHREAD_MUTEX_ERRORCHECK, or
96 PTHREAD_MUTEX_RECURSIVE, each explained in pthread_mutex_lock below
97 prioceiling: defines the lowest priority the mutex's critical section can be at
98*/
99
100typedef struct {
101 int robust;
102 int pshared;
103 int protocol;
104 int type;
105 int prioceiling;
106}pthread_mutexattr_t;
107
108/* pthread_mutex_t struct definition
109 Description: The pthread_mutex_t is a locking mechanism for threads to interact with in order to control the scheduling
110 of the threads. It can be locked, which allows for blocking of other threads waiting on the mutex and unlocked, allowing
111 access. It has a pthread_mutexattr_t which defines its behavior.
112 Fields: count - used for recursive mutex, incremented when locked, decremented when unlocked, mutex released when count is 0
113 owner - current process owner of the mutex
114 lock - int of 0 or 1, respectively 0 if unlocked, 1 if locked
115 prioceiling - allows locking without adherence to the priority ceiling
116 attr - see above
117*/
118
119typedef struct {
120 int count;
121 $proc owner;
122 int lock;
123 int prioceiling;
124 pthread_mutexattr_t *attr;
125} pthread_mutex_t;
126
127//Unimplemented
128/*
129typedef struct {
130 int pshared;
131 clockid_t clock_id;
132}pthread_condattr_t;
133*/
134
135/* pthread_cond_t struct definition
136 Description: The pthread_cond_t is another locking mechanism which interacts with the mutex variable. When
137 the mutex is locked, the condition can be accessed, leading the accessing thread to unlock it, and sleep
138 until the signal is given
139 Fields: proccount - specifies the number of processes/threads still waiting on this condition variable
140 signal - Boolean value stating whether the condition is satisfied (indicated by 1) or not (0)
141*/
142
143typedef struct {
144 int proccount;
145 _Bool signal;
146} pthread_cond_t;
147
148/* pthread_t struct definition
149 Description: The pthread_t is a struct containing a $proc variable as well as a thread attribute which defines
150 its interactions with other threads. It encapsulates the $proc and allows attributes to apply to it.
151 Fields: thr: the $proc variable that is the heart of the thread
152 attr: see above
153*/
154
155typedef struct {
156 $proc thr;
157 const pthread_attr_t *attr;
158} pthread_t;
159
160/**
161 * Initializes an attribute with the default values defined for it by an implementation.
162 * Corresponding specification: p. 1532-4
163 *
164 * @param *attr
165 * The attribute to be initialized.
166 * @return Returns 0 upon successful completion
167 */
168
169int pthread_attr_init(pthread_attr_t *attr){
170 attr->stacksize = 0;
171 attr->guardsize = 0;
172 attr->detachstate = PTHREAD_CREATE_DETACHED;
173 //attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
174 attr->contentionscope = PTHREAD_SCOPE_SYSTEM;
175 attr->stackaddr = NULL;
176 //attr->schedpolicy = SCHED_OTHER;
177 return 0;
178}
179
180/**
181 * Uninitializes the specified attr variable.
182 * Corresponding specification: p. 1532-4
183 *
184 * @param *attr
185 * The attribute to be uninitialized.
186 * @return Returns 0 upon successful completion
187 */
188
189int pthread_attr_destroy(pthread_attr_t *attr)
190{
191 pthread_attr_t blank;
192
193 *attr = blank;
194 return 0;
195}
196
197
198/**
199 * Sets the detachstate field of the attribute
200 * Corresponding specification: p. 1535-6
201 *
202 * @param *attr
203 * The attribute to have it's detachstate set
204 * @param detachstate
205 * The detachstate to which the attribute's detachstate is set
206 * @return Returns 0 upon successful completion
207 */
208
209int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
210{
211 attr->detachstate = detachstate;
212 return 0;
213}
214
215/**
216 * Stores the detachstate value of the attribute in an alternate location
217 * Corresponding specification: p. 1535-6
218 *
219 * @param *attr
220 * The attribute whose detachstate is to be stored
221 * @param *detachstate
222 * The location at which the detachstate is to be stored
223 * @return Returns 0 upon successful completion
224 */
225
226int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
227{
228 *detachstate = attr->detachstate;
229 return 0;
230}
231
232/**
233 * Set scheduling inheritance
234 * Corresponding specification: p. 1540-1
235 *
236 * @param *attr
237 * The attribute to have it's inheritsched set
238 * @param inheritsched
239 * The inheritsched to which the attribute's inheritsched is set
240 * @return Returns 0 upon successful completion
241 */
242
243int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
244{
245 attr->inheritsched = inheritsched;
246 return 0;
247}
248
249/**
250 * Stores the inheritsched value of the attribute in an alternate location
251 * Corresponding specification: p. 1540-1
252 *
253 * @param *attr
254 * The attribute whose inheritsched is to be stored
255 * @param *intheritsched
256 * The location at which the attribute's inheritsched is to be stored
257 * @return Returns 0 upon successful completion
258 */
259
260int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
261{
262 *inheritsched = attr->inheritsched;
263 return 0;
264}
265
266/**
267 * Set contentionscope field of the attribute
268 * Corresponding specification: p. 1546-7
269 *
270 * @param *attr
271 * The attribute to have it's contentionscope set
272 * @param contentionscope
273 * The contentionscope to which the attribute's contentionscope is set
274 * @return Returns 0 upon successful completion
275 */
276
277int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope)
278{
279 attr->contentionscope = contentionscope;
280 return 0;
281}
282
283/**
284 * Stores the contentionscope value of the attribute in an alternate location
285 * Corresponding specification: p. 1546-7
286 *
287 * @param *attr
288 * The attribute whose contentionscope is to be stored
289 * @param *contentionscope
290 * The location at which the attribute's contentionscope is to be stored
291 * @return Returns 0 upon successful completion
292 */
293
294int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope)
295{
296 *contentionscope = attr->contentionscope;
297 return 0;
298}
299
300
301/**
302 * Sets the stack address and stacksize fields of the attribute
303 * Corresponding specification: p. 1548-50
304 *
305 * @param *attr
306 * The attribute to have it's stack address and stack size set
307 * @param *stackaddr
308 * The address to which the attribute's stack address is set
309 * @param stacksize
310 * The size to which the attribute's stack size is set
311 * @return Returns 0 upon successful completion
312 */
313
314int pthread_attr_setstack(pthread_attr_t *attr, void * stackaddr, size_t stacksize){
315 attr->stackaddr = stackaddr;
316 attr->stacksize = stacksize;
317 return 0;
318}
319
320/**
321 * Stores the stack address and size values in alternate locations
322 * Corresponding specification: p. 1548-50
323 *
324 * @param *attr
325 * The attribute whose stack address and size are to be stored
326 * @param **stackaddr
327 * The location at which the attribute's stackaddr is to be stored
328 * @param *stacksize
329 * The location at which the attribute's stacksize is to be stored
330 * @return Returns 0 upon successful completion
331 */
332// Get the stack size and stack address of the specified pthread_attr_t
333// Corresponding specification p.1548
334int pthread_attr_getstack(const pthread_attr_t *attr, void ** stackaddr, size_t *stacksize)
335{
336 *stackaddr = attr->stackaddr;
337 *stacksize = attr->stacksize;
338 return 0;
339}
340
341/**
342 * Sets the guardsize field of the attribute
343 * Corresponding specification: p. 1537-9
344 *
345 * @param *attr
346 * The attribute to have it's guardsize set
347 * @param guardsize
348 * The guardsize to which the attribute's guardsize is set
349 * @return Returns 0 upon successful completion
350 */
351
352int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
353{
354 attr->guardsize = guardsize;
355 return 0;
356}
357
358/**
359 * Stores the guardsize value in an alternate location
360 * Corresponding specification: p. 1537-9
361 *
362 * @param *attr
363 * The attribute whose guardsize is to be stored
364 * @param *guardsize
365 * The location at which the attribute's guardsize is to be stored
366 * @return Returns 0 upon successful completion
367 */
368
369int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
370{
371 *guardsize = attr->guardsize;
372 return 0;
373}
374
375/**
376 * Sets the scheduling policy field of the attribute
377 * Corresponding specification: p. 1544-45
378 *
379 * @param *attr
380 * The attribute to have it's scheduling policy set
381 * @param policy
382 * The scheduling policy to which the attribute's scheduling policy is set
383 * @return Returns 0 upon successful completion
384 */
385
386int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
387{
388 attr->schedpolicy = policy;
389 return 0;
390}
391
392/**
393 * Stores the scheduling policy value in an alternate location
394 * Corresponding specification: p. 1544-45
395 *
396 * @param *attr
397 * The attribute whose scheduling policy is to be stored
398 * @param *policy
399 * The location at which the attribute's scheduling policy is to be stored
400 * @return Returns 0 upon successful completion
401 */
402
403int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
404{
405 *policy = attr->schedpolicy;
406 return 0;
407}
408
409/**
410 * Initializes an attribute with the default values defined for it by an implementation.
411 * Corresponding specification: p. 1647-51
412 *
413 * @param *attr
414 * The attribute to be initialized.
415 * @return Returns 0 upon successful completion
416 */
417
418int pthread_mutexattr_init(pthread_mutexattr_t *attr){
419 attr->robust = 0;
420 attr->pshared = 0;
421 attr->protocol = 0;
422 attr->type = 0;
423 attr->prioceiling = 0;
424 return 0;
425}
426
427/**
428 * Uninitializes the specified attr variable.
429 * Corresponding specification: p. 1647-51
430 *
431 * @param *attr
432 * The attribute to be uninitialized.
433 * @return Returns 0 upon successful completion
434 */
435
436int pthread_mutexattr_destroy(pthread_mutexattr_t *attr){
437 pthread_mutexattr_t blank;
438
439 *attr = blank;
440 return 0;
441}
442
443/**
444 * Stores the robustness value in an alternate location
445 * Corresponding specification: p. 1659-1660
446 *
447 * @param *attr
448 * The attribute whose robustness is to be stored
449 * @param *robust
450 * The location at which the attribute's robustness is to be stored
451 * @return Returns 0 upon successful completion
452 */
453
454int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr, int *robust){
455 *robust = attr->robust;
456 return 0;
457}
458
459/**
460 * Sets the robustness field of the attribute
461 * Corresponding specification: p. 1659-1660
462 *
463 * @param *attr
464 * The attribute to have it's robustness set
465 * @param robust
466 * The robustness to which the attribute's robustness is set
467 * @return Returns 0 upon successful completion
468 */
469
470int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust){
471 attr->robust = robust;
472 return 0;
473}
474
475/**
476 * Stores the process shared variable in an alternate location
477 * Corresponding specification: p. 1657-8
478 *
479 * @param *attr
480 * The attribute whose process shared variable is to be stored
481 * @param *detachstate
482 * The location at which the attribute's process shared variable is to be stored
483 * @return Returns 0 upon successful completion
484 */
485
486int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared){
487 *pshared = attr->pshared;
488 return 0;
489}
490
491/**
492 * Sets the process shared variable field of the attribute
493 * Corresponding specification: p. 1657-8
494 *
495 * @param *attr
496 * The attribute to have it's process shared variable set
497 * @param detachstate
498 * The process shared variable to which the attribute's process shared variable is set
499 * @return Returns 0 upon successful completion
500 */
501
502int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared){
503 attr->pshared = pshared;
504 return 0;
505}
506
507/**
508 * Stores the protocol value in an alternate location
509 * Corresponding specification: p. 1654-56
510 *
511 * @param *attr
512 * The attribute whose protocol is to be stored
513 * @param *detachstate
514 * The location at which the attribute's protocol is to be stored
515 * @return Returns 0 upon successful completion
516 */
517
518int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *protocol){
519 *protocol = attr->protocol;
520 return 0;
521}
522
523/**
524 * Sets the protocol field of the attribute
525 * Corresponding specification: p. 1654-56
526 *
527 * @param *attr
528 * The protocol to have it's protocol set
529 * @param detachstate
530 * The protocol to which the attribute's protocol is set
531 * @return Returns 0 upon successful completion
532 */
533int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol){
534 attr->protocol = protocol;
535 return 0;
536}
537
538/**
539 * Stores the type value in an alternate location
540 * Corresponding specification: p. 1709-10
541 *
542 * @param *attr
543 * The attribute whose type is to be stored
544 * @param *detachstate
545 * The location at which the attribute's type is to be stored
546 * @return Returns 0 upon successful completion
547 */
548int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type){
549 *type = attr->type;
550 return 0;
551}
552
553/**
554 * Sets the type field of the attribute
555 * Corresponding specification: p. 1709-10
556 *
557 * @param *attr
558 * The attribute to have it's type set
559 * @param detachstate
560 * The type to which the attribute's type is set
561 * @return Returns 0 upon successful completion
562 */
563int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type){
564 attr->type = type;
565 return 0;
566}
567
568/**
569 * Stores the priority ceiling value in an alternate location
570 * Corresponding specification: p. 1700-1
571 *
572 * @param *attr
573 * The attribute whose priority ceiling is to be stored
574 * @param *detachstate
575 * The location at which the attribute's priority ceiling is to be stored
576 * @return Returns 0 upon successful completion
577 */
578
579int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *prioceiling){
580 *prioceiling = attr->prioceiling;
581 return 0;
582}
583
584/**
585 * Sets the priority ceiling field of the attribute
586 * Corresponding specification: p. 1700-1
587 *
588 * @param *attr
589 * The attribute to have it's priority ceiling set
590 * @param detachstate
591 * The priority ceiling to which the attribute's priority ceiling is set
592 * @return Returns 0 upon successful completion
593 */
594
595int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling){
596 attr->prioceiling = prioceiling;
597 return 0;
598}
599
600
601/**
602 * Initializes a mutex with the default values defined for it by an implementation
603 * or with the values defined by the mutex attribute parameter
604 * Corresponding specification: p. 1676-81
605 *
606 * @param *mutex
607 * The mutex to be initialized.
608 * @param *attr
609 * The mutex attribute which the mutex shall take as it's field. May also
610 * be null for default values to be initialized.
611 * @return Returns 0 upon successful completion
612 */
613
614int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr){
615 if(attr == NULL){
616 mutex->attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
617 mutex->attr->robust = 0;
618 mutex->attr->pshared = 0;
619 mutex->attr->protocol = 0;
[8d512ae]620 mutex->attr->type = PTHREAD_MUTEX_NORMAL;
[7c7ed59]621 mutex->attr->prioceiling = 0;
622 }
623 else{
624 mutex->attr = (pthread_mutexattr_t *)malloc(sizeof(pthread_mutexattr_t));
625 mutex->attr = attr;
626 }
627 mutex->lock = 0;
628 mutex->count = 0;
629 mutex->owner = $proc_null;
630 return 0;
631}
632
633/**
634 * Uninitializes the specified mutex variable.
635 * Corresponding specification: p. 1676-81
636 *
637 * @param *mutex
638 * The mutex to be uninitialized.
639 * @return Returns 0 upon successful completion
640 */
641
642int pthread_mutex_destroy(pthread_mutex_t *mutex){
643 pthread_mutex_t blank;
644
645 *mutex = blank;
646 return 0;
647}
648
649/**
650 * Initializes an condition with the default values defined for it by an implementation.
651 * Corresponding specification: p. 1630-32
652 *
653 * @param *cond
654 * The condition to be initialized.
655 * @param *arg
656 * Should be changed to condition attribute
657 * @return Returns 0 upon successful completion
658 */
659
660int pthread_cond_init(pthread_cond_t *cond, void *arg){
661 cond->proccount = 0;
662 cond->signal = 0;
663 return 0;
664}
665
666
667/**
668 * Uninitializes the specified cond variable.
669 * Corresponding specification: p. 1630-2
670 *
671 * @param *cond
672 * The condition to be uninitialized.
673 * @return Returns 0 upon successful completion
674 */
675
676int pthread_cond_destroy(pthread_cond_t *cond){
677 if(cond->proccount != 0){
678 $assert($false, "ERROR: Threads still waiting on specified condition variable");
679 }
680 else{
681 pthread_cond_t blank;
682 *cond = blank;
683 }
684 return 0;
685}
686
687/**
688 * Defines a pthread_t by assigning it an attribute value (by value so the original attribute's state is
689 * irrelevant), and spawning a process as the thr field with arguments void *arg
690 * Corresponding specification: p. 1649-51
691 *
692 * @param *thread
693 * The thread to be created with fields set from the other parameters.
694 * @param *attr
695 * The attribute to be assigned to the thread
696 * @param *startroutine
697 * The process to be spawned as the thread's actual 'thread'
698 * @param *arg
699 * The argument to be passed to the spawned function
700 *
701 * @return Returns 0 upon successful completion
702 */
703
704int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg){
705 thread->thr = $spawn start_routine(arg);
706 if(attr == NULL){
707 thread->attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
708 thread->attr->stackaddr = NULL;
709 thread->attr->stacksize = 0;
710 thread->attr->guardsize = 0;
711 thread->attr->detachstate = 1;
712 thread->attr->inheritsched = 0;
713 thread->attr->contentionscope = 0;
714 thread->attr->schedpolicy = 0;
715 }
716 else{
717 thread->attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
718 thread->attr->stackaddr = attr->stackaddr;
719 thread->attr->stacksize = attr->stacksize;
720 thread->attr->guardsize = attr->guardsize;
721 thread->attr->detachstate = attr->detachstate;
722 thread->attr->inheritsched = attr->inheritsched;
723 thread->attr->contentionscope = attr->contentionscope;
724 thread->attr->schedpolicy = attr->schedpolicy;
725 }
726 return 0;
727}
728
729/**
730 * Causes current thread to wait on thread specified as a parameter. If specified thread's detachstate field is set as PTHREAD_CREATE_DETACHED,
731 * 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
732 * terminated thread using pthread_join's value_ptr
733 * Corresponding specification: p. 1617-9
734 *
735 * @param thread
736 * The thread to be waited on by the current thread.
737 * @param **value_ptr
738 * The location at which the pthread_exit output is accessible
739 *
740 * @return Returns 0 upon successful completion
741 */
742
743int pthread_join(pthread_t thread, void **value_ptr){
744 if(thread.attr != NULL){
745 if(thread.attr->detachstate == 0){
746 $assert($false, "Thread is designated as unjoinable");
747 return 1;
748 }
749 }
750 $wait(thread.thr);
[8d512ae]751 if(value_ptr!=NULL)
[7c7ed59]752 value_ptr = &value;
753 return 0;
754}
755
756/**
757 * Causes current thread to immediately terminate; if currently in the main method as specified by the
758 * isMain parameter, the main method will wait for each thread to terminate before it terminates. The value
759 * value_ptr will be made accessible in the location stated in pthread_join
760 * Corresponding specification: p. 1655-6
761 *
762 * @param *value_ptr
763 * The value to be stored in the location stated by pthread_join
764 * @param isMain
765 * Is this thread the main thread?
766 * @param *arr
767 * The array of threads which need to be waited upon by the main thread
768 * @param len
769 * The length of the array of threads to be waited upon
770 * @return Returns 0 upon successful completion
771 */
772
773int pthread_exit(void *value_ptr, _Bool isMain, pthread_t *arr, int len){
774 if(isMain){
775 for(int i = 0; i<len; i++)
776 $wait(arr[i].thr);
777 $exit();
778 return 0;
779 }
780 else{
781 value = value_ptr;
782 $exit();
783 return 0;
784 }
785}
786
787//Unimplemented
788int pthread_detach(pthread_t thread);
789
790/**
791 * Takes in a mutex variable and acts accordingly to its current state and type
792 * PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already locked and behaves accordingly
793 * locked and owner: Relock error, returns 0
794 * locked and not owner: Waits until mutex is unlocked and then locks and becomes owner
795 * unlocked and not owner: Locks the mutex and becomes owner
796 * PTHREAD_MUTEX_RECURSIVE: A recursive mutex increments its count when it is locked and decremented when
797 * it is unlocked and the lock is released when the count reaches 0.
798 * PTHREAD_MUTEX_ERRORCHECK: Implemented similarly to PTHREAD_MUTEX_NORMAL, but notifies the user of errors
799 * Corresponding specification: p. 1686-9
800 *
801 * @param *mutex
802 * The mutex to be locked
803 * @return Returns 0 upon successful completion, EOWNERDEAD upon termination of owner,
804 */
805
806int pthread_mutex_lock(pthread_mutex_t *mutex){
807 $atomic{
808 if (mutex->attr->type == PTHREAD_MUTEX_NORMAL){
809 if (mutex->lock != 0) {
810 if(mutex->owner == $proc_null){
811 if(mutex->attr->robust == PTHREAD_MUTEX_ROBUST){
812 $when(mutex->lock == 0);
813 }
814 else{
815 $assert($false);
816 return EOWNERDEAD;
817 }
818 }
819 else{
820 if(mutex->owner == $self){
821 $assert($false);
822 return 0;
823 }
824 else{
825 $when(mutex->lock == 0);
826 }
827 }
828 }
829 mutex->owner = $self;
830 mutex->lock = 1;
831 }
832 else {
833 int tmp = mutex->lock;
834
835 mutex->lock = 1;
836 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
837 mutex->count = 1;
838 mutex->owner = $self;
839 }
840 else {
841 //Checks for ownership, otherwise returns error
842 if(mutex->owner == $self){
843 // Checks for recursive mutex, otherwise returns an error
844 if (mutex->attr->type == PTHREAD_MUTEX_RECURSIVE) {
845 mutex->count++;
846 }
847 else {
848 $assert($false);
849 return 0;
850 }
851 }
852 else {
853 $assert($false, "ERROR: Relock attempted on non-recursive mutex\n");
854 return 0;
855 }
856 }
857 }
858 return 0;
859 }
860}
861
862/**
863 * Takes in a mutex variable and acts similarly to pthread_mutex_lock except that
864 * if the mutex is locked, it will return immeditately. In the case of a recursive mutex, the count will
865 * be incremented and will return successfully.
866 * Corresponding specification: p. 1686-9
867 *
868 * @param *mutex
869 * The mutex to be locked
870 * @return Returns 0 upon successful completion
871 */
872
873int pthread_mutex_trylock(pthread_mutex_t *mutex){
874 $atomic{
875 if (mutex->attr->type == PTHREAD_MUTEX_NORMAL){
876 if (mutex->lock != 0) {
877 return EBUSY;
878 }
879 mutex->owner = $self;
880 mutex->lock = 1;
881 }
882 else {
883 int tmp = mutex->lock;
884
885 mutex->lock = 1;
886 if (tmp == 0) { // Attempts lock and checks for whether lock is already locked
887 mutex->count = 1;
888 mutex->owner = $self;
889 }
890 else {
891 //Checks for ownership, otherwise returns error
892 if(mutex->owner == $self){
893 // Checks for recursive mutex, otherwise returns an error
894 if (mutex->attr->type == PTHREAD_MUTEX_RECURSIVE) {
895 mutex->count++;
896 }
897 else {
898 $assert($false);
899 return 0;
900 }
901 }
902 else {
903 return EBUSY;
904 }
905 }
906 }
907 return 0;
908 }
909}
910
911/**
912 * Takes in a mutex variable and acts accordingly to its current state and type
913 * PTHREAD_MUTEX_NORMAL: Checks to see whether mutex is already unlocked and behaves accordingly
914 * unlocked: returns error
915 * locked: unlocks
916 * PTHREAD_MUTEX_RECURSIVE: A recursive mutex increments its count when it is locked and decremented when
917 * it is unlocked and the lock is released when the count reaches 0.
918 * PTHREAD_MUTEX_ERRORCHECK: Currently implemented similarly to PTHREAD_MUTEX_NORMAL
919 * Corresponding specification: p. 1686-9
920 *
921 * @param *mutex
922 * The mutex to be unlocked
923 * @return Returns 0 upon successful completion
924 */
925
926int pthread_mutex_unlock(pthread_mutex_t *mutex){
927 $atomic{
928 if (mutex->attr->type == 0 || mutex->attr->type == 2) {
929 int idx;
930
931 // Attempts unlock, if already unlocked, returns error
[8d512ae]932 if (mutex->lock == 0 && mutex->attr->type == PTHREAD_MUTEX_NORMAL) {
[7c7ed59]933 $assert($false);
934 return 0;
935 }
936 else if (mutex->lock == 0 && mutex->attr->type == PTHREAD_MUTEX_ERRORCHECK){
937 $assert($false, "Attempting to unlock unlocked lock\n");
938 return 0;
939 }
940 else {
941 mutex->lock = 0;
942 mutex->owner = $proc_null;
943 }
944 }
945 else {
946 //Checks for ownership of thread, if not, returns error
947 if(mutex->owner == $self)
948 {
949 //Checks for recursive mutex
950 _Bool tmp = !(mutex->attr->type == 1);
951
952 if (--mutex->count == 0){
953 mutex->lock = 0;
954 mutex->owner = $proc_null;
955 }
956 }
957 else {
958 $assert($false);
959 return 0;
960 }
961 }
962 return 0;
963 }
964}
965
966/**
967 * Checks for robustness of mutex: if robust, the mutex is unlocked, otherwise an error is caused
968 * and EINVAL is returned
969 * Corresponding specification: p. 1674-5
970 *
971 * @param *mutex
972 * The mutex to be marked as consistent
973 * @return Returns 0 upon successful completion, EINVAL upon non-robust mutex input
974 */
975
976int pthread_mutex_consistent(pthread_mutex_t *mutex){
977 if(mutex->attr->robust == PTHREAD_MUTEX_ROBUST){
978 mutex->lock = 0;
979 return 0;
980 }
981 $assert($false);
982 return EINVAL;
983}
984
985/**
986 * Checks for calling thread as owner of the mutex, then increments proccount, unlocks the mutex
987 * and sleeps. Awakens upon signal and decrements proccount and locks mutex.
988 * Corresponding specification: p. 1634-9
989 *
990 * @param *cond
991 * The condition to be waited upon until a signal is given
992 * @param *mutex
993 * The mutex used to lock other threads out
994 * @return Returns 0 upon successful completion, EINVAL upon non-robust mutex input
995 */
996
997int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex){
998 if(mutex->owner != $self){
999 printf("Mutex not owned by thread");
1000 $assert($false);
1001 return 0;
1002 }
1003
1004 cond->proccount= cond->proccount+1;
1005 pthread_mutex_unlock(mutex);
1006
1007 $when(cond->signal);
1008 cond->signal = false;
1009 --cond->proccount;
1010 $when(mutex->lock == 0){pthread_mutex_lock(mutex);}
1011 return 0;
1012}
1013
1014/**
1015 * Signals the condition by setting the signal to true
1016 * Corresponding specification: p. 1627-30
1017 *
1018 * @param *cond
1019 * The condition to be signalled
1020 * @return Returns 0 upon successful completion
1021 */
1022
1023int pthread_cond_signal(pthread_cond_t *cond){
1024 cond->signal = true;
1025 return 0;
1026}
1027
1028/**
1029 * Repeated signals the condition until all processes waiting have been signalled and awoken
1030 * Corresponding specification: p. 1627-30
1031 *
1032 * @param *cond
1033 * The condition to be signalled repeatedly
1034 * @return Returns 0 upon successful completion
1035 */
1036
1037int pthread_cond_broadcast(pthread_cond_t *cond){
1038 while(cond->proccount > 0){
1039 cond->signal = true;
1040 }
1041 return 0;
1042}
1043
1044
1045
1046
1047
Note: See TracBrowser for help on using the repository browser.