02-13-2013 02:24 AM
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:
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?
02-13-2013 09:47 AM
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
02-13-2013 08:10 PM
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.
02-14-2013 11:02 AM - edited 02-14-2013 11:02 AM
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
02-14-2013 06:45 PM
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?
02-15-2013 09:48 AM
@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
02-15-2013 09:59 AM
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.
02-19-2013 11:25 AM
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.
02-20-2013 10:48 AM - edited 02-20-2013 10:50 AM
@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