LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

efficiently add to queue from dll


@for(imstuck) wrote:

@rolfk wrote:

Something like this

...

 


callback(...., void *data, int len, .....)

{

      MgErr err;

      int32 idx = NextDataInsertIndex();

      if (idx < 0)

           Buffer full!!!!!   

 

      LabVIEWArrayHdl handle = CircularBuf->handles[idx];

      err = NumericArrayResize(uB, 1, &handle, len);

      if (!err)

      {

            MoveBlock(data, (*handle)->elm, len);

            (*handle)->numElm = len;

            CircularBuf->handles[idx] = handle;

      }

}

....

 


 Try that.  Somehow Rolfk got the text all converted to the "Symbol" font.

 

0 Kudos
Message 11 of 17
(1,071 Views)

@Ravens Fan wrote:

@for(imstuck) wrote:

@rolfk wrote:

Something like this

...

 


callback(...., void *data, int len, .....)

{

      MgErr err;

      int32 idx = NextDataInsertIndex();

      if (idx < 0)

           Buffer full!!!!!   

 

      LabVIEWArrayHdl handle = CircularBuf->handles[idx];

      err = NumericArrayResize(uB, 1, &handle, len);

      if (!err)

      {

            MoveBlock(data, (*handle)->elm, len);

            (*handle)->numElm = len;

            CircularBuf->handles[idx] = handle;

      }

}

....

 


 Try that.  Somehow Rolfk got the text all converted to the "Symbol" font.

 


I thought he just wrote code with greek letters. 🙂

0 Kudos
Message 12 of 17
(1,067 Views)

@for(imstuck) wrote:

I thought he just wrote code with greek letters. 🙂



Only when he wants to show off.  He's that good.

0 Kudos
Message 13 of 17
(1,062 Views)

Rolf, Sounds like a good sollution, but what I don't understand is the need to de-allocate. When I  create the LV arrays with NumericArrayResize() isn't it just like any other LV array for which Labview manages the de-allocation?

0 Kudos
Message 14 of 17
(1,058 Views)

Not sure what happened with the font there. Here on my system the stuff looks simply readable even now. I just wanted an even spaced Font because that looks clearer for code than proportional fonts. Oh well! Seems the intended receiver could read it too Smiley LOL

 


@Dixie wrote:

Rolf, Sounds like a good sollution, but what I don't understand is the need to de-allocate. When I  create the LV arrays with NumericArrayResize() isn't it just like any other LV array for which Labview manages the de-allocation?




As to your question: No LabVIEW does not manage memory handles on memory manager level, <sigh>, well it does of course but not in the sense that it maintains a link to when they were created and by whom so it could garbage collect them if the according entity goes out of memory. Instead the diagram that allocates the handles does this lifetime management. But our handles in the circular buffer are not anymore controlled by the diagram, that is the entire trick of this exercise. You pass them in from the diagram and swap them out with one of the handles from the circular buffer and now you own that handle and are responsible to manage its lifetime. It's that simple. If the diagram would still know about them you could go into deep trouble, since it might feel to reallocate them for whatever reasons just at the moment your callback is busy to copy data into it, and that would inevitably lead to bad things.

 

An one other thing: It is important to wire the right side of that Call Library Node parameter too. You are changing in fact the handle and if you only wire the left side, hoping the fact that you pass the array by reference does the right thing, you forget about the LabVIEW optimizer. A Call Library Node parameter that is only wired on the left side is considered by LabVIEW a constant parameter that the function will not modify. So it is free to schedule the CLN with special optimizations that may lead to you loosing the handle that your DLL just swapped out. But if you wire the right side and wire that wire to wherever you need it from there, LabVIEW knows exactly that the CLN needs to execute before the dependant code and will not use this particular schedule optimization that could lead to the loss of the handle.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 15 of 17
(1,054 Views)

@Ravens Fan wrote:

 Try that.  Somehow Rolfk got the text all converted to the "Symbol" font.

 


Damn, I wanted to get the System font, which it doesn't show in the drop down listbox. But the really bad thing is that it looks on my system all totally proper, though the font is not exactly mono spaced. Even for(imstuck)'s response, which was BTW totally cryptic to me Smiley Very Happy, shows fully readable code on my system.

 

Since I can't edit the original post anymore here a hopefully readable copy of it for further reference.

 

If you maintain in your circular buffer not just the C pointer but actual LabVIEW array handles you could swap out those handles in your data collection call. Something like this:

 

typedef struct {

     int32 numElm;

     uInt8 elm[];

} LabVIEWArray, **LabVIEWArrayHdl;

 

typedef struct {

     ......

    LabVIEWArrayHdl handles[];

    .......

} CircularBuffer;

 

MgErr GetNextBuffer(LabVIEWArrayHdl *array)

{

      // Determine if there are any elements in the circular buffer

      int32 idx = NextDataAvailableIndex();

      if (idx >= 0)

      {

            // Copy next available buffer handle

            LabVIEWArrayHdl temp = CircularBuf->handles[idx];

            // Store the passed in handle in its place

            CircularBuf->handles[idx] = *array;

            // pass the handle back to LabVIEW

            *array = temp;

            return noErr;

      }

      return noDataErr;

}

 

And in your callback you do something like this

 

 

callback(...., void *data, int len, .....)

{

      MgErr err;

      int32 idx = NextDataInsertIndex();

      if (idx < 0)

           Buffer full!!!!!   

 

      LabVIEWArrayHdl handle = CircularBuf->handles[idx];

      err = NumericArrayResize(uB, 1, &handle, len);

      if (!err)

      {

            MoveBlock(data, (*handle)->elm, len);

            (*handle)->numElm = len;

            CircularBuf->handles[idx] = handle;

      }

}

 

This does not contain the code about initialization of the circular buffer and maybe almost as importantly about deallocation. For initialization you simply should make sure that the array of handles is all initialized to NULL. NumericArrayResize() is smart enough to allocate a new handle for NULL values, and resizes non NULL handles. For deallocation you need to walk the array and for any element that is not NULL call the DSDisposeHandle() memory manager function. It also does not show the critical section handling that is clearly needed here in order to synchonize the data get and the callback function.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 16 of 17
(1,047 Views)

Veering off-topic here... if you're looking at what you expect to be C code on this forum, but you're seeing a lot of smileys or other strange symbols, try changing your settings so that the forum will not display emoticons, as shown in this screenshot:

no-emoticons.png

0 Kudos
Message 17 of 17
(1,031 Views)