1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 <2011> 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 | Index | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 <2011> 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | RE: Delay problem in ca_array_put() command |
From: | "Jeff Hill" <[email protected]> |
To: | "'Perrier Pierre'" <[email protected]>, <[email protected]> |
Date: | Mon, 18 Jul 2011 10:46:01 -0600 |
Hello Pierre, Ø I don’t know which type of implementation (Portable CA Server or IOC) is the most Ø efficient. In this case, I started implementing an IOC. is it a good choice ? It’s hard to make specific recommendations without more knowledge of your application. Nevertheless, a strong benefit of using an IOC to control motors will be that you can use all of the EPICS device drivers already written for motors now and in the future if you upgrade. The portable server works well when you have a preexisting data store which needs to be interfaced to EPICS, or when you do not want to configure a subsystem using EPICS records. Ø And to be notified of change events, I’ve created a thread to launch : Ø ca_pend_event (0.0); In a preemptive callback application you will receive callbacks from the ca client library’s auxiliary threads at any time, and accordingly user callback execution isn’t restricted to occur only when executing in the ca client library (as is the case with non-preemptive callback mode). So therefore, a call to ca_pend_event in the thread that you have launched isn’t strictly necessary. Ø The problem occurs when I want to change a PV value. All seems ok but the pv is Ø only really modified 30 seconds to 1 min after the call to ca_array_put (I have Ø tested this in localhost) . To change a value, I proceed in the following manner Ø for a double : Ø ca_array_put(DBR_DOUBLE, 1, channel, &val); Ø status=ca_pend_io(put_timeout); A better approach is as follows. First issue the put request, and second force the output queue to be flushed to the network. ca_array_put(DBR_DOUBLE, 1, channel, &val); ca_flush_io(); The ca_pend_io is a synchronize-by-blocking function which waits for ca get and ca channel connect requests to complete (but such requests will only participate if they are not synchronized by callbacks). Thus, ca_pend_io isn’t typically used with a ca put request. Also, ca_pend_io is used typically only in single threaded ca client applications, and not in a multithreaded (preemptive callback) ca client applications (which are typically synchronized by callbacks). Ø Is this a normal behaviour? If not, how can this issue be solved? No, as soon as the request is flushed out of the output queue it will be delivered immediately to the IOC. While the ca_pend_io function call isn’t appropriate in a put request context, it does nevertheless issue internally a flush request so I _am_ surprised that you see this delay. Are you certain that the delay is in the ca subsystem? The motor record is actually more complex in its implementation than other EPICS records. Perhaps you can use the dbpr command from the IOC’s shell to verify that the field which is the target of the put request is in fact being modified after a delay? Jeff Message content: TSPA From: [email protected] [mailto:[email protected]] On Behalf Of Perrier Pierre Hi everybody, I 'm working on a IOC or Portable CA Server capable of managing other IOC in order to sequence them, for instance. Typically this IOC controls multiple motors, each represented by an IOC. I don’t know which type of implementation (Portable CA Server or IOC) is the most efficient. In this case, I started implementing an IOC. is it a good choice ? More particularly, I’ve a problem with the part of this IOC acting as the client of the others IOC it controls. This client monitors a few PV of the motor’s IOC and all seems ok. It’s a multi-threaded client. I’ve created my CA context with : ca_context_create(ca_enable_preemptive_callback); And to be notified of change events, I’ve created a thread to launch : ca_pend_event (0.0); The problem occurs when I want to change a PV value. All seems ok but the pv is only really modified 30 seconds to 1 min after the call to ca_array_put (I have tested this in localhost) . To change a value, I proceed in the following manner for a double : ca_array_put(DBR_DOUBLE, 1, channel, &val); status=ca_pend_io(put_timeout); Is this a normal behaviour? If not, how can this issue be solved? Thanks in advance, Best regards,
|