Max 5 API Reference
00001 /** 00002 00003 @defgroup threading Threads 00004 00005 In Max, there are several threads of execution. 00006 The details of these threads are highlighted in the article "Event Priority in Max (Scheduler vs. Queue)" 00007 located online at http://www.cycling74.com/story/2005/5/2/133649/9742. 00008 00009 Not all of the details of Max's threading model are expounded here. 00010 Most important to understand is that we typically deal the scheduler 00011 (which when overdrive is on runs in a separate and high priority thread) 00012 and the low priority queue (which always runs in the main application thread). 00013 00014 @see http://www.cycling74.com/twiki/bin/view/ProductDocumentation/JitterSdkSchedQueue 00015 @see http://www.cycling74.com/story/2005/5/2/133649/9742 00016 */ 00017 00018 00019 /** 00020 @defgroup critical Critical Regions 00021 @ingroup threading 00022 00023 A critical region is a simple mechanism that prevents multiple threads 00024 from accessing at once code protected by the same critical region. The 00025 code fragments could be different, and in completely different 00026 modules, but as long as the critical region is the same, no two threads 00027 should call the protected code at the same time. If one thread is inside 00028 a critical region, and another thread wants to execute code protected 00029 by the same critical region, the second thread must wait for the first 00030 thread to exit the critical region. In some implementations a critical 00031 region can be set so that if it takes too long for the first thread to exit 00032 said critical region, the second thread is allowed to execute, 00033 dangerously and potentially causing crashes. This is the case for the 00034 critical regions exposed by Max and the default upper limit for a given 00035 thread to remain inside a critical region is two seconds. Despite the fact 00036 that there are two seconds of leeway provided before two threads can 00037 dangerously enter a critical region, it is important to only protect as 00038 small a portion of code as necessary with a critical region. 00039 00040 Under Max 4.1 and earlier there was a simple protective mechanism 00041 called "lockout" that would prevent the scheduler from interrupting 00042 the low priority thread during sensitive operations such as sending 00043 data out an outlet or modifying members of a linked list. This lockout 00044 mechanism has been deprecated, and under the Mac OS X and 00045 Windows XP versions (Max 4.2 and later) does nothing. So how do 00046 you protect thread sensitive operations? Use critical regions (also 00047 known as critical sections). However, it is very important to mention 00048 that all outlet calls are now thread safe and should never be contained 00049 inside a critical region. Otherwise, this could result in serious timing 00050 problems. For other tasks which are not thread safe, such as accessing a 00051 linked list, critical regions or some other thread protection mechanism 00052 are appropriate. 00053 00054 In Max, the critical_enter() function is used to enter a critical 00055 region, and the critical_exit() function is used to exit a critical 00056 region. It is important that in any function which uses critical regions, 00057 all control paths protected by the critical region, exit the critical region 00058 (watch out for goto or return statements). The critical_enter() and 00059 critical_exit() functions take a critical region as an argument. 00060 However, for almost all purposes, we recommend using the global 00061 critical region in which case this argument is zero. The use of multiple 00062 critical regions can cause problems such as deadlock, i.e. when thread 00063 #1 is inside critical region A waiting on critical region B, but thread #2 00064 is inside critical region B and is waiting on critical region A. In a 00065 flexible programming environment such as Max, deadlock conditions 00066 are easier to generate than you might think. So unless you are 00067 completely sure of what you are doing, and absolutely need to make 00068 use of multiple critical regions to protect your code, we suggest you use 00069 the global critical region. 00070 00071 In the following example code we show how one might use critical 00072 regions to protect the traversal of a linked list, testing to find the first 00073 element whose values is equal to "val". If this code were not protected, 00074 another thread which was modifying the linked list could invalidate 00075 assumptions in the traversal code. 00076 00077 @code 00078 critical_enter(0); 00079 for (p = head; p; p = p->next) { 00080 if (p->value == val) 00081 break; 00082 } 00083 critical_exit(0); 00084 return p; 00085 @endcode 00086 00087 And just to illustrate how to ensure a critical region is exited when 00088 multiple control paths are protected by a critical region, here's a slight 00089 variant. 00090 00091 @code 00092 critical_enter(0); 00093 for (p = head; p; p = p->next) { 00094 if (p->value == val) { 00095 critical_exit(0); 00096 return p; 00097 } 00098 } 00099 critical_exit(0); 00100 return NULL; 00101 @endcode 00102 00103 For more information on multi-threaded programming, hardware 00104 interrupts, and related topics, we suggest you perform some research 00105 online or read the relevant chapters of "Modern Operating Systems" by 00106 Andrew S. Tanenbaum (Prentice Hall). At the time of writing, some 00107 relevant chapters from this book are available for download in PDF 00108 format on Prentice Hall’s web site. See: 00109 00110 http://www.prenhall.com/divisions/esm/app/author_tanenbaum/custom/mos2e/ 00111 00112 Look under "sample sections". 00113 00114 */ 00115 00116 00117 /** 00118 @defgroup mutex Mutexes 00119 @ingroup threading 00120 00121 @see @ref critical 00122 */
Copyright © 2008, Cycling '74