A thread is akin a continuously executing program running on a computer. Threads are managed by the computer’s operating system: the system is constantly pausing and resuming threads to create the effect of many simultaneous activities running on a single processor. For example, you can be downloading a song from the internet in one thread while reading your e-mail in another. When the Overdrive option is turned on, Max uses two threads and asks the operating system to ensure that one of the threads, which we call the high-priority thread, runs as regularly as possible (usually every millisecond). In exchange, Max tries to ensure that what happens in this thread uses as little of the computer’s time as possible. Time-consuming and user-interaction tasks are assigned to the low-priority thread.
The two threads allow you to use Max to do things that require high timing accuracy (such as MIDI) at the same time as you do things that are computationally expensive (such as decompress video) or involve user input.
Now, how does
js fit into this multi-threaded scenario? By default, the
js object executes all Javascript code in the low-priority thread. In particular, if it finds itself running in the high-priority thread, it will defer execution of whatever it was supposed to do to the low-priority thread. You can, however, tell
js not to do this by setting the immediate property of a function.
Let’s say you have a function bang that you intend to run when someone hooks up your
js object to a metro, as follows:
Your bang function does something simple such as sending the value of a number out its outlet.
var value = 1;
function bang()
{
outlet(0,value);
}
The timing accuracy of this function will be improved if you execute it immediately when the bang is received, rather than deferring it to the low-priority thread, where it will execute at some unspecified later time. In order to do this, you place the following statement in your global code.
bang.immediate = 1;
However, just because a function’s immediate property is set does not mean that it will always execute at high-priority. This depends on the context in which the
js object received a request to execute your function. For example, if I click on a bang button connected to the
js object described above, the bang function will run in the low-priority thread, because mouse clicks are always handled at low priority.
Another example that is a bit more subtle: let’s say I write a function slowbang that does not have its immediate property set. It merely calls the bang function I wrote above.
function slowbang()
{
bang();
}
Suppose we make a new patch in which the metro is hooked up to the slowbang message, as shown here:
Now the bang function will no longer execute in the high-priority thread, because slowbang was deferred to the low-priority thread before bang is executed.
You can determine the current thread of execution for your Javascript code by testing the mainthread property of the max object. The mainthread property will be 1 if the code is running in the low-priority thread.
In summary, a function will execute at in the high-priority thread…
-
if the function’s immediate property is set
and
-
the js receives a message to invoke the function at high-priority
or
-
the function is executing via a js Task object
The immediate property is generally intended for functions that will perform brief computational actions that participate in the logic in your Max patch. In other words, you would use it where the
js object is somewhere in the middle of the computational sequence, where preserving execution order or timing accuracy is important. The immediate property is not appropriate (and indeed, not allowed) for end-point actions such as drawing or scripting a Patcher.
The high-priority thread can be used for the following actions:
-
Sending messages using the outlet function
-
Posting messages to the Max window using post (although the order in which the messages appear is not guaranteed)
-
Calling other Javascript functions you defined
-
Accessing or controlling a js Task object
-
Performing mathematical, string, or logical computation
-
Accessing standard properties of the jsthis or max objects
The following actions are not guaranteed to work if you attempt to perform them in the high-priority thread. In most cases, there is no protection against doing any of these things, which may result in unexpected behavior, including Max crashing (although if you find such cases, we will do our best to prevent them).
-
Any use of jsui features such as creating a Sketch or Image object or invoking methods of those objects
-
Accessing files or folders using the File or Folder class
-
Using the scripting or application control features in the Patcher, Maxobj, or Wind objects and their methods.