Added SemaphorePool class.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11930 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
2efc846c8a
commit
fa062b9f09
@ -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
|
||||||
;
|
;
|
||||||
|
|
||||||
|
104
src/add-ons/kernel/drivers/tty/SemaphorePool.cpp
Normal file
104
src/add-ons/kernel/drivers/tty/SemaphorePool.cpp
Normal 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++;
|
||||||
|
}
|
67
src/add-ons/kernel/drivers/tty/SemaphorePool.h
Normal file
67
src/add-ons/kernel/drivers/tty/SemaphorePool.h
Normal 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
|
Loading…
Reference in New Issue
Block a user