добавлен пример pthread_rwlock
This commit is contained in:
parent
10632ce639
commit
0f87373a87
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#include "mpool.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
struct mpool_s pool1;
|
||||
|
||||
mpool_init(&pool1, 128, 16);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef XERROR_H
|
||||
#define XERROR_H
|
||||
|
||||
void fatal(const char *s);
|
||||
|
||||
#endif // XERORR_H
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue