Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision d23712e1aebdc4f095d0e9fa82b099933122c067)
+++ kernel/generic/include/proc/thread.h	(revision 5a5269df4bb8693ab8e38af0622b7fa6365b9535)
@@ -70,6 +70,4 @@
 /** Thread structure. There is one per thread. */
 typedef struct thread {
-	atomic_refcount_t refcount;
-
 	link_t rq_link;  /**< Run queue link. */
 	link_t wq_link;  /**< Wait queue link. */
@@ -79,48 +77,11 @@
 	odlink_t lthreads;
 
-	/** Tracking variable for thread_wait/thread_wakeup */
-	atomic_int sleep_state;
-
-	/**
-	 * If true, the thread is terminating.
-	 * It will not go to sleep in interruptible synchronization functions
-	 * and will call thread_exit() before returning to userspace.
-	 */
-	volatile bool interrupted;
-
-	/** Wait queue in which this thread sleeps. Used for debug printouts. */
-	_Atomic(waitq_t *) sleep_queue;
-
-	/** Waitq for thread_join_timeout(). */
-	waitq_t join_wq;
-
-	/** Thread accounting. */
-	atomic_time_stat_t ucycles;
-	atomic_time_stat_t kcycles;
-
-	/** Architecture-specific data. */
-	thread_arch_t arch;
-
-#ifdef CONFIG_UDEBUG
-	/**
-	 * If true, the scheduler will print a stack trace
-	 * to the kernel console upon scheduling this thread.
-	 */
-	atomic_int_fast8_t btrace;
-
-	/** Debugging stuff */
-	udebug_thread_t udebug;
-#endif /* CONFIG_UDEBUG */
-
-	/*
-	 * Immutable fields.
+	/** Lock protecting thread structure.
 	 *
-	 * These fields are only modified during initialization, and are not
-	 * changed at any time between initialization and destruction.
-	 * Can be accessed without synchronization in most places.
-	 */
-
-	/** Thread ID. */
-	thread_id_t tid;
+	 * Protects the whole thread structure except list links above.
+	 */
+	IRQ_SPINLOCK_DECLARE(lock);
+
+	char name[THREAD_NAME_BUFLEN];
 
 	/** Function implementing the thread. */
@@ -129,83 +90,123 @@
 	void *thread_arg;
 
-	char name[THREAD_NAME_BUFLEN];
-
+	/**
+	 * From here, the stored context is restored
+	 * when the thread is scheduled.
+	 */
+	context_t saved_context;
+
+	/**
+	 * From here, the stored timeout context
+	 * is restored when sleep times out.
+	 */
+	context_t sleep_timeout_context;
+
+	/**
+	 * From here, the stored interruption context
+	 * is restored when sleep is interrupted.
+	 */
+	context_t sleep_interruption_context;
+
+	/** If true, the thread can be interrupted from sleep. */
+	bool sleep_interruptible;
+
+	/**
+	 * If true, and this thread's sleep returns without a wakeup
+	 * (timed out or interrupted), waitq ignores the next wakeup.
+	 * This is necessary for futex to be able to handle those conditions.
+	 */
+	bool sleep_composable;
+
+	/** Wait queue in which this thread sleeps. */
+	waitq_t *sleep_queue;
+	/** Timeout used for timeoutable sleeping.  */
+	timeout_t sleep_timeout;
+	/** Flag signalling sleep timeout in progress. */
+	volatile bool timeout_pending;
+
+	/**
+	 * True if this thread is executing copy_from_uspace().
+	 * False otherwise.
+	 */
+	bool in_copy_from_uspace;
+
+	/**
+	 * True if this thread is executing copy_to_uspace().
+	 * False otherwise.
+	 */
+	bool in_copy_to_uspace;
+
+	/**
+	 * If true, the thread will not go to sleep at all and will call
+	 * thread_exit() before returning to userspace.
+	 */
+	bool interrupted;
+
+	/** If true, thread_join_timeout() cannot be used on this thread. */
+	bool detached;
+	/** Waitq for thread_join_timeout(). */
+	waitq_t join_wq;
+	/** Link used in the joiner_head list. */
+	link_t joiner_link;
+
+	fpu_context_t *saved_fpu_context;
+	bool fpu_context_exists;
+
+	/*
+	 * Defined only if thread doesn't run.
+	 * It means that fpu context is in CPU that last time executes this
+	 * thread. This disables migration.
+	 */
+	bool fpu_context_engaged;
+
+	/* The thread will not be migrated if nomigrate is non-zero. */
+	unsigned int nomigrate;
+
+	/** Thread state. */
+	state_t state;
+
+	/** Thread CPU. */
+	cpu_t *cpu;
+	/** Containing task. */
+	task_t *task;
+	/** Thread is wired to CPU. */
+	bool wired;
+	/** Thread was migrated to another CPU and has not run yet. */
+	bool stolen;
 	/** Thread is executed in user space. */
 	bool uspace;
 
+	/** Ticks before preemption. */
+	uint64_t ticks;
+
+	/** Thread accounting. */
+	uint64_t ucycles;
+	uint64_t kcycles;
+	/** Last sampled cycle. */
+	uint64_t last_cycle;
 	/** Thread doesn't affect accumulated accounting. */
 	bool uncounted;
 
-	/** Containing task. */
-	task_t *task;
+	/** Thread's priority. Implemented as index to CPU->rq */
+	int priority;
+	/** Thread ID. */
+	thread_id_t tid;
+
+	/** Architecture-specific data. */
+	thread_arch_t arch;
 
 	/** Thread's kernel stack. */
 	uint8_t *kstack;
 
-	/*
-	 * Local fields.
-	 *
-	 * These fields can be safely accessed from code that _controls execution_
-	 * of this thread. Code controls execution of a thread if either:
-	 *  - it runs in the context of said thread AND interrupts are disabled
-	 *    (interrupts can and will access these fields)
-	 *  - the thread is not running, and the code accessing it can legally
-	 *    add/remove the thread to/from a runqueue, i.e., either:
-	 *    - it is allowed to enqueue thread in a new runqueue
-	 *    - it holds the lock to the runqueue containing the thread
-	 *
-	 */
-
-	/**
-	 * From here, the stored context is restored
-	 * when the thread is scheduled.
-	 */
-	context_t saved_context;
-
-	// TODO: we only need one of the two bools below
-
-	/**
-	 * True if this thread is executing copy_from_uspace().
-	 * False otherwise.
-	 */
-	bool in_copy_from_uspace;
-
-	/**
-	 * True if this thread is executing copy_to_uspace().
-	 * False otherwise.
-	 */
-	bool in_copy_to_uspace;
-
-	/*
-	 * FPU context is a special case. If lazy FPU switching is disabled,
-	 * it acts as a regular local field. However, if lazy switching is enabled,
-	 * the context is synchronized via CPU->fpu_lock
-	 */
-#ifdef CONFIG_FPU
-	fpu_context_t fpu_context;
-#endif
-	bool fpu_context_exists;
-
-	/* The thread will not be migrated if nomigrate is non-zero. */
-	unsigned int nomigrate;
-
-	/** Thread was migrated to another CPU and has not run yet. */
-	bool stolen;
-
-	/**
-	 * Thread state (state_t).
-	 * This is atomic because we read it via some commands for debug output,
-	 * otherwise it could just be a regular local.
-	 */
-	atomic_int_fast32_t state;
-
-	/** Thread CPU. */
-	_Atomic(cpu_t *) cpu;
-
-	/** Thread's priority. Implemented as index to CPU->rq */
-	atomic_int_fast32_t priority;
-
-	/** Last sampled cycle. */
-	uint64_t last_cycle;
+#ifdef CONFIG_UDEBUG
+	/**
+	 * If true, the scheduler will print a stack trace
+	 * to the kernel console upon scheduling this thread.
+	 */
+	bool btrace;
+
+	/** Debugging stuff */
+	udebug_thread_t udebug;
+#endif /* CONFIG_UDEBUG */
 } thread_t;
 
@@ -218,44 +219,8 @@
 extern void thread_wire(thread_t *, cpu_t *);
 extern void thread_attach(thread_t *, task_t *);
-extern void thread_start(thread_t *);
-extern void thread_requeue_sleeping(thread_t *);
+extern void thread_ready(thread_t *);
 extern void thread_exit(void) __attribute__((noreturn));
 extern void thread_interrupt(thread_t *);
-
-enum sleep_state {
-	SLEEP_INITIAL,
-	SLEEP_ASLEEP,
-	SLEEP_WOKE,
-};
-
-typedef enum {
-	THREAD_OK,
-	THREAD_TERMINATING,
-} thread_termination_state_t;
-
-typedef enum {
-	THREAD_WAIT_SUCCESS,
-	THREAD_WAIT_TIMEOUT,
-} thread_wait_result_t;
-
-extern thread_termination_state_t thread_wait_start(void);
-extern thread_wait_result_t thread_wait_finish(deadline_t);
-extern void thread_wakeup(thread_t *);
-
-static inline thread_t *thread_ref(thread_t *thread)
-{
-	refcount_up(&thread->refcount);
-	return thread;
-}
-
-static inline thread_t *thread_try_ref(thread_t *thread)
-{
-	if (refcount_try_up(&thread->refcount))
-		return thread;
-	else
-		return NULL;
-}
-
-extern void thread_put(thread_t *);
+extern bool thread_interrupted(thread_t *);
 
 #ifndef thread_create_arch
@@ -274,11 +239,12 @@
 extern void thread_usleep(uint32_t);
 
-extern errno_t thread_join(thread_t *);
+#define thread_join(t) \
+	thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
+
 extern errno_t thread_join_timeout(thread_t *, uint32_t, unsigned int);
 extern void thread_detach(thread_t *);
 
-extern void thread_yield(void);
-
 extern void thread_print_list(bool);
+extern void thread_destroy(thread_t *, bool);
 extern thread_t *thread_find_by_id(thread_id_t);
 extern size_t thread_count(void);
@@ -286,5 +252,5 @@
 extern thread_t *thread_next(thread_t *);
 extern void thread_update_accounting(bool);
-extern thread_t *thread_try_get(thread_t *);
+extern bool thread_exists(thread_t *);
 
 extern void thread_migration_disable(void);
