Index: uspace/lib/cpp/include/__bits/thread/future.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/future.hpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
+++ uspace/lib/cpp/include/__bits/thread/future.hpp	(revision 04c0fc5aa45ec90f84d2ef0b8b067f698c6f5f0e)
@@ -30,8 +30,11 @@
 #define LIBCPP_BITS_THREAD_FUTURE
 
+#include <__bits/refcount_obj.hpp>
+#include <__bits/thread/threading.hpp>
 #include <cassert>
 #include <memory>
 #include <system_error>
 #include <type_traits>
+#include <utility>
 
 namespace std
@@ -85,4 +88,5 @@
 
             const error_code& code() const noexcept;
+            const char* what() const noexcept;
 
         private:
@@ -94,7 +98,270 @@
      */
 
+    namespace aux
+    {
+        template<class R>
+        class shared_state: public aux::refcount_obj
+        {
+            public:
+                const bool is_deferred_function;
+
+                shared_state(bool is_deferred = false)
+                    : is_deferred_function{is_deferred}, mutex_{},
+                      condvar_{}, value_{}, value_set_{false},
+                      exception_{}, has_exception_{false}
+                {
+                    threading::mutex::init(mutex_);
+                    threading::condvar::init(condvar_);
+                }
+
+                void destroy() override
+                {
+                    if (this->refs() < 1)
+                    {
+                        // TODO: what to destroy? just this?
+                    }
+                }
+
+                void set_value(const R& val, bool set)
+                {
+                    value_ = val;
+                    value_set_ = set;
+                }
+
+                void set_value(R&& val, bool set)
+                {
+                    aux::threading::mutex::lock(mutex_);
+                    value_ = std::move(val);
+                    value_set_ = set;
+                    aux::threading::mutex::unlock(mutex_);
+
+                    aux::threading::condvar::broadcast(condvar_);
+                }
+
+                void set_set(bool set = true) noexcept
+                {
+                    value_set_ = set;
+                }
+
+                bool is_set() const noexcept
+                {
+                    return value_set_;
+                }
+
+                R& get()
+                {
+                    return value_;
+                }
+
+                void set_exception(exception_ptr ptr)
+                {
+                    exception_ = ptr;
+                    has_exception_ = true;
+                }
+
+                bool has_exception() const noexcept
+                {
+                    return has_exception_;
+                }
+
+                void throw_stored_exception() const
+                {
+                    // TODO: implement
+                }
+
+                /**
+                 * TODO: This member function is supposed to be marked
+                 *       as 'const'. In such a case, however, we cannot
+                 *       use the underlying fibril API because these
+                 *       references get converted to pointers and the API
+                 *       does not accept e.g. 'const fibril_condvar_t*'.
+                 *
+                 *       The same applies to the wait_for and wait_until
+                 *       functions.
+                 */
+                void wait()
+                {
+                    aux::threading::mutex::lock(mutex_);
+                    while (!value_set_)
+                        aux::threading::condvar::wait(condvar_, mutex_);
+                    aux::threading::mutex::unlock(mutex_);
+                }
+
+                template<class Rep, class Period>
+                bool wait_for(const chrono::duration<Rep, Period>& rel_time)
+                {
+                    aux::threading::mutex::lock(mutex_);
+                    aux::threading::condvar::wait_for(
+                        condvar_, mutex_,
+                        aux::threading::time::convert(rel_time)
+                    );
+                    aux::threading::mutex::unlock(mutex_);
+
+                    return value_set_;
+                }
+
+                template<class Clock, class Duration>
+                bool wait_until(const chrono::time_point<Clock, Duration>& abs_time)
+                {
+                    aux::threading::mutex::lock(mutex_);
+                    aux::threading::condvar::wait_for(
+                        condvar_, mutex_,
+                        aux::threading::time::convert(abs_time - Clock::now())
+                    );
+                    aux::threading::mutex::unlock(mutex_);
+
+                    return value_set_;
+                }
+
+                ~shared_state()
+                {
+                    // TODO: just destroy?
+                }
+
+            private:
+                aux::mutex_t mutex_;
+                aux::condvar_t condvar_;
+
+                R value_;
+                bool value_set_;
+
+                exception_ptr exception_;
+                bool has_exception_;
+        };
+    }
+
+    template<class R>
+    class future;
+
     template<class R>
     class promise
     {
+        public:
+            promise()
+                : state_{new aux::shared_state<R>{}}
+            { /* DUMMY BODY */ }
+
+            template<class Allocator>
+            promise(allocator_arg_t, const Allocator& a)
+                : promise{}
+            {
+                // TODO: Use the allocator.
+            }
+
+            promise(promise&& rhs) noexcept
+                : state_{}
+            {
+                state_ = rhs.state_;
+                rhs.state_ = nullptr;
+            }
+
+            promise(const promise&) = delete;
+
+            ~promise()
+            {
+                abandon_state_();
+            }
+
+            promise& operator=(promise&& rhs) noexcept
+            {
+                abandon_state_();
+                promise{std::move(rhs)}.swap(*this);
+            }
+
+            promise& operator=(const promise&) = delete;
+
+            void swap(promise& other) noexcept
+            {
+                std::swap(state_, other.state_);
+            }
+
+            future<R> get_future()
+            {
+                return future<R>{state_};
+            }
+
+            void set_value(const R& val)
+            {
+                if (!state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                state_->set_value(val, true);
+            }
+
+            void set_value(R&& val)
+            {
+                if (!state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                state_->set_value(std::forward<R>(val), true);
+            }
+
+            void set_exception(exception_ptr ptr)
+            {
+                assert(state_);
+
+                state_->set_exception(ptr);
+            }
+
+            void set_value_at_thread_exit(const R& val)
+            {
+                if (!state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                state_->set_value(val, false);
+                // TODO: schedule it to be set as ready when thread exits
+            }
+
+            void set_value_at_thread_exit(R&& val)
+            {
+                if (!state_)
+                    throw future_error{make_error_code(future_errc::no_state)};
+                if (state_->is_set())
+                {
+                    throw future_error{
+                        make_error_code(future_errc::promise_already_satisfied)
+                    };
+                }
+
+                state_->set_value(std::forward<R>(val), false);
+                // TODO: schedule it to be set as ready when thread exits
+            }
+
+            void set_exception_at_thread_exit(exception_ptr)
+            {
+                // TODO: No exception handling, no-op at this time.
+            }
+
+        private:
+            void abandon_state_()
+            {
+                /**
+                 * 1) If state is not ready:
+                 *   a) Store exception of type future_error with
+                 *      error condition broken_promise.
+                 *   b) Mark state as ready.
+                 * 2) Rekease the state.
+                 */
+            }
+
+            aux::shared_state<R>* state_;
     };
 
@@ -102,4 +369,5 @@
     class promise<R&>
     {
+        // TODO: Copy & modify once promise is done.
     };
 
@@ -107,4 +375,5 @@
     class promise<void>
     {
+        // TODO: Copy & modify once promise is done.
     };
 
@@ -120,6 +389,122 @@
 
     template<class R>
+    class shared_future;
+
+    template<class R>
     class future
     {
+        public:
+            future() noexcept
+                : state_{nullptr}
+            { /* DUMMY BODY */ }
+
+            future(const future&) = delete;
+
+            future(future&& rhs) noexcept
+                : state_{std::move(rhs.state_)}
+            {
+                rhs.state_ = nullptr;
+            }
+
+            future(aux::shared_state<R>* state)
+                : state_{state}
+            {
+                /**
+                 * Note: This is a custom non-standard constructor that allows
+                 *       us to create a future directly from a shared state. This
+                 *       should never be a problem as aux::shared_state is a private
+                 *       type and future has no constructor templates.
+                 */
+            }
+
+            ~future()
+            {
+                release_state_();
+            }
+
+            future& operator=(const future) = delete;
+
+            future& operator=(future&& rhs) noexcept
+            {
+                release_state_();
+                state_ = std::move(rhs.state_);
+                rhs.state_ = nullptr;
+            }
+
+            shared_future<R> share()
+            {
+                return shared_future<R>(std::move(*this));
+            }
+
+            R get()
+            {
+                assert(state_);
+
+                wait();
+
+                auto state = state_;
+                state_ = nullptr;
+                if (state->has_exception())
+                    state->throw_stored_exception();
+
+                return std::move(state->get());
+            }
+
+            bool valid() const noexcept
+            {
+                return state_ != nullptr;
+            }
+
+            void wait() const noexcept
+            {
+                assert(state_);
+
+                state_->wait();
+            }
+
+            template<class Rep, class Period>
+            future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const
+            {
+                assert(state_);
+                if (state_->is_deffered_function)
+                    return future_status::deferred;
+
+                auto res = state_->wait_for(rel_time);
+
+                if (res)
+                    return future_status::ready;
+                else
+                    return future_status::timeout;
+            }
+
+            template<class Clock, class Duration>
+            future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const
+            {
+                assert(state_);
+                if (state_->is_deffered_function)
+                    return future_status::deferred;
+
+                auto res = state_->wait_until(abs_time);
+
+                if (res)
+                    return future_status::ready;
+                else
+                    return future_status::timeout;
+            }
+
+        private:
+            void release_state_()
+            {
+                /**
+                 * Last reference to state -> destroy state.
+                 * Decrement refcount of state otherwise.
+                 * Will not block, unless all following hold:
+                 *  1) State was created by call to std::async.
+                 *  2) State is not yet ready.
+                 *  3) This was the last reference to the shared state.
+                 */
+            }
+
+            aux::shared_state<R>* state_;
     };
 
@@ -127,4 +512,5 @@
     class future<R&>
     {
+        // TODO: Copy & modify once future is done.
     };
 
@@ -132,9 +518,13 @@
     class future<void>
     {
-    };
-
+        // TODO: Copy & modify once future is done.
+    };
+
+    // TODO: Make sure the move constructor of shared_future
+    //       invalidates the state (i.e. sets to nullptr).
     template<class R>
     class shared_future
     {
+        // TODO: Copy & modify once future is done.
     };
 
@@ -142,4 +532,5 @@
     class shared_future<R&>
     {
+        // TODO: Copy & modify once future is done.
     };
 
@@ -147,4 +538,5 @@
     class shared_future<void>
     {
+        // TODO: Copy & modify once future is done.
     };
 
@@ -155,4 +547,44 @@
     class packaged_task<R(Args...)>
     {
+        packaged_task() noexcept
+        {}
+
+        template<class F>
+        explicit packaged_task(F&& f)
+        {}
+
+        template<class F, class Allocator>
+        explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f)
+        {}
+
+        ~packaged_task()
+        {}
+
+        packaged_task(const packaged_task&) = delete;
+        packaged_task& operator=(const packaged_task&) = delete;
+
+        packaged_task(packaged_task&& rhs)
+        {}
+
+        packaged_task& operator=(packaged_task&& rhs)
+        {}
+
+        void swap(packaged_task& other) noexcept
+        {}
+
+        bool valid() const noexcept
+        {}
+
+        future<R> get_future()
+        {}
+
+        void operator()(Args...)
+        {}
+
+        void make_ready_at_thread_exit(Args...)
+        {}
+
+        void reset()
+        {}
     };
 
Index: uspace/lib/cpp/src/future.cpp
===================================================================
--- uspace/lib/cpp/src/future.cpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
+++ uspace/lib/cpp/src/future.cpp	(revision 04c0fc5aa45ec90f84d2ef0b8b067f698c6f5f0e)
@@ -81,3 +81,8 @@
         return code_;
     }
+
+    const char* future_error::what() const noexcept
+    {
+        return code().message().c_str();
+    }
 }
