switched to epicsMutex for locking

This commit is contained in:
Jeff Hill
2003-02-12 18:54:48 +00:00
parent 11dcec07bf
commit f8db8b4dc0
4 changed files with 103 additions and 88 deletions

View File

@@ -224,9 +224,10 @@ gddStatus gddApplicationTypeTable::registerApplicationType(
return gddErrorAtLimit;
}
sem.take();
rapp=total_registered++;
sem.give();
{
epicsGuard < epicsMutex > guard ( sem );
rapp=total_registered++;
}
if((rc=splitApplicationType(rapp,group,app))<0) return rc;
@@ -382,16 +383,16 @@ gdd* gddApplicationTypeTable::getDD(aitUint32 rapp)
switch(attr_table[group][app].type)
{
case gddApplicationTypeProto:
attr_table[group][app].sem.take();
attr_table[group][app].sem.lock ();
if( (dd=attr_table[group][app].free_list) )
{
//fprintf(stderr,"Popping a proto DD from list! %d %8.8x\n",app,dd);
attr_table[group][app].free_list=dd->next();
attr_table[group][app].sem.give();
attr_table[group][app].sem.unlock ();
}
else
{
attr_table[group][app].sem.give();
attr_table[group][app].sem.unlock ();
// copy the prototype
blk=new aitUint8[attr_table[group][app].proto_size];
// fprintf(stderr,"Creating a new proto DD! %d %8.8x\n",app,blk);

View File

@@ -79,7 +79,7 @@ public:
aitIndex total_dds;
gdd* proto;
gdd* free_list;
gddSemaphore sem;
epicsMutex sem;
gddApplicationTypeType type;
aitUint32 user_value;
aitUint16* map;
@@ -162,7 +162,7 @@ private:
aitUint32 max_groups;
gddApplicationTypeElement** attr_table;
gddSemaphore sem;
epicsMutex sem;
};
inline aitUint32 gddApplicationTypeTable::group(aitUint32 rapp) const

View File

@@ -17,17 +17,42 @@
#include "gddNewDel.h"
#include <stdio.h>
gddCleanUp gddBufferCleanUp;
class gddCleanUpNode
{
public:
void* buffer;
gddCleanUpNode* next;
};
gddCleanUp::gddCleanUp(void) { }
class gddCleanUp
{
public:
gddCleanUp();
~gddCleanUp();
void Add(void*);
private:
gddCleanUpNode * bufs;
epicsMutex lock;
};
gddCleanUp::~gddCleanUp(void) { gddCleanUp::CleanUp(); }
static gddCleanUp * pBufferCleanUpGDD = NULL;
gddCleanUpNode* gddCleanUp::bufs = NULL;
static epicsThreadOnceId gddCleanupOnce = EPICS_THREAD_ONCE_INIT;
static void gddCleanupInit ( void * )
{
pBufferCleanUpGDD = new gddCleanUp;
assert ( pBufferCleanUpGDD );
}
gddSemaphore gddCleanUp::lock;
void gddGlobalCleanupAdd ( void * pBuf )
{
epicsThreadOnce ( & gddCleanupOnce, gddCleanupInit, 0 );
pBufferCleanUpGDD->Add ( pBuf );
}
void gddCleanUp::CleanUp(void)
gddCleanUp::gddCleanUp() : bufs ( NULL ) {}
gddCleanUp::~gddCleanUp()
{
gddCleanUpNode *p1,*p2;
@@ -44,9 +69,10 @@ void gddCleanUp::Add(void* v)
{
gddCleanUpNode* p = new gddCleanUpNode;
p->buffer=v;
lock.take();
p->next=gddCleanUp::bufs;
gddCleanUp::bufs=p;
lock.give();
{
epicsGuard < epicsMutex > guard ( lock );
p->next=gddCleanUp::bufs;
gddCleanUp::bufs=p;
}
}

View File

@@ -21,7 +21,9 @@
// this file if formatted with tab stop = 4
#include <stdlib.h>
#include "gddSemaphore.h"
#include "epicsMutex.h"
#include "epicsGuard.h"
#include "epicsThread.h"
// Avoid using templates at the cost of very poor readability.
// This forces the user to have a static data member named "gddNewDel_freelist"
@@ -29,51 +31,56 @@
// To use this stuff:
//
// ** In class description header file:
// class myClass
// {
// public:
// gdd_NEWDEL_FUNC(address_to_be_used_for_freelist_next_pointer)
// private:
// gdd_NEWDEL_DATA(myClass)
// };
// class myClass
// {
// public:
// gdd_NEWDEL_FUNC(address_to_be_used_for_freelist_next_pointer)
// private:
// gdd_NEWDEL_DATA(myClass)
// };
//
// ** In source file where functions for class are written:
// gdd_NEWDEL_STAT(myClass)
// gdd_NEWDEL_DEL(myClass)
// gdd_NEWDEL_NEW(myClass)
// gdd_NEWDEL_STAT(myClass)
// gdd_NEWDEL_DEL(myClass)
// gdd_NEWDEL_NEW(myClass)
#define gdd_CHUNK_NUM 20
#define gdd_CHUNK(mine) (gdd_CHUNK_NUM*sizeof(mine))
void gddGlobalCleanupAdd ( void * pBuf );
// private data to add to a class
#define gdd_NEWDEL_DATA \
static char* newdel_freelist; \
static gddSemaphore newdel_lock;
static char* newdel_freelist; \
static epicsMutex *pNewdel_lock; \
static epicsThreadOnceId once;
// public interface for the new/delete stuff
// user gives this macro the address they want to use for the next pointer
#define gdd_NEWDEL_FUNC(fld) \
void* operator new(size_t); \
void operator delete(void*); \
char* newdel_next(void) { char** x=(char**)&(fld); return *x; } \
void newdel_setNext(char* n) { char** x=(char**)&(fld); *x=n; }
void* operator new(size_t); \
void operator delete(void*); \
char* newdel_next(void) { char** x=(char**)&(fld); return *x; } \
void newdel_setNext(char* n) { char** x=(char**)&(fld); *x=n; } \
static void gddNewDelInit ( void * ) { pNewdel_lock = new epicsMutex; }
// declaration of the static variable for the free list
#define gdd_NEWDEL_STAT(clas) \
char* clas::newdel_freelist=NULL; \
gddSemaphore clas::newdel_lock;
char* clas::newdel_freelist=NULL; \
epicsMutex * clas::pNewdel_lock = NULL; \
epicsThreadOnceId clas::once = EPICS_THREAD_ONCE_INIT;
// code for the delete function
#define gdd_NEWDEL_DEL(clas) \
void clas::operator delete(void* v) { \
clas* dn = (clas*)v; \
if(dn->newdel_next()==(char*)(-1)) free((char*)v); \
else { \
clas::newdel_lock.take(); \
dn->newdel_setNext(clas::newdel_freelist); \
clas::newdel_freelist=(char*)dn; \
clas::newdel_lock.give(); \
} \
clas* dn = (clas*)v; \
if(dn->newdel_next()==(char*)(-1)) free((char*)v); \
else { \
epicsGuard < epicsMutex > guard ( *clas::pNewdel_lock ); \
dn->newdel_setNext(clas::newdel_freelist); \
clas::newdel_freelist=(char*)dn; \
} \
}
// following function assumes that reading/writing address is atomic
@@ -81,50 +88,31 @@
// code for the new function
#define gdd_NEWDEL_NEW(clas) \
void* clas::operator new(size_t size) { \
int tot; \
clas *nn,*dn; \
if(!clas::newdel_freelist) { \
tot=gdd_CHUNK_NUM; \
nn=(clas*)malloc(gdd_CHUNK(clas)); \
gddCleanUp::Add(nn); \
for(dn=nn;--tot;dn++) dn->newdel_setNext((char*)(dn+1)); \
clas::newdel_lock.take(); \
(dn)->newdel_setNext(clas::newdel_freelist); \
clas::newdel_freelist=(char*)nn; \
clas::newdel_lock.give(); \
} \
if(size==sizeof(clas)) { \
clas::newdel_lock.take(); \
dn=(clas*)clas::newdel_freelist; \
clas::newdel_freelist=((clas*)clas::newdel_freelist)->newdel_next(); \
clas::newdel_lock.give(); \
dn->newdel_setNext(NULL); \
} else { \
dn=(clas*)malloc(size); \
dn->newdel_setNext((char*)(-1)); \
} \
return (void*)dn; \
int tot; \
clas *nn,*dn; \
epicsThreadOnce ( &once, gddNewDelInit, 0 ); \
if(!clas::newdel_freelist) { \
tot=gdd_CHUNK_NUM; \
nn=(clas*)malloc(gdd_CHUNK(clas)); \
gddGlobalCleanupAdd (nn); \
for(dn=nn;--tot;dn++) dn->newdel_setNext((char*)(dn+1)); \
epicsGuard < epicsMutex > guard ( *clas::pNewdel_lock ); \
(dn)->newdel_setNext(clas::newdel_freelist); \
clas::newdel_freelist=(char*)nn; \
} \
if(size==sizeof(clas)) { \
{ \
epicsGuard < epicsMutex > guard ( *clas::pNewdel_lock ); \
dn=(clas*)clas::newdel_freelist; \
clas::newdel_freelist=((clas*)clas::newdel_freelist)->newdel_next(); \
} \
dn->newdel_setNext(NULL); \
} else { \
dn=(clas*)malloc(size); \
dn->newdel_setNext((char*)(-1)); \
} \
return (void*)dn; \
}
class gddCleanUpNode
{
public:
void* buffer;
gddCleanUpNode* next;
};
class gddCleanUp
{
public:
gddCleanUp(void);
~gddCleanUp(void);
static void Add(void*);
static void CleanUp(void);
private:
static gddCleanUpNode* bufs;
static gddSemaphore lock;
};
#endif