On 19/05/2004 at 9:00 AM, Scott Hannahs <[EMAIL PROTECTED]> wrote:

> At 7:58 -0500 5/19/04, [EMAIL PROTECTED] wrote:
>> If the task acquires a finite number of samples and you set this
>> input to -1, the VI waits for the task to acquire all requested
>> samples, then reads those samples.
>
> Is this a blocking wait like the non-DAQmx call into a CIN (or LLB) or
> is it a "LV style" wait where other LV nodes even in the same thread
> can execute? That would be nice! Is there a way to do this threading
> in our own created dlls (frameworks)?. I would like to make my PCI-
> GPIB library non-blocking but that is not trivial because of this
> limitation. Is there a way to set up a call back into LV for a non-
> blocking wait from a CIN or framework?

I'm not sure exactly what you are asking; so, I'll define some terms,
explain a couple of things, and hope I get lucky :)  For example, I'm
not sure what you mean by a "LV style" wait.  I'm not aware of a
construct that would allow a thread to wait on a synchronization
primitive and yet continue to execute.  That is, a thread is either
running or waiting.  If my definition of an asynchronous call matches
your definition of a "LV style" wait, great.  If not, please let me know
what you have in mind.

So, here are some definitions that I'll use.  Note that these aren't
necessary standard definitions, but I'll use them is this mail:

Synchronous call:  the thread that invokes the call performs the
specified operation in its entirety.  When the calling thread has
returned to its originating context, the operation has been completed
either successfully or unsuccessfully.  Most VIs, including the DAQmx
Read VI, operate in this fashion.

Asynchronous call:  the thread that invokes the call doesn't perform the
specified operation in its entirety but, rather, schedules another
thread to perform the operation.  When the calling thread has returned
to its originating context, the operation may or may not have been
completed.  Usually, there is a mechanism where either the scheduled
thread "calls back" to inform the application of the status of the
operation or the calling thread can invoke another call to check on the
status of the operation.  Few VIs operate in this fashion.  From a
certain perspective, the DAQmx Write VI operates in this fashion when
performing a generation timed by a method other than on-demand timing.
That is, the DAQmx Write VI may return before all samples are generated.
The DAQmx Is Task Done VI is used to query the status of this
asynchronous operation.  (The validity of this example is dependent on
the perspective that the operation performed by the DAQmx Write VI is to
generate all samples from the device rather than to only copy the
samples to the device.)

These two types of calls present fundamentally different API models.  In
general, synchronous calls cannot simply be converted to asynchronous
calls without changing the semantics of the API and adding additional
concepts (e.g., call backs, query calls).

Regardless of the type of call, other threads in the application may
continue to execute.  There are at least a couple of factors that
determine how these other threads may be constrained by the thread
making the call.  One factor is how the synchronous call waits.  If the
thread is continuously trying to execute code to check the status of a
pending operation (i.e., polling), other threads will be competing with
this thread for the processor.  However, if the thread waits on a
synchronization primitive, other threads will not be competing with this
thread until this synchronization primitive is signaled and the thread
is awakened.  The polling approach is more responsive (i.e., the change
in status is detected more quickly) and less efficient (i.e., the
processor is used more) than the thread waiting on a synchronization
primitive.  The DAQmx Read VI falls somewhere between these two extremes
in an attempt to balance responsiveness and efficiency.

A second factor relates to what kind of locks are acquired by the call
(either a synchronous or asynchronous call).  A call that acquires a
very general lock that other threads in the system may need (e.g.,
Traditional NI-DAQ VIs that acquire a lock for all of Traditional
NI-DAQ) will prevent any other threads from acquiring that same lock;
these other threads will wait for the lock to be released.  However, a
call that acquires a more specific lock (e.g., DAQmx VIs that acquire a
lock for a specific task) will only prevent other threads that try to
acquire that specific lock from executing.

While I'm certainly not an NI-488.2 expert, I believe there are both
synchronous and asynchronous functions in NI-488.2.  Regardless, other
threads in your application should be able to execute while a NI-488.2
call is waiting subject to the restrictions I've mentioned.  If you're
concerned that your PCI-GPIB library is too inefficient when waiting and
it is polling, maybe you can change its implementation such that the
thread waits on a synchronization object rather than polls (or at least
occasionally yields to give other threads more of a chance to use the
processor).  If you're concerned that other threads in your application
cannot execute because the thread that is waiting has acquired a common
lock, perhaps the lock can be eliminated or a finer-grained lock can be
used instead.  If you really want other LV nodes to be executed by the
same thread that is calling into your library, you need to structure
your API to be asynchronous and provide other mechanisms to communicate
the status of these asynchronous operations.

I hope this helps.

geoff
-- 
Geoffrey Schmit
Senior Software Engineer
National Instruments
[EMAIL PROTECTED]
www.ni.com


Reply via email to