source: doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/pthread.hpp @ d4da688

arm-ehjacob/cs343-translationnew-ast-unique-expr
Last change on this file since d4da688 was d4da688, checked in by Thierry Delisle <tdelisle@…>, 14 months ago

Some renaming to move away from dlopen in toy program

  • Property mode set to 100644
File size: 2.1 KB
Line 
1#include <pthread.h>
2#include <errno.h>
3#include <cstring>
4#include <cstdio>
5#include <iostream>
6
7#define CHECKED(x) { int err = x; if( err != 0 ) { std::cerr << "KERNEL ERROR: Operation \"" #x "\" return error " << err << " - " << strerror(err) << std::endl; std::abort(); } }
8
9struct __bin_sem_t {
10        pthread_mutex_t         lock;
11        pthread_cond_t          cond;
12        int                     val;
13
14        __bin_sem_t() {
15                // Create the mutex with error checking
16                pthread_mutexattr_t mattr;
17                pthread_mutexattr_init( &mattr );
18                pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP);
19                pthread_mutex_init(&lock, &mattr);
20
21                pthread_cond_init (&cond, nullptr);
22                val = 0;
23        }
24
25        ~__bin_sem_t() {
26                CHECKED( pthread_mutex_destroy(&lock) );
27                CHECKED( pthread_cond_destroy (&cond) );
28        }
29
30        void wait() {
31                CHECKED( pthread_mutex_lock(&lock) );
32                        while(val < 1) {
33                                pthread_cond_wait(&cond, &lock);
34                        }
35                        val -= 1;
36                CHECKED( pthread_mutex_unlock(&lock) );
37        }
38
39        bool post() {
40                bool needs_signal = false;
41
42                CHECKED( pthread_mutex_lock(&lock) );
43                        if(val < 1) {
44                                val += 1;
45                                pthread_cond_signal(&cond);
46                                needs_signal = true;
47                        }
48                CHECKED( pthread_mutex_unlock(&lock) );
49
50                return needs_signal;
51        }
52};
53
54#undef CHECKED
55
56//--------------------
57// Basic types
58struct pthread_runner_t {
59        pthread_t handle;
60        __bin_sem_t sem;
61};
62typedef pthread_runner_t * thread_t;
63
64static_assert(sizeof(thread_t) == sizeof(void*), "thread_t musst be of same size as void*");
65
66extern "C" {
67        //--------------------
68        // Basic thread support
69        thread_t thrdlib_create( void (*main)( thread_t ) ) {
70                thread_t thrd = new pthread_runner_t();
71                int r = pthread_create( &thrd->handle, nullptr, (void *(*)(void *))main, thrd );
72                if( r != 0 ) std::abort();
73                return thrd;
74        }
75
76        void thrdlib_join( thread_t handle ) {
77                void * ret;
78                int r = pthread_join( handle->handle, &ret );
79                if( r != 0 ) std::abort();
80                delete handle;
81        }
82
83        void thrdlib_park( thread_t handle ) {
84                handle->sem.wait();
85        }
86
87        void thrdlib_unpark( thread_t handle ) {
88                handle->sem.post();
89        }
90
91        void thrdlib_yield( void ) {
92                int r = pthread_yield();
93                if( r != 0 ) std::abort();
94        }
95
96        //--------------------
97        // Basic kernel features
98        void thrdlib_init( int ) {}
99}
Note: See TracBrowser for help on using the repository browser.