Saturday, March 31, 2012

Reader write lock without any priority


#include <pthread.h>

enum locktype{
    READER =0,
    WRITER
};

typedef struct QNode {
    locktype  _type;
    struct QNode* pNext;
} QNode;

tyepdef struct Queue {
    QNode* _pHead;
} Queue;

typdef struct RWLock {
    Queue*              _pQueue;
    ptread_mutex_t      _lock;
    pthread_cond_t      _condv;
    uint32_t            _currentReaderCount;
    bool                _writeLocked;
} RWLock;

void

int
rw_lock_init(RWLock* pLock)
{
    if (pLock == NULL) {
        return ENULL;
    }
 
    pLock->pQueue = (Queue*) malloc(sizeof(queue));
    if (pLock->pQueue == NULL) {
        return ENULL;
    }
    initQueue(pLock->pQueue);
 
    if (pthread_mutex_init(&pLock->_lock)) {
        return EMUTEX_INIT;
    }
 
    if (pthread_cond_init(&pLock0>conv)) {
        return ECOND_INIT;
    }
 
    _readCount = 0;
    _writerLocked = false;
}

int
reader_rw_lock(RWlock* pRWLock)
{
    if (pRWLock == NULL) {
        return ENULL;
    }
 
    if (pthread_mutex_lock(&pRWLock->_lock)) {
        return EMUTEX_LOCK;
    }
 
    while((pQueue->pHead) || pQueue->_writerLocked)) {
        pQueue->insert(READER);
        if (pthread_cond_wait(&pRWLock->_lock, &pRWLock->condv)) {
            pthread_mutex_unlock(&pRWLock->lock));
            return ECONDWAIT;
        }
    }
    pRWLock->readCount++;
 
    pthread_mutex_unlock(&pRWlock->_lock);

    return 0;
}

int.
reader_rw_destroy(RWLock* pRWLock)
{
    if (pRWLock == NULL) {
        return ENULL;
    }
 
    pthread_mutex_lock(&pRWlock->_lock);
    if (pRWLock->_readerCount || pRWLock->_writeLock || pRWLock->_pHead) {
        pthread_mutex_unlock(&pRWlock->_lock);
        return EBUSY;
    }
 
    pthread_cond_destroy(pRWLock->_condv);
 
    pthread_mutex_unlock(&pRWlock->_lock);
    pthread_mutex_destory(&pRwlock->lock);

     return 0;  
}
int
writer_rw_lock(RWLock* pRWlock)
{
    if (pRWlock == NULL) {
        return ENULL;
    }
 
    if (pthread_mutex_lock(&pRWlock->_lock) {
        return EMUTEX_LOCK;
    }
 
    while ((pQueue->pHead) || (pQueue->_writeLocked) || pQueue->_readCount)) {
        pQueue->insert(WRITER);
        if (pthread_cond_wait(&pRWLock->_lock, &pRWLock->condv)) {
            pthread_mutex_unlock(&pRWLock->lock));
            return ECONDWAIT;
        }      
    }
 
    pRWLock->writerLocked = true;
 
    pthread_mutext_unlock(&pRWlock->_lock);
 
    return 0;
}

int
rw_unlock(RWLock* pRWlock)
{
    if (pRWLock == NULL) {
        return ENULL;
    }
 
    if (pthread_mutex_lock(&pRWlock->_lock) {
        return EMUTEX_LOCK;
    }
 
    if (pRWLock->_readcount) {
        pRWLock->_readcount -= 1;
    }
 
    if (pRWLock->_writelocked) {
        pRWLock->_writeLock = false;
    }    
 
    if ((pRWLock->_readCount == 0)&& (pRWLock->_writeLocked == false)) {
        if (pRWLock->_pHead) {
            if (pRWlock->_pHeade->_type == READER) {
                while (pRWLock->pHeader && (pRWLock->pHeader->_ptype == WRITER) {
                    pthread_cond_signal(pRWLock->pCondv);
                    removeHead(pRWLock->pQueue);
                }  
            } else {
                    pthread_cond_signal(pRWLock->pCondv);
                    removeHead(pRWLock->pQueue);
            }
        }
    }
    return 0;
}






No comments:

Post a Comment