Max 5 API Reference

Threads

In Max, there are several threads of execution. More...

Collaboration diagram for Threads:

Modules

 Critical Regions
 

A critical region is a simple mechanism that prevents multiple threads from accessing at once code protected by the same critical region.


 Mutexes

Defines

#define ATOMIC_INCREMENT(pv)   (_InterlockedIncrement(pv))
 Use this routine for incrementing a global counter using a threadsafe and multiprocessor safe method.
#define ATOMIC_DECREMENT(pv)   (_InterlockedDecrement(pv))
 Use this routine for decrementing a global counter using a threadsafe and multiprocessor safe method.

Typedefs

typedef void t_thread
 A Max thread.
typedef void * t_systhread
 An opaque thread instance pointer.
typedef void * t_systhread_mutex
 An opaque mutex handle.
typedef void * t_systhread_cond
 An opaque cond handle.

Enumerations

enum  e_max_systhread_mutex_flags {
  SYSTHREAD_MUTEX_NORMAL = 0x00000000,
  SYSTHREAD_MUTEX_ERRORCHECK = 0x00000001,
  SYSTHREAD_MUTEX_RECURSIVE = 0x00000002
}
 

systhread_mutex_new() flags

More...

Functions

void schedule (void *ob, method fun, long when, t_symbol *sym, short argc, Atom *argv)
 Cause a function to be executed at the timer level at some time in the future.
void schedule_delay (void *ob, method fun, long delay, t_symbol *sym, short argc, t_atom *argv)
 Cause a function to be executed at the timer level at some time in the future specified by a delay offset.
long isr (void)
 Determine whether your code is executing in the Max scheduler thread.
void * defer (void *ob, method fn, t_symbol *sym, short argc, t_atom *argv)
 Defer execution of a function to the main thread if (and only if) your function is executing in the scheduler thread.
void * defer_low (void *ob, method fn, t_symbol *sym, short argc, t_atom *argv)
 Defer execution of a function to the back of the queue on the main thread.
long systhread_create (method entryproc, void *arg, long stacksize, long priority, long flags, t_systhread *thread)
 Create a new thread.
long systhread_terminate (t_systhread thread)
 Forcefully kill a thread -- not recommended.
void systhread_sleep (long milliseconds)
 Suspend the execution of the calling thread.
void systhread_exit (long status)
 Exit the calling thread.
long systhread_join (t_systhread thread, unsigned int *retval)
 Wait for thread to quit and get return value from systhread_exit().
t_systhread systhread_self (void)
 Return the thread instance pointer for the calling thread.
void systhread_setpriority (t_systhread thread, int priority)
 Set the thread priority for the given thread.
int systhread_getpriority (t_systhread thread)
 Get the thread priority for the given thread.
short systhread_ismainthread (void)
 Check to see if the function currently being executed is in the main thread.
short systhread_istimerthread (void)
 Check to see if the function currently being executed is in the scheduler thread.

Detailed Description

In Max, there are several threads of execution.

The details of these threads are highlighted in the article "Event Priority in Max (Scheduler vs. Queue)" located online at http://www.cycling74.com/story/2005/5/2/133649/9742.

Not all of the details of Max's threading model are expounded here. Most important to understand is that we typically deal the scheduler (which when overdrive is on runs in a separate and high priority thread) and the low priority queue (which always runs in the main application thread).

See also:
http://www.cycling74.com/twiki/bin/view/ProductDocumentation/JitterSdkSchedQueue
http://www.cycling74.com/story/2005/5/2/133649/9742

Define Documentation

#define ATOMIC_DECREMENT ( pv   )     (_InterlockedDecrement(pv))

Use this routine for decrementing a global counter using a threadsafe and multiprocessor safe method.

Parameters:
pv pointer to the (int) counter.
#define ATOMIC_INCREMENT ( pv   )     (_InterlockedIncrement(pv))

Use this routine for incrementing a global counter using a threadsafe and multiprocessor safe method.

Parameters:
pv pointer to the (int) counter.

Enumeration Type Documentation

systhread_mutex_new() flags

Enumerator:
SYSTHREAD_MUTEX_NORMAL 

Normal.

SYSTHREAD_MUTEX_ERRORCHECK 

Error-checking.

SYSTHREAD_MUTEX_RECURSIVE 

Recursive.


Function Documentation

void* defer ( void *  ob,
method  fn,
t_symbol sym,
short  argc,
t_atom argv 
)

Defer execution of a function to the main thread if (and only if) your function is executing in the scheduler thread.

Parameters:
ob First argument passed to the function fun when it executes.
fn Function to be called, see below for how it should be declared.
sym Second argument passed to the function fun when it executes.
argc Count of arguments in argv. argc is also the third argument passed to the function fun when it executes.
argv Array containing a variable number of t_atom function arguments. If this argument is non-zero, defer allocates memory to make a copy of the arguments (according to the size passed in argc) and passes the copied array to the function fun when it executes as the fourth argument.
Returns:
Return values is for internal Cycling '74 use only.
Remarks:
This function uses the isr() routine to determine whether you’re at the Max timer interrupt level (in the scheduler thread). If so, defer() creates a Qelem (see Qelems), calls qelem_front(), and its queue function calls the function fn you passed with the specified arguments. If you’re not in the scheduler thread, the function is executed immediately with the arguments. Note that this implies that defer() is not appropriate for using in situations such as Device or File manager I/0 completion routines. The defer_low() function is appropriate however, because it always defers.

The deferred function should be declared as follows:

    void myobject_do (myObject *client, t_symbol *s, short argc, t_atom *argv);
See also:
defer_low()
void* defer_low ( void *  ob,
method  fn,
t_symbol sym,
short  argc,
t_atom argv 
)

Defer execution of a function to the back of the queue on the main thread.

Parameters:
ob First argument passed to the function fun when it executes.
fn Function to be called, see below for how it should be declared.
sym Second argument passed to the function fun when it executes.
argc Count of arguments in argv. argc is also the third argument passed to the function fun when it executes.
argv Array containing a variable number of t_atom function arguments. If this argument is non-zero, defer allocates memory to make a copy of the arguments (according to the size passed in argc) and passes the copied array to the function fun when it executes as the fourth argument.
Returns:
Return values is for internal Cycling '74 use only.
Remarks:
defer_low() always defers a call to the function fun whether you are already in the main thread or not, and uses qelem_set(), not qelem_front(). This function is recommended for responding to messages that will cause your object to open a dialog box, such as read and write.

The deferred function should be declared as follows:

    void myobject_do (myObject *client, t_symbol *s, short argc, t_atom *argv);
See also:
defer()
long isr ( void   ) 

Determine whether your code is executing in the Max scheduler thread.

Returns:
This function returns non-zero if you are within Max's scheduler thread, zero otherwise. Note that if your code sets up other types of interrupt-level callbacks, such as for other types of device drivers used in asynchronous mode, isr will return false.
void schedule ( void *  ob,
method  fun,
long  when,
t_symbol sym,
short  argc,
Atom *  argv 
)

Cause a function to be executed at the timer level at some time in the future.

Parameters:
ob First argument passed to the function fun when it executes.
fun Function to be called, see below for how it should be declared.
when The logical time that the function fun will be executed.
sym Second argument passed to the function fun when it executes.
argc Count of arguments in argv. argc is also the third argument passed to the function fun when it executes.
argv Array containing a variable number of t_atom function arguments. If this argument is non-zero, defer allocates memory to make a copy of the arguments (according to the size passed in argc) and passes the copied array to the function fun when it executes as the fourth argument.
Remarks:
schedule() calls a function at some time in the future. Unlike defer(), the function is called in the scheduling loop when logical time is equal to the specified value when. This means that the function could be called at interrupt level, so it should follow the usual restrictions on interrupt-level conduct. The function fun passed to schedule should be declared as follows:
    void myobject_do (myObject *client, t_symbol *s, short argc, t_atom *argv); 
Remarks:
One use of schedule() is as an alternative to using the lockout flag.
See also:
defer()
void schedule_delay ( void *  ob,
method  fun,
long  delay,
t_symbol sym,
short  argc,
t_atom argv 
)

Cause a function to be executed at the timer level at some time in the future specified by a delay offset.

Parameters:
ob First argument passed to the function fun when it executes.
fun Function to be called, see below for how it should be declared.
delay The delay from the current time before the function will be executed.
sym Second argument passed to the function fun when it executes.
argc Count of arguments in argv. argc is also the third argument passed to the function fun when it executes.
argv Array containing a variable number of t_atom function arguments. If this argument is non-zero, defer allocates memory to make a copy of the arguments (according to the size passed in argc) and passes the copied array to the function fun when it executes as the fourth argument.
Remarks:
schedule_delay() is similar to schedule but allows you to specify the time as a delay rather than a specific logical time.

One use of schedule() or schedule_delay() is as an alternative to using the lockout flag. Here is an example click method that calls schedule() instead of outlet_int() surrounded by lockout_set() calls.

    void myobject_click (t_myobject *x, Point pt, short modifiers) 
    { 
        t_atom a[1]; 
        a[0].a_type = A_LONG; 
        a[0].a_w.w_long = Random(); 
        schedule_delay(x, myobject_sched, 0 ,0, 1, a); 
    } 

    void myobject_sched (t_myobject *x, t_symbol *s, short ac, t_atom *av) 
    { 
        outlet_int(x->m_out,av->a_w.w_long); 
    } 
See also:
schedule()
long systhread_create ( method  entryproc,
void *  arg,
long  stacksize,
long  priority,
long  flags,
t_systhread thread 
)

Create a new thread.

Parameters:
entryproc A method to call in the new thread when the thread is created.
arg An argument to pass to the method specified for entryproc. Typically this might be a pointer to your object's struct.
stacksize Not used. Pass 0 for this argument.
priority Pass 0 for default priority. The priority can range from -32 to 32 where -32 is low, 0 is default and 32 is high.
flags Not used. Pass 0 for this argument.
thread The address of a t_systhread where this thread's instance pointer will be stored.
Returns:
A Max error code as defined in e_max_errorcodes.
void systhread_exit ( long  status  ) 

Exit the calling thread.

Call this from within a thread made using systhread_create() when the thread is no longer needed.

Parameters:
status You will typically pass 0 for status. This value will be accessible by systhread_join(), if needed.
int systhread_getpriority ( t_systhread  thread  ) 

Get the thread priority for the given thread.

Parameters:
thread The thread for which to find the priority.
Returns:
The current priority value for the given thread.
short systhread_ismainthread ( void   ) 

Check to see if the function currently being executed is in the main thread.

Returns:
Returns true if the function is being executed in the main thread, otherwise false.
short systhread_istimerthread ( void   ) 

Check to see if the function currently being executed is in the scheduler thread.

Returns:
Returns true if the function is being executed in the main thread, otherwise false.
long systhread_join ( t_systhread  thread,
unsigned int *  retval 
)

Wait for thread to quit and get return value from systhread_exit().

Parameters:
thread The thread to join.
retval The address of a long to hold the return value (status) from systhread_exit().
Returns:
A Max error code as defined in e_max_errorcodes.
Remarks:
If your object is freed, and your thread function accesses memory from your object, then you will obviously have a memory violation. A common use of systhread_join() is to prevent this situation by waiting (in your free method) for the thread to exit.
t_systhread systhread_self ( void   ) 

Return the thread instance pointer for the calling thread.

Returns:
The thread instance pointer for the thread from which this function is called.
void systhread_setpriority ( t_systhread  thread,
int  priority 
)

Set the thread priority for the given thread.

Parameters:
thread The thread for which to set the priority.
priority A value in the range -32 to 32 where -32 is lowest, 0 is default, and 32 is highest.
void systhread_sleep ( long  milliseconds  ) 

Suspend the execution of the calling thread.

Parameters:
milliseconds The number of milliseconds to suspend the execution of the calling thread. The actual amount of time may be longer depending on various factors.
long systhread_terminate ( t_systhread  thread  ) 

Forcefully kill a thread -- not recommended.

Parameters:
thread The thread to kill.
Returns:
A Max error code as defined in e_max_errorcodes.

Copyright © 2008, Cycling '74