Index: uspace/lib/cpp/Makefile
===================================================================
--- uspace/lib/cpp/Makefile	(revision 59d82352304d341674d06eca07ba9d7a4d7f7a41)
+++ uspace/lib/cpp/Makefile	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
@@ -47,4 +47,5 @@
 	src/mutex.cpp \
 	src/new.cpp \
+	src/refcount_obj.cpp \
 	src/shared_mutex.cpp \
 	src/stdexcept.cpp \
Index: uspace/lib/cpp/include/__bits/memory/shared_payload.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/memory/shared_payload.hpp	(revision 59d82352304d341674d06eca07ba9d7a4d7f7a41)
+++ uspace/lib/cpp/include/__bits/memory/shared_payload.hpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_MEMORY_SHARED_PAYLOAD
 
+#include <__bits/refcount_obj.hpp>
 #include <cinttypes>
 #include <utility>
@@ -43,10 +44,4 @@
 namespace std::aux
 {
-    /**
-     * At the moment we do not have atomics, change this
-     * to std::atomic<long> once we do.
-     */
-    using refcount_t = long;
-
     /**
      * This allows us to construct shared_ptr from
@@ -66,19 +61,11 @@
 
     template<class T>
-    class shared_payload_base
+    class shared_payload_base: public aux::refcount_obj
     {
         public:
-            virtual void destroy() = 0;
             virtual T* get() const noexcept = 0;
 
             virtual uint8_t* deleter() const noexcept = 0;
 
-            virtual void increment() noexcept = 0;
-            virtual void increment_weak() noexcept = 0;
-            virtual bool decrement() noexcept = 0;
-            virtual bool decrement_weak() noexcept = 0;
-            virtual refcount_t refs() const noexcept = 0;
-            virtual refcount_t weak_refs() const noexcept = 0;
-            virtual bool expired() const noexcept = 0;
             virtual shared_payload_base* lock() noexcept = 0;
 
@@ -91,6 +78,5 @@
         public:
             shared_payload(T* ptr, D deleter = D{})
-                : data_{ptr}, deleter_{deleter},
-                  refcount_{1}, weak_refcount_{1}
+                : data_{ptr}, deleter_{deleter}
             { /* DUMMY BODY */ }
 
@@ -98,5 +84,5 @@
             shared_payload(Args&&... args)
                 : data_{new T{forward<Args>(args)...}},
-                  deleter_{}, refcount_{1}, weak_refcount_{1}
+                  deleter_{}
             { /* DUMMY BODY */ }
 
@@ -104,5 +90,5 @@
             shared_payload(allocator_arg_t, Alloc alloc, Args&&... args)
                 : data_{alloc.allocate(1)},
-                  deleter_{}, refcount_{1}, weak_refcount_{1}
+                  deleter_{}
             {
                 alloc.construct(data_, forward<Args>(args)...);
@@ -112,5 +98,5 @@
             shared_payload(D deleter, Alloc alloc, Args&&... args)
                 : data_{alloc.allocate(1)},
-                  deleter_{deleter}, refcount_{1}, weak_refcount_{1}
+                  deleter_{deleter}
             {
                 alloc.construct(data_, forward<Args>(args)...);
@@ -119,5 +105,5 @@
             void destroy() override
             {
-                if (refs() == 0)
+                if (this->refs() == 0)
                 {
                     if (data_)
@@ -127,5 +113,5 @@
                     }
 
-                    if (weak_refs() == 0)
+                    if (this->weak_refs() == 0)
                         delete this;
                 }
@@ -142,57 +128,10 @@
             }
 
-            void increment() noexcept override
-            {
-                __atomic_add_fetch(&refcount_, 1, __ATOMIC_ACQ_REL);
-            }
-
-            void increment_weak() noexcept override
-            {
-                __atomic_add_fetch(&weak_refcount_, 1, __ATOMIC_ACQ_REL);
-            }
-
-            bool decrement() noexcept override
-            {
-                if (__atomic_sub_fetch(&refcount_, 1, __ATOMIC_ACQ_REL) == 0)
-                {
-                    /**
-                     * First call to destroy() will delete the held object,
-                     * so it doesn't matter what the weak_refcount_ is,
-                     * but we added one and we need to remove it now.
-                     */
-                    decrement_weak();
-
-                    return true;
-                }
-                else
-                    return false;
-            }
-
-            bool decrement_weak() noexcept override
-            {
-                return __atomic_sub_fetch(&weak_refcount_, 1, __ATOMIC_ACQ_REL) == 0 && refs() == 0;
-            }
-
-            refcount_t refs() const noexcept override
-            {
-                return __atomic_load_n(&refcount_, __ATOMIC_RELAXED);
-            }
-
-            refcount_t weak_refs() const noexcept override
-            {
-                return __atomic_load_n(&weak_refcount_, __ATOMIC_RELAXED);
-            }
-
-            bool expired() const noexcept override
-            {
-                return refs() == 0;
-            }
-
             shared_payload_base<T>* lock() noexcept override
             {
-                refcount_t rfs = refs();
+                refcount_t rfs = this->refs();
                 while (rfs != 0L)
                 {
-                    if (__atomic_compare_exchange_n(&refcount_, &rfs, rfs + 1,
+                    if (__atomic_compare_exchange_n(&this->refcount_, &rfs, rfs + 1,
                                                     true, __ATOMIC_RELAXED,
                                                     __ATOMIC_RELAXED))
@@ -208,14 +147,4 @@
             T* data_;
             D deleter_;
-
-            /**
-             * We're using a trick where refcount_ > 0
-             * means weak_refcount_ has 1 added to it,
-             * this makes it easier for weak_ptrs that
-             * can't decrement the weak_refcount_ to
-             * zero with shared_ptrs using this object.
-             */
-            refcount_t refcount_;
-            refcount_t weak_refcount_;
     };
 }
Index: uspace/lib/cpp/include/__bits/refcount_obj.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/refcount_obj.hpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
+++ uspace/lib/cpp/include/__bits/refcount_obj.hpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LIBCPP_BITS_REFCOUNT_OBJ
+#define LIBCPP_BITS_REFCOUNT_OBJ
+
+namespace std::aux
+{
+    /**
+     * At the moment we do not have atomics, change this
+     * to std::atomic<long> once we do.
+     */
+    using refcount_t = long;
+
+    class refcount_obj
+    {
+        public:
+            refcount_obj() = default;
+
+            void increment() noexcept;
+            void increment_weak() noexcept;
+            bool decrement() noexcept;
+            bool decrement_weak() noexcept;
+            refcount_t refs() const noexcept;
+            refcount_t weak_refs() const noexcept;
+            bool expired() const noexcept;
+
+            virtual ~refcount_obj() = default;
+            virtual void destroy() = 0;
+
+        protected:
+            /**
+             * We're using a trick where refcount_ > 0
+             * means weak_refcount_ has 1 added to it,
+             * this makes it easier for weak_ptrs that
+             * can't decrement the weak_refcount_ to
+             * zero with shared_ptrs using this object.
+             */
+            refcount_t refcount_{1};
+            refcount_t weak_refcount_{1};
+    };
+}
+
+#endif
Index: uspace/lib/cpp/src/refcount_obj.cpp
===================================================================
--- uspace/lib/cpp/src/refcount_obj.cpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
+++ uspace/lib/cpp/src/refcount_obj.cpp	(revision 8add15e0d742e2ce9688f92ee8e6378e2caa7b04)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 Jaroslav Jindrak
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <__bits/refcount_obj.hpp>
+
+namespace std::aux
+{
+    void refcount_obj::increment()
+    {
+        __atomic_add_fetch(&refcount_, 1, __ATOMIC_ACQ_REL);
+    }
+
+    void refcount_obj::increment_weak()
+    {
+        __atomic_add_fetch(&weak_refcount_, 1, __ATOMIC_ACQ_REL);
+    }
+
+    bool refcount_obj::decrement()
+    {
+        if (__atomic_sub_fetch(&refcount_, 1, __ATOMIC_ACQ_REL) == 0)
+        {
+            /**
+             * First call to destroy() will delete the held object,
+             * so it doesn't matter what the weak_refcount_ is,
+             * but we added one and we need to remove it now.
+             */
+            decrement_weak();
+
+            return true;
+        }
+        else
+            return false;
+    }
+
+    bool refcount_obj::decrement_weak()
+    {
+        return __atomic_sub_fetch(&weak_refcount_, 1, __ATOMIC_ACQ_REL) == 0 && refs() == 0;
+    }
+
+    refcount_t refcount_obj::refs() const
+    {
+        return __atomic_load_n(&refcount_, __ATOMIC_RELAXED);
+    }
+
+    refcount_t refcount_obj::weak_refs() const
+    {
+        return __atomic_load_n(&weak_refcount_, __ATOMIC_RELAXED);
+    }
+
+    bool refcount_obj::expired() const
+    {
+        return refs() == 0;
+    }
+}
