diff --git a/c/malloc_speed_test/const.h b/c/malloc_speed_test/const.h
new file mode 100644
index 0000000..1745981
--- /dev/null
+++ b/c/malloc_speed_test/const.h
@@ -0,0 +1,12 @@
+#ifndef CONST_H
+#define CONST_H
+
+#ifndef TRUE
+    #define TRUE (1)
+#endif
+
+#ifndef FALSE
+    #define FALSE (0)
+#endif
+
+#endif // CONST_H
diff --git a/c/malloc_speed_test/mpool.c b/c/malloc_speed_test/mpool.c
new file mode 100644
index 0000000..9ada81d
--- /dev/null
+++ b/c/malloc_speed_test/mpool.c
@@ -0,0 +1,100 @@
+#include "mpool.h"
+
+/*
+ * инициализация пула
+ */
+void mpool_init(struct mpool_s *bp, size_t nblocks, size_t mpool_block_size)
+{
+	size_t i;
+
+	bp->nblocks = nblocks;
+
+	mpool_block_size += 2 * sizeof(struct mpool_block_s *);
+
+	bp->pool = (struct mpool_block_s *)malloc(nblocks * mpool_block_size);
+
+	if (!bp->pool)
+	    fatal("virtual memory exhaused");
+
+	void *p = bp->pool + mpool_block_size,
+	     *pmax = p + (nblocks - 2) * mpool_block_size;
+
+	for ( ; p < pmax; p += mpool_block_size) {
+		((struct mpool_block_s *)p)->prev = (struct mpool_block_s *)(p - mpool_block_size);
+		((struct mpool_block_s *)p)->next = (struct mpool_block_s *)(p + mpool_block_size);
+	}
+
+	((struct mpool_block_s *)bp->pool)->prev = NULL;
+	((struct mpool_block_s *)bp->pool)->next = (struct mpool_block_s *)(bp->pool + mpool_block_size);
+
+	((struct mpool_block_s *)(bp->pool + (nblocks - 1) * mpool_block_size))->prev =
+		(struct mpool_block_s *)(bp->pool + (nblocks - 2) * mpool_block_size);
+	((struct mpool_block_s *)(bp->pool + (nblocks - 1) * mpool_block_size))->next = NULL;
+
+	bp->free_pool = (struct mpool_block_s *)bp->pool;
+	bp->busy_pool = NULL;
+}
+
+/*
+ * уничтожение пула
+ */
+void mpool_destroy(struct mpool_s *bp)
+{
+	free(bp->pool);
+	bp->nblocks = 0;
+	bp->pool = bp->free_pool = bp->busy_pool = NULL;
+}
+
+/*
+ * выдача блока из пула
+ */
+void *mpool_alloc(struct mpool_s *bp)
+{
+	if (!bp->free_pool)
+		return NULL;
+
+	bp->free_pool->prev = bp->free_pool->next; // save free_pool->next in free_pool->prev
+	
+	bp->free_pool->next = bp->busy_pool;
+
+	if (bp->busy_pool)
+		bp->busy_pool->prev = bp->free_pool;
+
+	bp->busy_pool = bp->free_pool;
+
+	bp->free_pool = bp->free_pool->prev;
+	
+	bp->busy_pool->prev = NULL; // saved in free_pool->prev to NULL
+
+	return &bp->busy_pool->obj;
+}
+
+/*
+ * возвращение блока в пул
+ */
+void mpool_free(struct mpool_s *bp, void *p)
+{
+	if (!p)
+		return;
+
+	struct mpool_block_s *b1 = (struct mpool_block_s *)(p - 2 * sizeof(struct mpool_block_s *)),
+		       *b2 = b1->next;
+
+	if (b1->prev)
+		b1->prev->next = b2;
+	if (b2)
+		b2->prev = b1->prev;
+
+	if (bp->free_pool) {
+		b1->next = bp->free_pool;
+		bp->free_pool->prev = b1;
+	}
+	else
+		b1->next = NULL;
+
+	bp->free_pool = b2;
+
+	if (bp->busy_pool == b1)
+		bp->busy_pool = b2;
+}
+
diff --git a/c/malloc_speed_test/mpool.h b/c/malloc_speed_test/mpool.h
new file mode 100644
index 0000000..1f941a0
--- /dev/null
+++ b/c/malloc_speed_test/mpool.h
@@ -0,0 +1,42 @@
+#ifndef MPOOL_H
+#define MPOOL_H
+
+#include <stdlib.h>
+
+#include "const.h"
+
+struct mpool_block_s {
+    struct mpool_block_s *next;
+    struct mpool_block_s *prev;
+    char obj;
+};
+
+struct mpool_s {
+	size_t nblocks;
+	void *pool;
+	struct mpool_block_s *free_pool;
+	struct mpool_block_s *busy_pool;
+};
+
+/*
+ * инициализация пула
+ */
+void mpool_init(struct mpool_s *bp, size_t nblocks, size_t mpool_block_size);
+
+/*
+ * уничтожение пула
+ */
+void mpool_destroy(struct mpool_s *bp);
+
+/*
+ * выдача блока из пула
+ */
+void *mpool_alloc(struct mpool_s *bp);
+
+/*
+ * возвращение блока в пул
+ */
+void mpool_free(struct mpool_s *bp, void *p);
+
+#endif // MPOOL_H
+
diff --git a/c/malloc_speed_test/mpool_test.c b/c/malloc_speed_test/mpool_test.c
new file mode 100644
index 0000000..df04bba
--- /dev/null
+++ b/c/malloc_speed_test/mpool_test.c
@@ -0,0 +1,10 @@
+#include "mpool.h"
+
+int main()
+{
+    struct mpool_s pool1;
+
+    mpool_init(&pool1, 128, 16);
+
+    return 0;
+}
diff --git a/c/malloc_speed_test/xerror.c b/c/malloc_speed_test/xerror.c
new file mode 100644
index 0000000..f40c1d6
--- /dev/null
+++ b/c/malloc_speed_test/xerror.c
@@ -0,0 +1,11 @@
+#include "xerror.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+void fatal(const char *s)
+{
+	perror(s);
+	exit(-1);
+}
diff --git a/c/malloc_speed_test/xerror.h b/c/malloc_speed_test/xerror.h
new file mode 100644
index 0000000..d8c64f7
--- /dev/null
+++ b/c/malloc_speed_test/xerror.h
@@ -0,0 +1,6 @@
+#ifndef XERROR_H
+#define XERROR_H
+
+void fatal(const char *s);
+
+#endif // XERORR_H
diff --git a/c/pthread_ex/pthread_rwlock_ex.c b/c/pthread_ex/pthread_rwlock_ex.c
new file mode 100644
index 0000000..041e896
--- /dev/null
+++ b/c/pthread_ex/pthread_rwlock_ex.c
@@ -0,0 +1,94 @@
+#define _MULTI_THREADED
+#include <pthread.h>
+#include <stdio.h>
+//#include "check.h"
+
+void checkResults(const char *s, int rc)
+{
+
+}
+
+pthread_rwlock_t       rwlock;
+
+void *rdlockThread(void *arg)
+{
+  int rc;
+
+  printf("Entered thread, getting read lock\n");
+  rc = pthread_rwlock_rdlock(&rwlock);
+  checkResults("pthread_rwlock_rdlock()\n", rc);
+  printf("got the rwlock read lock\n");
+
+  sleep(5);
+
+  printf("unlock the read lock\n");
+  rc = pthread_rwlock_unlock(&rwlock);
+  checkResults("pthread_rwlock_unlock()\n", rc);
+  printf("Secondary thread unlocked\n");
+  return NULL;
+}
+
+void *wrlockThread(void *arg)
+{
+  int rc;
+
+  printf("Entered thread, getting write lock\n");
+  rc = pthread_rwlock_wrlock(&rwlock);
+  checkResults("pthread_rwlock_wrlock()\n", rc);
+
+  printf("Got the rwlock write lock, now unlock\n");
+  rc = pthread_rwlock_unlock(&rwlock);
+  checkResults("pthread_rwlock_unlock()\n", rc);
+  printf("Secondary thread unlocked\n");
+  return NULL;
+}
+
+int main(int argc, char **argv)
+{
+  int                   rc=0;
+  pthread_t             thread, thread1;
+
+  printf("Enter Testcase - %s\n", argv[0]);
+
+  printf("Main, initialize the read write lock\n");
+  rc = pthread_rwlock_init(&rwlock, NULL);
+  checkResults("pthread_rwlock_init()\n", rc);
+
+  printf("Main, grab a read lock\n");
+  rc = pthread_rwlock_rdlock(&rwlock);
+  checkResults("pthread_rwlock_rdlock()\n",rc);
+
+  printf("Main, grab the same read lock again\n");
+  rc = pthread_rwlock_rdlock(&rwlock);
+  checkResults("pthread_rwlock_rdlock() second\n", rc);
+
+  printf("Main, create the read lock thread\n");
+  rc = pthread_create(&thread, NULL, rdlockThread, NULL);
+  checkResults("pthread_create\n", rc);
+
+  printf("Main - unlock the first read lock\n");
+  rc = pthread_rwlock_unlock(&rwlock);
+  checkResults("pthread_rwlock_unlock()\n", rc);
+
+  printf("Main, create the write lock thread\n");
+  rc = pthread_create(&thread1, NULL, wrlockThread, NULL);
+  checkResults("pthread_create\n", rc);
+
+  sleep(5);
+  printf("Main - unlock the second read lock\n");
+  rc = pthread_rwlock_unlock(&rwlock);
+  checkResults("pthread_rwlock_unlock()\n", rc);
+
+  printf("Main, wait for the threads\n");
+  rc = pthread_join(thread, NULL);
+  checkResults("pthread_join\n", rc);
+
+  rc = pthread_join(thread1, NULL);
+  checkResults("pthread_join\n", rc);
+
+  rc = pthread_rwlock_destroy(&rwlock);
+  checkResults("pthread_rwlock_destroy()\n", rc);
+
+  printf("Main completed\n");
+  return 0;
+}