/* epicsEventTest.cpp */ /* Author: Marty Kraimer Date: 26JAN2000 */ /********************COPYRIGHT NOTIFICATION********************************** This software was developed under a United States Government license described on the COPYRIGHT_UniversityOfChicago file included as part of this distribution. ****************************************************************************/ #include #include #include #include #include #include #include #include "osiThread.h" #include "epicsEvent.h" #include "epicsMutex.h" #include "epicsRingPointer.h" #include "errlog.h" typedef struct info { epicsEventId event; epicsMutexId lockRing; int quit; epicsRingPointerId ring; }info; static void consumer(void *arg) { info *pinfo = (info *)arg; time_t tp; threadId idSelf = threadGetIdSelf(); printf("consumer %p starting time %ld\n",idSelf,time(&tp)); while(1) { epicsEventWaitStatus status; if(pinfo->quit) { printf("consumer %p returning time %ld\n", idSelf,time(&tp)); return; } status = epicsEventWait(pinfo->event); if(status!=epicsEventWaitOK) { printf("task %p epicsEventWait returned %d time %ld\n", idSelf,(int)status,time(&tp)); } while(epicsRingPointerGetUsed(pinfo->ring)>=2) { threadId message[2]; int i; for(i=0; i<2; i++) { if(!(message[i]=epicsRingPointerPop(pinfo->ring))) printf("consumer error\n"); } if(message[0]!=message[1]) { printf("consumer error message %p %p\n",message[0],message[1]); } else { printf("consumer message from %p\n",message[0]); } } } } static void producer(void *arg) { info *pinfo = (info *)arg; time_t tp; threadId idSelf = threadGetIdSelf(); int ntimes=0; printf("producer %p starting time %ld\n",idSelf,time(&tp)); while(1) { epicsMutexLockStatus status; ++ntimes; if(pinfo->quit) { printf("producer %p returning time %ld\n", idSelf,time(&tp)); return; } status = epicsMutexLock(pinfo->lockRing); if(status!=epicsMutexLockOK) { printf("producer %p epicsMutexLock returned %d time %ld\n", idSelf,(int)status,time(&tp)); } if(epicsRingPointerGetFree(pinfo->ring)>=2) { int i; for(i=0; i<2; i++) { if(!epicsRingPointerPush(pinfo->ring,idSelf)) printf("producer %p error\n",idSelf); if(i==0 && (ntimes%4==0)) threadSleep(.1); } printf("producer %p sending\n",idSelf); } else { printf("producer %p ring buffer is full\n",idSelf); } epicsMutexUnlock(pinfo->lockRing); threadSleep(1.0); epicsEventSignal(pinfo->event); } } extern "C" void epicsEventTest(int nthreads,int verbose) { unsigned int stackSize; threadId *id; char **name; int i; info *pinfo; epicsEventId event; int status; time_t tp; int errVerboseSave = errVerbose; threadInit (); errVerbose = verbose; event = epicsEventMustCreate(epicsEventEmpty); printf("calling epicsEventWaitWithTimeout(event,2.0) time %ld\n",time(&tp)); status = epicsEventWaitWithTimeout(event,2.0); if(status!=epicsEventWaitTimeout) printf("status %d\n",status); printf("calling epicsEventTryWait(event) time %ld\n",time(&tp)); status = epicsEventTryWait(event); if(status!=epicsEventWaitTimeout) printf("status %d\n",status); printf("calling epicsEventSignal() time %ld\n",time(&tp)); epicsEventSignal(event); printf("calling epicsEventWaitWithTimeout(event,2.0) time %ld\n",time(&tp)); status = epicsEventWaitWithTimeout(event,2.0); if(status) printf("status %d\n",status); printf("calling epicsEventSignal() time %ld\n",time(&tp)); epicsEventSignal(event); printf("calling epicsEventTryWait(event) time %ld\n",time(&tp)); status = epicsEventTryWait(event); if(status) printf("status %d\n",status); if(nthreads<=0) { errVerbose = errVerboseSave; return; } pinfo = (info *)calloc(1,sizeof(info)); pinfo->event = event; pinfo->lockRing = epicsMutexCreate(); pinfo->ring = epicsRingPointerCreate(1024*2); stackSize = threadGetStackSize(threadStackSmall); threadCreate("consumer",50,stackSize,consumer,pinfo); id = (threadId *)calloc(nthreads,sizeof(threadId)); name = (char **)calloc(nthreads,sizeof(char *)); for(i=0; iquit = 1; threadSleep(2.0); epicsEventSignal(pinfo->event); threadSleep(1.0); printf("semTest returning time %ld\n",time(&tp)); errVerbose = errVerboseSave; }