Do not allow a thread to stash the next pending action if its last action was a SLEEP...
[c11tester.git] / threads-model.h
index 733d825f243ea5ea32a1bde878f37c97448f77b2..f2162a89e55752ffde61e74ebf3f0c675584d4ba 100644 (file)
@@ -6,12 +6,13 @@
 #define __THREADS_MODEL_H__
 
 #include <stdint.h>
-
 #include "mymemory.h"
-#include <threads.h>
+#include "threads.h"
 #include "modeltypes.h"
 #include "stl-model.h"
 #include "context.h"
+#include "classlist.h"
+#include "pthread.h"
 
 struct thread_params {
        thrd_start_t func;
@@ -35,13 +36,14 @@ typedef enum thread_state {
        THREAD_COMPLETED
 } thread_state;
 
-class ModelAction;
 
 /** @brief A Thread is created for each user-space thread */
 class Thread {
 public:
        Thread(thread_id_t tid);
        Thread(thread_id_t tid, thrd_t *t, void (*func)(void *), void *a, Thread *parent);
+       Thread(thread_id_t tid, thrd_t *t, void *(*func)(void *), void *a, Thread *parent);
+
        ~Thread();
        void complete();
 
@@ -72,6 +74,10 @@ public:
         */
        uint64_t get_return_value() const { return last_action_val; }
 
+       /** @set and get the return value from pthread functions */
+       void set_pthread_return(void *ret) { pthread_return = ret; }
+       void * get_pthread_return() { return pthread_return; }
+
        /** @return True if this thread is finished executing */
        bool is_complete() const { return state == THREAD_COMPLETED; }
 
@@ -87,12 +93,20 @@ public:
         *  @see Thread::pending */
        void set_pending(ModelAction *act) { pending = act; }
 
+       bool just_woken_up() { return wakeup_state; }
+       void set_wakeup_state(bool state) { wakeup_state = state; }
+
        Thread * waiting_on() const;
        bool is_waiting_on(const Thread *t) const;
 
        bool is_model_thread() const { return model_thread; }
 
        friend void thread_startup();
+#ifdef TLS
+       friend void setup_context();
+       friend void * helper_thread(void *);
+       friend void finalize_helper_thread();
+#endif
 
        /**
         * Intentionally NOT allocated with MODELALLOC or SNAPSHOTALLOC.
@@ -112,6 +126,9 @@ public:
        void operator delete[](void *p, size_t size) {
                Thread_free(p);
        }
+#ifdef TLS
+       void setTLS(char *_tls) { tls = _tls;}
+#endif
 private:
        int create_context();
 
@@ -130,10 +147,24 @@ private:
         */
        ModelAction *pending;
 
+       /** @brief True if this thread was just woken up */
+       bool wakeup_state;
+
        void (*start_routine)(void *);
+       void *(*pstart_routine)(void *);
+
        void *arg;
        ucontext_t context;
        void *stack;
+#ifdef TLS
+public:
+       char *tls;
+       ucontext_t helpercontext;
+       pthread_mutex_t mutex;
+       pthread_mutex_t mutex2;
+       pthread_t thread;
+private:
+#endif
        thrd_t *user_thread;
        thread_id_t id;
        thread_state state;
@@ -145,11 +176,20 @@ private:
         */
        uint64_t last_action_val;
 
+       /** the value return from pthread functions */
+       void * pthread_return;
+
        /** @brief Is this Thread a special model-checker thread? */
        const bool model_thread;
 };
 
+#ifdef TLS
+uintptr_t get_tls_addr();
+#endif
+
 Thread * thread_current();
+void thread_startup();
+void main_thread_startup();
 
 static inline thread_id_t thrd_to_id(thrd_t t)
 {
@@ -176,4 +216,12 @@ static inline int id_to_int(thread_id_t id)
        return id;
 }
 
-#endif /* __THREADS_MODEL_H__ */
+int real_pthread_mutex_init(pthread_mutex_t *__mutex, const pthread_mutexattr_t *__mutexattr);
+int real_pthread_mutex_lock (pthread_mutex_t *__mutex);
+int real_pthread_mutex_unlock (pthread_mutex_t *__mutex);
+int real_pthread_create (pthread_t *__restrict __newthread, const pthread_attr_t *__restrict __attr, void *(*__start_routine)(void *), void *__restrict __arg);
+int real_pthread_join (pthread_t __th, void ** __thread_return);
+void real_pthread_exit (void * value_ptr) __attribute__((noreturn));
+void real_init_all();
+
+#endif /* __THREADS_MODEL_H__ */