Added SemaphorePool class.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11930 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2005-03-20 22:24:05 +00:00
parent 2efc846c8a
commit fa062b9f09
3 changed files with 173 additions and 0 deletions

View File

@ -8,4 +8,6 @@ KernelAddon <driver>tty : kernel drivers dev :
line_buffer.cpp line_buffer.cpp
master.cpp master.cpp
slave.cpp slave.cpp
SemaphorePool.cpp
; ;

View File

@ -0,0 +1,104 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Distributed under the terms of the MIT License.
*/
#include <new>
#include <util/AutoLock.h>
#include "SemaphorePool.h"
status_t
Semaphore::ZeroCount()
{
int32 count;
status_t error = get_sem_count(fSemaphore, &count);
if (error != B_OK)
return error;
if (count > 0)
error = acquire_sem_etc(fSemaphore, count, B_RELATIVE_TIMEOUT, 0);
else if (count < 0)
error = release_sem_etc(fSemaphore, -count, 0);
return error;
}
// #pragma mark -
SemaphorePool::SemaphorePool(int32 maxCached)
: fSemaphores(),
fCount(0),
fMaxCount(maxCached)
{
if (fMaxCount < 0)
fMaxCount = 8;
}
SemaphorePool::~SemaphorePool()
{
while (Semaphore *sem = fSemaphores.Head()) {
fSemaphores.Remove(sem);
delete sem;
}
mutex_destroy(&fLock);
}
status_t
SemaphorePool::Init()
{
return mutex_init(&fLock, "tty semaphore pool");
}
status_t
SemaphorePool::Get(Semaphore *&semaphore)
{
MutexLocker _(fLock);
// use a cached one, if available
if (fCount > 0) {
fCount--;
semaphore = fSemaphores.Head();
fSemaphores.Remove(semaphore);
return B_OK;
}
// create a new one
Semaphore *sem = new(nothrow) Semaphore(0, "pool semaphore");
if (!sem)
return B_NO_MEMORY;
status_t error = sem->ZeroCount();
if (error != B_OK) {
delete sem;
return error;
}
semaphore = sem;
return B_OK;
}
void
SemaphorePool::Put(Semaphore *semaphore)
{
if (!semaphore)
return;
MutexLocker _(fLock);
if (fCount >= fMaxCount || semaphore->InitCheck() != B_OK) {
delete semaphore;
return;
}
fSemaphores.Add(semaphore);
fCount++;
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
* Distributed under the terms of the MIT License.
*/
#ifndef TTY_SEMAPHORE_POOL_H
#define TTY_SEMAPHORE_POOL_H
#include <lock.h>
#include <util/DoublyLinkedList.h>
class Semaphore : public DoublyLinkedListLinkImpl<Semaphore> {
public:
Semaphore(sem_id sem)
: fSemaphore(sem)
{
}
Semaphore(int32 count, const char *name)
{
fSemaphore = create_sem(count, name);
}
~Semaphore()
{
if (fSemaphore >= 0)
delete_sem(fSemaphore);
}
status_t InitCheck() const
{
return (fSemaphore >= 0 ? B_OK : fSemaphore);
}
sem_id ID() const
{
return fSemaphore;
}
status_t ZeroCount();
private:
sem_id fSemaphore;
public:
Semaphore *fNext;
};
class SemaphorePool {
public:
SemaphorePool(int32 maxCached);
~SemaphorePool();
status_t Init();
status_t Get(Semaphore *&semaphore);
void Put(Semaphore *semaphore);
private:
typedef DoublyLinkedList<Semaphore> SemaphoreList;
struct mutex fLock;
SemaphoreList fSemaphores;
int32 fCount;
int32 fMaxCount;
};
#endif // TTY_SEMAPHORE_POOL_H