# "Perform" and Concurrency

**URL:** <https://forum.bome.com/t/perform-and-concurrency/7120>\
**Category:** Bome Products\
**Tags:** perform\
**Created:** [March 26, 2025, 8:48am UTC](https://forum.bome.com/t/perform-and-concurrency/7120 "2025-03-26T08:48:46Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Clint.Goss](https://forum.bome.com/user_avatar/forum.bome.com/clint.goss/32/5105_2.png) [@Clint.Goss](https://forum.bome.com/u/Clint.Goss)\
**Post date:** [March 26, 2025, 8:48am UTC](https://forum.bome.com/t/perform-and-concurrency/7120/1 "2025-03-26T08:48:46Z")

</div>

My proficiency with concurrent processing is pretty low. (\*\*)

I got bit a few times recently with the sequence of triggering Perform Actions, and I would like to confirm that the way I _ **think** _ it works is correct and will always continue to work, in any runtime environment.

Here is what I found that does _ **not** _ work:

- Do Stuff A
- Perform B
- Do stuff C that depends on B having been completed.

I was thinking of a Perform like a Subroutine / Subprogram. Bad news.

Now I understand that B is queued for later execution, which happens after C. So I changed it to:

- Do Stuff A
- Perform B
- Perform C

… and created a new Perform C translator for all the C stuff that depends on B having been completed. However, my question is:

**Will the Perform C _always_ execute after the Perform B?** … or is there some multi-threaded situation where Perform C could precede Perform B?

Even worse, **If B does a Perform B2, will that execute _after_ the Perform C?**

(\*\*) Worked at NYU on some of the core multi-threading code on the first validated Ada compiler (written in an amazing set-based language, appropriately called SETL). Despite that, I’m constantly blindsided when I actually use concurrency … If I were a Dining Philosopher, I’d starve.

---

<div class="post-metadata">

**Author:** ![SteveC](https://forum.bome.com/user_avatar/forum.bome.com/stevec/32/8250_2.png) [@SteveC](https://forum.bome.com/u/SteveC)\
**Post date:** [March 26, 2025, 3:13pm UTC](https://forum.bome.com/t/perform-and-concurrency/7120/2 "2025-03-26T15:13:03Z")

</div>

Hi,

Unlike function calls perform doesn’t return anything so you would need to store the return state in a global variable.

The below example might be what you are looking for. I have a Main perform ‘Dispatch’ that calls Perform A, B and C respectively. Perform A is called with no delay and B and C with 100ms delay. The main program also calls itself so that it is essentially polling until all actions are completed. I use the global variable ga to track the return status (whether it has been completed or not).

When the last return has been completed, the value of ga will be \>2 and the recurring perform ‘Dispatch’ will stop.

A word of caution, since Dispatch is a recurring perform, it is advisable to have a way to make it stop to prevent consistent spinning.  
For this reason I have a translator (0.5) that when triggered, sets the value to 100 so the perform stops on the next iteration.

I added log messages within the rules of the translators so you can watch the action in the log window.

[Perform-Wait-Example-2025-03-26.bmtp](https://forum.bome.com/uploads/short-url/u5EXr1GG1mwT3uJ1RdDtoXMZYeW.bmtp) (2.4 KB)

Steve Caldwell  
Bome Customer Care

* * *
_Also available for paid consulting services: bome@sniz.biz_

---

<div class="post-metadata">

**Author:** ![Clint.Goss](https://forum.bome.com/user_avatar/forum.bome.com/clint.goss/32/5105_2.png) [@Clint.Goss](https://forum.bome.com/u/Clint.Goss)\
**Post date:** [March 28, 2025, 5:21am UTC](https://forum.bome.com/t/perform-and-concurrency/7120/3 "2025-03-28T05:21:38Z")

</div>

Thanks Steve!

So this situation happens a **lot** in the .BMTP for my current rig, and the machinery of the timers would be a significant amount of machinery to install.

I am hoping that what I’m currently seeing … that when I have in my rules:

- Perform B
- Perform C

Whether it is guaranteed that the actions in C will always happen after the actions in B.

… If that is **not** the case, then I’ve probably got some ‘subroutine unraveling’ to do (rather than timers set in a Dispatch).

---

<div class="post-metadata">

**Author:** ![SteveC](https://forum.bome.com/user_avatar/forum.bome.com/stevec/32/8250_2.png) [@SteveC](https://forum.bome.com/u/SteveC)\
**Post date:** [March 28, 2025, 12:33pm UTC](https://forum.bome.com/t/perform-and-concurrency/7120/4 "2025-03-28T12:33:53Z")

</div>

Hi,

Translators can happen in parallel and are not dependent on the previous translator from completing. They are designed to do that for performance reasons. Without using something like my example, there is no guarantee of completion status or the order in which they complete.

My example didn’t use timers but rather a recurring perform translator and a global variable to ensure the previous perform translator completed before triggering the next one.

Also in my example, the status (value of the global variable) just indicates the perform action completed and not any king of “return” status to the calling translator.

Sorry!

Steve Caldwell  
Bome Customer Care

* * *
_Also available for paid consulting services: bome@sniz.biz_

---

<div class="post-metadata">

**Author:** ![FlorianBome](https://forum.bome.com/user_avatar/forum.bome.com/florianbome/32/2367_2.png) [@FlorianBome](https://forum.bome.com/u/FlorianBome)\
**Post date:** [March 28, 2025, 1:35pm UTC](https://forum.bome.com/t/perform-and-concurrency/7120/6 "2025-03-28T13:35:31Z")

</div>

Hi,  
interesting discussion! Steve’s replies are correct, however, there is a trick to force serialization of events.

But first, I’d like to make sure you understand how concurrency can happen. The MIDI processing engine receives events from a variety of sources, e.g. MIDI devices, keystrokes, etc. These incoming events can happen concurrently, i.e. a MIDI message from device A can be processed at the same time (literally) as an incoming MIDI message from device B. The incoming and Rules sections of such translators will be executed in parallel, too. Now for the outgoing action, it depends on a number of factors when it will get executed:

- some outgoing actions are executed ‘in place’, i.e. in the same context as the incoming action. For example, sending MIDI. In the example above, if both translators from device A and device B send MIDI as outgoing action, they will send their messages concurrently.
- other outgoing actions are forced to be placed on an asynchronous queue (‘dispatcher’). This is is true for all outgoing actions that are ‘slow’ like keystroke emulation (to not hold up event processing of incoming actions).
- specifying a delay for an outgoing action will also put the outgoing action on the dispatcher queue.

The dispatcher works in parallel to incoming event processing, but for events of the same type, they are guaranteed to be executed by the dispatcher in order received and _one after another_.

So a trick to force outgoing actions to be put on the dispatcher queue is to specify a delay of 1 millisecond. In most cases, a delay of 1ms is not noticeable, but it will ensure that Perform B is fully processed before Perform C is executed.

When using Perform as outgoing action, this trick will only ensure that the incoming Perform event (and associated Rules) will be executed _before_ Perform C is executed. If a matching translator’s outgoing action is sent to the dispatcher (according to the rules above), it will be executed _after_ Perform C is executed.

I hope that makes sense! A diagram would be nice, but hard to get right, I guess.

---

<div class="post-metadata">

**Author:** ![Clint.Goss](https://forum.bome.com/user_avatar/forum.bome.com/clint.goss/32/5105_2.png) [@Clint.Goss](https://forum.bome.com/u/Clint.Goss)\
**Post date:** [March 28, 2025, 5:14pm UTC](https://forum.bome.com/t/perform-and-concurrency/7120/7 "2025-03-28T17:14:20Z")

</div>

One gotcha: I am executing Performs from my Rules section.

_ **Is there a way to executed a Perform with a Delay from the Rules section?** _

---

<div class="post-metadata">

**Author:** ![SteveC](https://forum.bome.com/user_avatar/forum.bome.com/stevec/32/8250_2.png) [@SteveC](https://forum.bome.com/u/SteveC)\
**Post date:** [March 28, 2025, 5:19pm UTC](https://forum.bome.com/t/perform-and-concurrency/7120/8 "2025-03-28T17:19:11Z")

</div>

> [@Clint.Goss](#):
>
> Is there a way to executed a Perform with a Delay from the Rules section?

Not that I’m aware of. This is primarily why I have a dispatcher perform translator, so that it can take the incoming delay as a parameter from the dispatcher and use it as a delay for the outgoing action.

Steve Caldwell  
Bome Customer Care

* * *
_Also available for paid consulting services: bome@sniz.biz_
