Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
<== Date ==> <== Thread ==>

Subject: Re: asynDriver / epicsTimer bug
From: Dirk Zimoch <dirk.zimoch@psi.ch>
To: TECHTALK <tech-talk@aps.anl.gov>
Date: Wed, 31 May 2006 11:27:54 +0200
Hi all,

attached is a test program that can reproduce the problem. Since it uses sysClkRateGet(), it compiles only on vxWorks.

It calls pasynOctet->readRaw() once with pasynUser->timeout=1.1/sysClkRateGet() and once with pasynUser->timeout=1.0/sysClkRateGet().

In the first case, readRaw() returns asynTimeout, as expected. In the second case, readRaw() does not return.

I print the thread ID before calling readRaw(). When I do 'tt' on the thread ID, readRaw() suddenly returns asynTimeout. Very strange.

A Makefile is also attached. No records are required. Just set up a TCP server somewhere, call drvAsynIPPortConfigure and run:
readTimeoutTest "portname".


BTW: As long as readRaw() hangs, I could not open a channel access connection to records on that IOC and the dbior command hangs when trying to report drvAsyn.

I use asynDriver version 4-5, EPICS base R3.14.8, vxWorks 5.5 on MVME2300 (ppc604).

Dirk



Dirk Zimoch wrote:
Hi Marty, Jeff et al

When asynOctet->read() (or at least readRaw() of the TCP port driver) is called on vxWorks with pasynUser->timeout < 1/sysClkRateGet() [normally about 16 ms], the read call hangs and does never time out.

I think it is actually a problem with epicsTimer, which never expires for timeouts < 1/sysClkRateGet(). But I have not tested this.

I think, a timer should wait at least the specified amount of time, thus always round up to at least one tick.

Dirk


-- Dr. Dirk Zimoch Swiss Light Source Paul Scherrer Institut Computing and Controls phone +41 56 310 5182 fax +41 56 310 4413
#include <asynDriver.h>
#include <asynOctet.h>
#include <epicsThread.h>
#include <sysLib.h>

static char* asynStatusStr[] = {"Success", "Timeout", "Overflow", "Error"};

void readTimeoutTestHandleRequest(asynUser* pasynUser)
{
    asynInterface* pasynInterface;
    asynOctet* pasynOctet;
    void* pvtOctet;
    char buffer[1];
    asynStatus status;
    size_t received;
    int eomReason;
    
    printf ("readTimeoutTestHandleRequest, thread = %s %p\n",
        epicsThreadGetNameSelf(), epicsThreadGetIdSelf());
        
    pasynInterface = pasynUser->userPvt;
    pasynOctet =  pasynInterface->pinterface;
    pvtOctet = pasynInterface->drvPvt;
    
    pasynUser->timeout = 1.1 / sysClkRateGet();
    printf ("calling pasynOctet->readRaw() with %g seconds timeout\n",
        pasynUser->timeout);
    status = pasynOctet->readRaw(pvtOctet, pasynUser, buffer, 1,
        &received, &eomReason);
    printf ("pasynOctet->readRaw() returned status %s\n",
        asynStatusStr[status]);
    pasynUser->timeout = 1.0 / sysClkRateGet();
    printf ("calling pasynOctet->readRaw() with %g seconds timeout\n",
        pasynUser->timeout);
    status = pasynOctet->readRaw(pvtOctet, pasynUser, buffer, 1,
        &received, &eomReason);
    printf ("pasynOctet->readRaw() returned status %s\n",
        asynStatusStr[status]);
}

void readTimeoutTestTimeout(asynUser* pasynUser)
{
    printf ("pasynManager->queueRequest() timed out\n");
}


int readTimeoutTest(char * port, int addr)
{
    asynStatus status;
    asynUser* pasynUser;
    asynInterface* pasynInterface;
    
    pasynUser = pasynManager->createAsynUser(readTimeoutTestHandleRequest,
        readTimeoutTestTimeout);
    if (pasynManager->connectDevice(pasynUser, port, addr) !=
        asynSuccess)
    {
        printf ("No such device: %s,%d\n", port, addr);
        return ERROR;
    }
    pasynInterface = pasynManager->findInterface(pasynUser,
        asynOctetType, TRUE);
    if (!pasynInterface)
    {
        printf ("No asynOctet interface: %s,%d\n", port, addr);
        return ERROR;
    }
    pasynUser->userPvt = pasynInterface;
    status = pasynManager->queueRequest(pasynUser,
        asynQueuePriorityHigh, 10.0);
    if (status != asynSuccess)
    {
        printf ("pasynManager->queueRequest() failed: %s\n",
            pasynUser->errorMessage);
        return ERROR;
    }
    return OK;
}
TOP=../..

include $(TOP)/configure/CONFIG

HOST_OPT = NO

PROD_vxWorks = asynApp
DBD  = asynApp.dbd

asynApp_DBD += base.dbd

PROD_SRCS += asynApp_registerRecordDeviceDriver.cpp

PROD_SRCS += readTimeoutTest.c

asynApp_DBD += drvAsynIPPort.dbd
PROD_LIBS += asyn

PROD_LIBS += $(EPICS_BASE_IOC_LIBS)

include $(TOP)/configure/RULES

Replies:
Re: asynDriver / epicsTimer bug Eric Norum
Re: asynDriver / epicsTimer bug Eric Norum
References:
asynDriver / epicsTimer bug Dirk Zimoch

Navigate by Date:
Prev: about building ChannelArchiver for base3.14 Zhao Zhuo
Next: StreamDevice 2.1 released Dirk Zimoch
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
Navigate by Thread:
Prev: Re: asynDriver / epicsTimer bug Benjamin Franksen
Next: Re: asynDriver / epicsTimer bug Eric Norum
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·