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; +}