diff --git a/repos/libports/lib/mk/pthread.mk b/repos/libports/lib/mk/pthread.mk
index 216cbcbd80..96b2648b5d 100644
--- a/repos/libports/lib/mk/pthread.mk
+++ b/repos/libports/lib/mk/pthread.mk
@@ -1,4 +1,4 @@
-SRC_CC = semaphore.cc \
+SRC_CC = semaphore.cc rwlock.cc \
thread.cc thread_create.cc
LIBS += libc
diff --git a/repos/libports/src/lib/pthread/rwlock.cc b/repos/libports/src/lib/pthread/rwlock.cc
new file mode 100644
index 0000000000..0fd961174d
--- /dev/null
+++ b/repos/libports/src/lib/pthread/rwlock.cc
@@ -0,0 +1,155 @@
+/*
+ * \brief POSIX readers/writer lock (rwlock) implementation
+ * \author Alexander Senier
+ * \date 2018-01-25
+ *
+ */
+
+/*
+ * Copyright (C) 2018 Componolit GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+
+/* Libc includes */
+#include
+#include
+
+/*
+ * A reader-preferring implementation of a readers-writer lock as described
+ * in Michael Raynal, "Concurrent Programming: Algorithms, Principles, and
+ * Foundations", ISBN 978-3-642-32026-2, page 75
+ */
+
+extern "C" {
+
+ /*
+ * This class is named 'struct pthread_rwlock' because the 'pthread_rwlock_t'
+ * type is defined as 'struct rwlock*' in 'sys/_pthreadtypes.h'
+ */
+ struct pthread_rwlock
+ {
+ private:
+
+ Genode::Thread *_owner;
+ Genode::Lock _nbr_mutex {};
+ Genode::Lock _global_mutex {};
+ int _nbr = 0;
+
+ public:
+
+ void rdlock()
+ {
+ Genode::Lock_guard guard(_nbr_mutex);
+ ++_nbr;
+ if (_nbr == 1) {
+ _global_mutex.lock();
+ }
+ }
+
+ void wrlock()
+ {
+ _global_mutex.lock();
+ _owner = Genode::Thread::myself();
+ }
+
+ int unlock()
+ {
+ Genode::Lock_guard guard(_nbr_mutex);
+
+ /* Read lock */
+ if (_owner == nullptr) {
+ _nbr--;
+ if (_nbr == 0) {
+ _global_mutex.unlock();
+ }
+ return 0;
+ };
+
+ if (_owner != Genode::Thread::myself()) {
+ Genode::error("Unlocking writer lock owned by other thread");
+ errno = EPERM;
+ return -1;
+ };
+
+ /* Write lock owned by us */
+ _global_mutex.unlock();
+ return 0;
+ }
+ };
+
+ struct pthread_rwlockattr
+ {
+ };
+
+ int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+ {
+ *rwlock = new struct pthread_rwlock();
+ return 0;
+ }
+
+ int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
+ {
+ delete *rwlock;
+ return 0;
+ }
+
+ int pthread_rwlock_rdlock(pthread_rwlock_t * rwlock)
+ {
+ (*rwlock)->rdlock();
+ return 0;
+ }
+
+ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+ {
+ (*rwlock)->wrlock();
+ return 0;
+ }
+
+ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+ {
+ return (*rwlock)->unlock();
+ }
+
+ int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
+ {
+ *attr = new struct pthread_rwlockattr();
+ return 0;
+ }
+
+ int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared)
+ {
+ *pshared = PTHREAD_PROCESS_PRIVATE;
+ return 0;
+ }
+
+ int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
+ {
+ if (pshared != PTHREAD_PROCESS_PRIVATE) {
+ errno = EINVAL;
+ return -1;
+ }
+ return 0;
+ }
+
+ int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
+ {
+ delete *attr;
+ return 0;
+ }
+
+ /*
+ * Unimplemented functions:
+ * int pthread_rwlock_timedrdlock(pthread_rwlock_t *, const struct timespec *);
+ * int pthread_rwlock_timedwrlock(pthread_rwlock_t *, const struct timespec *);
+ * int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+ * int pthread_rwlock_trywrlock(pthread_rwlock_t *);
+ */
+}