switched to epicsMutex for locking
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user