NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

A special Rendezvous that works on subsets of processes in the parallel model

I have a parallel model test that works great on 14 UUTs so far, but now I must write some sequences where the processes have to share hardware two at a time. I need to pair up the processes like (0,1), (2,3), (4,5), etc. and have a Rendezvous operate on them two at a time like this:

 

  1. Processes (0,1) operate in parallel.
  2. Processes (2,3) operate in parallel.
  3. Processes (4,5) operate in parallel.
  4. And so on....

 

Given enough time, maybe I could write that programmatically in TestStand; but I hope TestStand has a built-in Rendezvous for subsets of processes, or something else to do that. Does such a thing exist?

0 Kudos
Message 1 of 9
(4,451 Views)

TestStand has a rendezvous step type. You can create them by name so you could have sockets 0,1 use a rendezvous with a name "myRendezvous_0_1". A thread can tell what its socket is by looking at RunState.TestSockets.MyIndex. You could either use that directly to determine what rendezvous name to use, or you could create a file global array of strings where the testsocket index maps to the element in the array with the rendezvous name the socket should use.

 

Hope this helps,

-Doug

0 Kudos
Message 2 of 9
(4,441 Views)

That sounds promising!

 

I am creating these Rendezvous by name and am using them for all sockets, but I don't know how to programmatically assign a process' socket number RunState.TestSockets.MyIndex to a particular Rendezvous like "myRendezvous_0_1".

 

How is that done? I could not find any examples.

 

0 Kudos
Message 3 of 9
(4,432 Views)

The simplest way is create an array of strings as big as the largest number of testsockets you plan on using. Then set the values of the elements to correspond to the rendezvous name you want the testsocket with that index to use. For example:

 

 

Locals.RendezvousNames[RunState.TestSockets.MyIndex]

 

would give you the rendezvous name to use for that socket.

 

-Doug

0 Kudos
Message 4 of 9
(4,422 Views)

I'm almost there (maybe); please correct me if I stop making sense...

 

My system has 14 sockets and I sometimes want to pair them, so I'll have 14/2 = 7 "pairing" Rendezvous.

 

In the Rendezvous' "Rendezvous Name Expression" box I can enter "Locals.RendezvousNames [RunState.TestSockets.MyIndex]", and populate that array with names like "myRendezvous_0_1", "myRendezvous_2_3", etc.

 

I can create those 7 Rendezvous and make them apply to only their specific sockets in their "Precondition" Expression. (Is that how it's done?)

 

If I am still making sense, could I store those 7 Rendezvous globally, like in StationGlobals (I don't see how there)so that all of my test sequences could access them?

0 Kudos
Message 5 of 9
(4,407 Views)

@bmihura wrote:

I'm almost there (maybe); please correct me if I stop making sense...

 

My system has 14 sockets and I sometimes want to pair them, so I'll have 14/2 = 7 "pairing" Rendezvous.

 

1) In the Rendezvous' "Rendezvous Name Expression" box I can enter "Locals.RendezvousNames [RunState.TestSockets.MyIndex]", and populate that array with names like "myRendezvous_0_1", "myRendezvous_2_3", etc.

 

2) I can create those 7 Rendezvous and make them apply to only their specific sockets in their "Precondition" Expression. (Is that how it's done?)

 

3) If I am still making sense, could I store those 7 Rendezvous globally, like in StationGlobals (I don't see how there)so that all of my test sequences could access them?


 

Note that I've numbered your questions above so I can tie them to my answers below:

 

1) Correct. The expression would not be in quotes in the expression edit control though. If you put it in quotes then you are just creating a string constant.

2) I do not understand this question. You shouldn't need to do anything in preconditions at all. You just need to do the create operation with the step type at the beginning of your main sequence and you can use the same expression as in 1) to determine the name. Leave the lifetime as the default "Same as Execution". That should be fine. Then, everywhere you use the rendezvous just reference it by name. If you put the names array in a fileglobal or station global instead then you can access the names from more sequences.

3) I think this is also answered in 2).

 

Note that I'm not sure rendezvous are the right synchronization primitive to use for the synchronization you want. I do not have enough information about how you want your system to work to recommend a synchronization approach for your situation. I'm assuming you know what rendezvous do and have determined they are the right thing to use in your use case.

 

-Doug

0 Kudos
Message 6 of 9
(4,401 Views)

I finally get it! Where are my fake buck teeth? Your idea should work, and I'll try it Monday when I return to the office.

0 Kudos
Message 7 of 9
(4,398 Views)

OK I tried your pairing up idea with six processes (three seperate Rendezvous, one for each pair), but they all still ran in parallel. I'd like for one pair to execute at a time while locking out the others. This is because my system has two electronic loads (and two of many other things) that the six UUTs must share.

0 Kudos
Message 8 of 9
(4,368 Views)

@bmihura wrote:

OK I tried your pairing up idea with six processes (three seperate Rendezvous, one for each pair), but they all still ran in parallel. I'd like for one pair to execute at a time while locking out the others. This is because my system has two electronic loads (and two of many other things) that the six UUTs must share.


Ok, then what you proposed before (a separate rendezvous for each pair of threads) is not the correct way to synchronize things. A rendezvous just causes threads to block until the specified number of threads reaches the rendezvous point. You have three independent pairs of threads running in parallel. If that is not what you want, then using rendezvous like this isn't the right approach.

 

Please describe in more detail the entire flow of execution you are looking for. At what scope do you want the other threads to be blocked? Do you want each pair of threads to run all tests before any other threads can run? Do you want this only around certain steps? or Group of steps? Also, why do you want the threads to be paired? The most straightforward way I can think of to allocate two of a resource is to not care about which thread is using it, but to only allow two threads at a time, they don't necessarily have to be in pairs or even the same two threads every time. Do you really need the threads to be paired?

 

One of the simplest TestStand specific ways to allocate resources is to use the auto-schedule step types. They allow you to define blocks of code which require specific resources and then automatically run those blocks of code when those resources are available. I recommend you read the documentation for these step types and see if that sounds like it will work for you.

 

Another relatively simply way to synchronize access to a fixed number of resources among many threads is with a semaphore. A semaphore allows a certain number of threads through at a time, and blocks other threads until one of the ones using the resource release their acquisition of the semaphore. If the resources involved are more complicated though, I think you are better off using the auto-scheduler step types.


Hope this helps,

-Doug

0 Kudos
Message 9 of 9
(4,358 Views)