diff --git a/src/ca/iocinf.h b/src/ca/iocinf.h index 92b694691..00436bf23 100644 --- a/src/ca/iocinf.h +++ b/src/ca/iocinf.h @@ -32,6 +32,9 @@ /************************************************************************/ /* $Log$ + * Revision 1.61 1997/04/23 17:05:07 jhill + * pc port changes + * * Revision 1.60 1997/04/10 19:26:24 jhill * asynch connect, faster connect, ... * @@ -342,7 +345,6 @@ typedef struct caclient_put_notify{ #define pndrecvcnt (ca_static->ca_pndrecvcnt) #define ioeventlist (ca_static->ca_ioeventlist) #define nxtiiu (ca_static->ca_nxtiiu) -#define free_event_list (ca_static->ca_free_event_list) #define pend_read_list (ca_static->ca_pend_read_list) #define pend_write_list (ca_static->ca_pend_write_list) #define fd_register_func\ @@ -361,7 +363,6 @@ typedef struct caclient_put_notify{ # define client_lock (ca_static->ca_client_lock) # define event_lock (ca_static->ca_event_lock) # define local_chidlist (ca_static->ca_local_chidlist) -# define dbfree_ev_list (ca_static->ca_dbfree_ev_list) # define lcl_buff_list (ca_static->ca_lcl_buff_list) # define event_tid (ca_static->ca_event_tid) #endif @@ -482,13 +483,10 @@ typedef struct { struct ca_static{ ELLLIST ca_iiuList; ELLLIST ca_ioeventlist; - ELLLIST ca_free_event_list; ELLLIST ca_pend_read_list; ELLLIST ca_pend_write_list; ELLLIST activeCASG; - ELLLIST freeCASG; ELLLIST activeCASGOP; - ELLLIST freeCASGOP; ELLLIST putCvrtBuf; ELLLIST fdInfoFreeList; ELLLIST fdInfoList; @@ -511,6 +509,9 @@ struct ca_static{ BUCKET *ca_pSlowBucket; BUCKET *ca_pFastBucket; bhe *ca_beaconHash[BHT_INET_ADDR_MASK+1]; + void *ca_ioBlockFreeListPVT; + void *ca_sgFreeListPVT; + void *ca_sgopFreeListPVT; ciu ca_pEndOfBCastList; unsigned long ca_search_responses; /* num valid search resp within seq # */ unsigned long ca_search_tries; /* num search tries within seq # */ @@ -536,11 +537,11 @@ struct ca_static{ SEM_ID ca_event_lock; /* dont allow events to preempt */ SEM_ID ca_putNotifyLock; ELLLIST ca_local_chidlist; - ELLLIST ca_dbfree_ev_list; ELLLIST ca_lcl_buff_list; ELLLIST ca_putNotifyQue; ELLLIST ca_taskVarList; void *ca_evuser; + void *ca_dbMonixFreeList; int ca_event_tid; int ca_tid; int recv_tid; diff --git a/src/ca/syncgrp.c b/src/ca/syncgrp.c index 0ddeb8164..e2406148e 100644 --- a/src/ca/syncgrp.c +++ b/src/ca/syncgrp.c @@ -29,6 +29,9 @@ * Modification Log: * ----------------- * $Log$ + * Revision 1.22 1996/11/22 19:08:02 jhill + * added const to API + * * Revision 1.21 1996/11/02 00:51:08 jhill * many pc port, const in API, and other changes * @@ -55,6 +58,7 @@ */ #include "iocinf.h" +#include "freeList.h" LOCAL void io_complete(struct event_handler_args args); @@ -67,8 +71,8 @@ void ca_sg_init(void) /* * init all sync group lists */ - ellInit(&ca_static->activeCASG); - ellInit(&ca_static->freeCASG); + freeListInitPvt(&ca_static->ca_sgFreeListPVT,sizeof(CASG),32); + freeListInitPvt(&ca_static->ca_sgopFreeListPVT,sizeof(CASGOP),256); return; } @@ -99,13 +103,13 @@ void ca_sg_shutdown(struct ca_static *ca_temp) /* * per sync group */ - ellFree (&ca_temp->freeCASG); + freeListCleanup(ca_temp->ca_sgFreeListPVT); /* * per sync group op */ ellFree (&ca_temp->activeCASGOP); - ellFree (&ca_temp->freeCASGOP); + freeListCleanup(ca_temp->ca_sgopFreeListPVT); UNLOCK; @@ -132,15 +136,13 @@ int epicsShareAPI ca_sg_create(CA_SYNC_GID *pgid) * first look on a free list. If not there * allocate dynamic memory for it. */ - LOCK; - pcasg = (CASG *) ellGet(&ca_static->freeCASG); + pcasg = (CASG *) freeListMalloc(ca_static->ca_sgFreeListPVT); if(!pcasg){ - pcasg = (CASG *) malloc(sizeof(*pcasg)); - if(!pcasg){ - return ECA_ALLOCMEM; - } + return ECA_ALLOCMEM; } + LOCK; + /* * setup initial values for all of the fields * @@ -170,7 +172,7 @@ int epicsShareAPI ca_sg_create(CA_SYNC_GID *pgid) /* * place it back on the free sync group list */ - ellAdd (&ca_static->freeCASG, &pcasg->node); + freeListFree(ca_static->ca_sgFreeListPVT, pcasg); UNLOCK; if (status == S_bucket_noMemory) { return ECA_ALLOCMEM; @@ -217,10 +219,10 @@ int epicsShareAPI ca_sg_delete(const CA_SYNC_GID gid) pcasg->magic = 0; ellDelete(&ca_static->activeCASG, &pcasg->node); - ellAdd(&ca_static->freeCASG, &pcasg->node); - UNLOCK; + freeListFree(ca_static->ca_sgFreeListPVT, pcasg); + return ECA_NORMAL; } @@ -417,24 +419,21 @@ const void *pvalue) CASGOP *pcasgop; CASG *pcasg; - LOCK; - pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid); - if(!pcasg || pcasg->magic != CASG_MAGIC){ - UNLOCK; - return ECA_BADSYNCGRP; - } - /* * first look on a free list. If not there * allocate dynamic memory for it. */ - pcasgop = (CASGOP *)ellGet(&ca_static->freeCASGOP); + pcasgop = (CASGOP *) freeListMalloc(ca_static->ca_sgopFreeListPVT); if(!pcasgop){ - pcasgop = (CASGOP *)malloc(sizeof(*pcasgop)); - if(!pcasgop){ - UNLOCK; - return ECA_ALLOCMEM; - } + return ECA_ALLOCMEM; + } + + LOCK; + pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid); + if(!pcasg || pcasg->magic != CASG_MAGIC){ + UNLOCK; + freeListFree(ca_static->ca_sgopFreeListPVT, pcasgop); + return ECA_BADSYNCGRP; } memset((char *)pcasgop, 0,sizeof(*pcasgop)); @@ -459,8 +458,8 @@ const void *pvalue) assert(pcasg->opPendCount>=1u); pcasg->opPendCount--; ellDelete(&ca_static->activeCASGOP, &pcasgop->node); - ellAdd(&ca_static->freeCASGOP, &pcasgop->node); UNLOCK; + freeListFree(ca_static->ca_sgopFreeListPVT, pcasgop); } @@ -483,24 +482,21 @@ void *pvalue) CASGOP *pcasgop; CASG *pcasg; - LOCK; - pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid); - if(!pcasg || pcasg->magic != CASG_MAGIC){ - UNLOCK; - return ECA_BADSYNCGRP; - } - /* * first look on a free list. If not there * allocate dynamic memory for it. */ - pcasgop = (CASGOP *)ellGet(&ca_static->freeCASGOP); + pcasgop = (CASGOP *) freeListMalloc(ca_static->ca_sgopFreeListPVT); if(!pcasgop){ - pcasgop = (CASGOP *) malloc(sizeof(*pcasgop)); - if(!pcasgop){ - UNLOCK; - return ECA_ALLOCMEM; - } + return ECA_ALLOCMEM; + } + + LOCK; + pcasg = bucketLookupItemUnsignedId(pSlowBucket, &gid); + if(!pcasg || pcasg->magic != CASG_MAGIC){ + UNLOCK; + freeListFree(ca_static->ca_sgopFreeListPVT, pcasgop); + return ECA_BADSYNCGRP; } memset((char *)pcasgop, 0,sizeof(*pcasgop)); @@ -525,8 +521,8 @@ void *pvalue) assert(pcasg->opPendCount>=1u); pcasg->opPendCount--; ellDelete(&ca_static->activeCASGOP, &pcasgop->node); - ellAdd(&ca_static->freeCASGOP, &pcasgop->node); UNLOCK; + freeListFree(ca_static->ca_sgopFreeListPVT, pcasgop); } return status; } @@ -547,7 +543,6 @@ LOCAL void io_complete(struct event_handler_args args) LOCK; ellDelete(&ca_static->activeCASGOP, &pcasgop->node); pcasgop->magic = 0; - ellAdd(&ca_static->freeCASGOP, &pcasgop->node); /* * ignore stale replies @@ -567,6 +562,7 @@ LOCAL void io_complete(struct event_handler_args args) pcasgop->id, ca_message(args.status)); UNLOCK; + freeListFree(ca_static->ca_sgopFreeListPVT, pcasgop); return; } @@ -587,6 +583,8 @@ LOCAL void io_complete(struct event_handler_args args) UNLOCK; + freeListFree(ca_static->ca_sgopFreeListPVT, pcasgop); + /* * Wake up any tasks pending * diff --git a/src/ca/vxWorks_depen.c b/src/ca/vxWorks_depen.c index b7a1901b7..57a8c7433 100644 --- a/src/ca/vxWorks_depen.c +++ b/src/ca/vxWorks_depen.c @@ -29,6 +29,9 @@ * Modification Log: * ----------------- * $Log$ + * Revision 1.29 1997/04/23 17:05:10 jhill + * pc port changes + * * Revision 1.28 1997/04/10 19:26:19 jhill * asynch connect, faster connect, ... * @@ -63,6 +66,7 @@ #include "iocinf.h" #include "remLib.h" #include "dbEvent.h" +#include "freeList.h" LOCAL void ca_repeater_task(); LOCAL void ca_task_exit_tcb(WIND_TCB *ptcb); @@ -364,11 +368,13 @@ int cac_os_depen_init(struct ca_static *pcas) int status; ellInit(&pcas->ca_local_chidlist); - ellInit(&pcas->ca_dbfree_ev_list); ellInit(&pcas->ca_lcl_buff_list); ellInit(&pcas->ca_taskVarList); ellInit(&pcas->ca_putNotifyQue); + freeListInitPvt(&pcas->ca_dbMonixFreeList, + db_sizeof_event_block()+sizeof(struct pending_event),256); + pcas->ca_tid = taskIdSelf(); pcas->ca_client_lock = semMCreate(SEM_DELETE_SAFE); assert(pcas->ca_client_lock); @@ -481,7 +487,7 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid) status = db_cancel_event((struct event_block *)(monix+1)); LOCK; assert(status == OK); - free(monix); + freeListFree (ca_static->ca_dbMonixFreeList, monix); } if (chix->ppn) { CACLIENTPUTNOTIFY *ppn; @@ -550,8 +556,7 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid) * remove local chid blocks, paddr blocks, waiting ev blocks */ ellFree(&pcas->ca_local_chidlist); - ellFree(&pcas->ca_dbfree_ev_list); - + freeListCleanup(pcas->ca_dbMonixFreeList); /* * remove semaphores here so that ca_process_exit() @@ -918,12 +923,30 @@ void cac_recv_task(int tid) cac_clean_iiu_list(); /* + * first check for pending recv's with a + * zero time out so that + * 1) flow control works correctly (and) + * 2) we queue up sends resulting from recvs properly + */ + while (TRUE) { + LD_CA_TIME (0.0, &timeout); + count = cac_select_io(&timeout, CA_DO_RECVS); + if (count<=0) { + break; + } + ca_process_input_queue(); + } + + /* + * flush out all pending io prior to blocking + * * NOTE: this must be longer than one vxWorks * tick or we will infinite loop */ - timeout.tv_usec = (4*USEC_PER_SEC)/sysClkRateGet(); + timeout.tv_usec = (4/*ticks*/ * USEC_PER_SEC)/sysClkRateGet(); timeout.tv_sec = 0; - count = cac_select_io(&timeout, CA_DO_RECVS); + count = cac_select_io(&timeout, + CA_DO_RECVS|CA_DO_SENDS); ca_process_input_queue(); manage_conn(); #endif diff --git a/src/libCom/bucketLib.c b/src/libCom/bucketLib.c index 3e3ccc073..2763d3abf 100644 --- a/src/libCom/bucketLib.c +++ b/src/libCom/bucketLib.c @@ -362,9 +362,11 @@ BUCKET *bucketCreate (unsigned nHashTableEntries) pb->hashIdMask = mask; pb->hashIdNBits = nbits; + freeListInitPvt(&pb->freeListPVT, sizeof(ITEM), 1024); pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable)); if (!pb->pTable) { + freeListCleanup(pb->freeListPVT); free (pb); return NULL; } @@ -394,12 +396,7 @@ BUCKET *prb; /* * free the free list */ - pi = prb->pFreeItems; - while (pi) { - pni = pi->pItem; - free (pi); - pi = pni; - } + freeListCleanup(prb->freeListPVT); free (prb->pTable); free (prb); @@ -433,15 +430,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const vo * try to get it off the free list first. If * that fails then malloc() */ - pi = prb->pFreeItems; - if (pi) { - prb->pFreeItems = pi->pItem; - } - else { - pi = (ITEM *) malloc (sizeof(ITEM)); - if(!pi){ - return S_bucket_noMemory; - } + pi = (ITEM *) freeListMalloc(prb->freeListPVT); + if (!pi) { + return S_bucket_noMemory; } /* @@ -459,6 +450,7 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const vo */ ppiExists = (*pBSET->pCompare) (ppi, pId); if (ppiExists) { + freeListFree(prb->freeListPVT,pi); return S_bucket_idInUse; } pi->pItem = *ppi; @@ -508,8 +500,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId) /* * stuff it on the free list */ - pi->pItem = prb->pFreeItems; - prb->pFreeItems = pi; + freeListFree(prb->freeListPVT, pi); return S_bucket_success; } @@ -575,27 +566,12 @@ BUCKET *pb; double stdDev; unsigned count; unsigned maxEntries; - unsigned freeListCount; - - /* - * count bytes on the free list - */ - pi = pb->pFreeItems; - freeListCount = 0; - while (pi) { - freeListCount++; - pni = pi->pItem; - pi = pni; - } printf( "Bucket entries in use = %d bytes in use = %ld\n", pb->nInUse, (long) (sizeof(*pb)+(pb->hashIdMask+1)* sizeof(ITEM *)+pb->nInUse*sizeof(ITEM))); - printf( "Free list bytes in use = %ld\n", - (long)(freeListCount*sizeof(ITEM))); - ppi = pb->pTable; nElem = pb->hashIdMask+1; X = 0.0; diff --git a/src/libCom/bucketLib.h b/src/libCom/bucketLib.h index 6d4439e94..70b2d0008 100644 --- a/src/libCom/bucketLib.h +++ b/src/libCom/bucketLib.h @@ -33,6 +33,9 @@ * .02 121693 joh added bucketFree() * .03 052395 joh use std EPICS status * $Log$ + * Revision 1.3 1997/04/10 19:45:35 jhill + * API changes and include with not <> + * * Revision 1.2 1996/06/19 19:44:53 jhill * C++ support * @@ -63,11 +66,11 @@ typedef struct item{ }ITEM; typedef struct bucket{ - ITEM **pTable; - ITEM *pFreeItems; - unsigned hashIdMask; - unsigned hashIdNBits; - unsigned nInUse; + ITEM **pTable; + void *freeListPVT; + unsigned hashIdMask; + unsigned hashIdNBits; + unsigned nInUse; }BUCKET; diff --git a/src/libCom/bucketLib/bucketLib.c b/src/libCom/bucketLib/bucketLib.c index 3e3ccc073..2763d3abf 100644 --- a/src/libCom/bucketLib/bucketLib.c +++ b/src/libCom/bucketLib/bucketLib.c @@ -362,9 +362,11 @@ BUCKET *bucketCreate (unsigned nHashTableEntries) pb->hashIdMask = mask; pb->hashIdNBits = nbits; + freeListInitPvt(&pb->freeListPVT, sizeof(ITEM), 1024); pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable)); if (!pb->pTable) { + freeListCleanup(pb->freeListPVT); free (pb); return NULL; } @@ -394,12 +396,7 @@ BUCKET *prb; /* * free the free list */ - pi = prb->pFreeItems; - while (pi) { - pni = pi->pItem; - free (pi); - pi = pni; - } + freeListCleanup(prb->freeListPVT); free (prb->pTable); free (prb); @@ -433,15 +430,9 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const vo * try to get it off the free list first. If * that fails then malloc() */ - pi = prb->pFreeItems; - if (pi) { - prb->pFreeItems = pi->pItem; - } - else { - pi = (ITEM *) malloc (sizeof(ITEM)); - if(!pi){ - return S_bucket_noMemory; - } + pi = (ITEM *) freeListMalloc(prb->freeListPVT); + if (!pi) { + return S_bucket_noMemory; } /* @@ -459,6 +450,7 @@ LOCAL int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const vo */ ppiExists = (*pBSET->pCompare) (ppi, pId); if (ppiExists) { + freeListFree(prb->freeListPVT,pi); return S_bucket_idInUse; } pi->pItem = *ppi; @@ -508,8 +500,7 @@ LOCAL int bucketRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId) /* * stuff it on the free list */ - pi->pItem = prb->pFreeItems; - prb->pFreeItems = pi; + freeListFree(prb->freeListPVT, pi); return S_bucket_success; } @@ -575,27 +566,12 @@ BUCKET *pb; double stdDev; unsigned count; unsigned maxEntries; - unsigned freeListCount; - - /* - * count bytes on the free list - */ - pi = pb->pFreeItems; - freeListCount = 0; - while (pi) { - freeListCount++; - pni = pi->pItem; - pi = pni; - } printf( "Bucket entries in use = %d bytes in use = %ld\n", pb->nInUse, (long) (sizeof(*pb)+(pb->hashIdMask+1)* sizeof(ITEM *)+pb->nInUse*sizeof(ITEM))); - printf( "Free list bytes in use = %ld\n", - (long)(freeListCount*sizeof(ITEM))); - ppi = pb->pTable; nElem = pb->hashIdMask+1; X = 0.0; diff --git a/src/libCom/bucketLib/bucketLib.h b/src/libCom/bucketLib/bucketLib.h index 6d4439e94..70b2d0008 100644 --- a/src/libCom/bucketLib/bucketLib.h +++ b/src/libCom/bucketLib/bucketLib.h @@ -33,6 +33,9 @@ * .02 121693 joh added bucketFree() * .03 052395 joh use std EPICS status * $Log$ + * Revision 1.3 1997/04/10 19:45:35 jhill + * API changes and include with not <> + * * Revision 1.2 1996/06/19 19:44:53 jhill * C++ support * @@ -63,11 +66,11 @@ typedef struct item{ }ITEM; typedef struct bucket{ - ITEM **pTable; - ITEM *pFreeItems; - unsigned hashIdMask; - unsigned hashIdNBits; - unsigned nInUse; + ITEM **pTable; + void *freeListPVT; + unsigned hashIdMask; + unsigned hashIdNBits; + unsigned nInUse; }BUCKET;