X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=threads.h;h=91db236f4bddb904fbd7944c35c00b39bbfce092;hb=9db4729d3e6ab5f3ec5fd8a2560d95026332fecf;hp=25b1d6466a4abbb37f0aa633c4a9028cf1459955;hpb=d3b710fc183b8b71ab4726c2ae1b75caf13012b7;p=model-checker.git diff --git a/threads.h b/threads.h index 25b1d64..91db236 100644 --- a/threads.h +++ b/threads.h @@ -11,10 +11,7 @@ #include "mymemory.h" #include "libthreads.h" - -typedef int thread_id_t; - -#define THREAD_ID_T_NONE -1 +#include "modeltypes.h" /** @brief Represents the state of a user Thread */ typedef enum thread_state { @@ -22,12 +19,13 @@ typedef enum thread_state { THREAD_CREATED, /** Thread is running */ THREAD_RUNNING, + /** Thread is not currently running but is ready to run */ + THREAD_READY, /** - * Thread has yielded to the model-checker but is ready to run. Used - * during an action that caused a context switch to the model-checking - * context. + * Thread is waiting on another action (e.g., thread completion, lock + * release, etc.) */ - THREAD_READY, + THREAD_BLOCKED, /** Thread has completed its execution */ THREAD_COMPLETED } thread_state; @@ -37,6 +35,7 @@ class ModelAction; /** @brief A Thread is created for each user-space thread */ class Thread { public: + Thread(thread_id_t tid); Thread(thrd_t *t, void (*func)(void *), void *a); ~Thread(); void complete(); @@ -71,33 +70,54 @@ public: /** @return True if this thread is finished executing */ bool is_complete() { return state == THREAD_COMPLETED; } + /** @return True if this thread is blocked */ + bool is_blocked() { return state == THREAD_BLOCKED; } + /** @return True if no threads are waiting on this Thread */ bool wait_list_empty() { return wait_list.empty(); } /** - * Add a thread to the waiting list for this thread. - * @param t The Thread to add + * Add a ModelAction to the waiting list for this thread. + * @param t The ModelAction to add. Must be a JOIN. */ - void push_wait_list(Thread *t) { wait_list.push_back(t); } + void push_wait_list(ModelAction *act) { wait_list.push_back(act); } + + unsigned int num_wait_list() { + return wait_list.size(); + } + ModelAction * get_waiter(unsigned int i) { + return wait_list[i]; + } + + ModelAction * get_pending() { return pending; } + void set_pending(ModelAction *act) { pending = act; } /** - * Remove one Thread from the waiting list - * @return The Thread that was removed from the waiting list + * Remove one ModelAction from the waiting list + * @return The ModelAction that was removed from the waiting list */ - Thread * pop_wait_list() { - Thread *ret = wait_list.front(); + ModelAction * pop_wait_list() { + ModelAction *ret = wait_list.front(); wait_list.pop_back(); return ret; } + bool is_model_thread() { return model_thread; } + friend void thread_startup(); - SNAPSHOTALLOC + /** + * Intentionally NOT allocated with MODELALLOC or SNAPSHOTALLOC. + * Threads should be allocated on the user's normal (snapshotting) heap + * to allow their allocation/deallocation to follow the same pattern as + * the rest of the backtracked/replayed program. + */ private: int create_context(); Thread *parent; ModelAction *creation; + ModelAction *pending; void (*start_routine)(void *); void *arg; ucontext_t context; @@ -107,11 +127,11 @@ private: thread_state state; /** - * A list of Threads waiting on this Thread. Particularly, this list is - * used for thread joins, where another Thread waits for this Thread to - * complete + * A list of ModelActions waiting on this Thread. Particularly, this + * list is used for thread joins, where another Thread waits for this + * Thread to complete */ - std::vector wait_list; + std::vector< ModelAction *, SnapshotAlloc > wait_list; /** * The value returned by the last action in this thread @@ -119,6 +139,9 @@ private: * @see Thread::get_return_value() */ uint64_t last_action_val; + + /** @brief Is this Thread a special model-checker thread? */ + const bool model_thread; }; Thread * thread_current();