Vocabulary/tcapdot
T. y Set Debug Thread Verb
Rank Infinity -- operates on x and y as a whole -- WHY IS THIS IMPORTANT?
T. y sets the debug thread number to y. The master thread is always thread 0. On entry into debug suspension, the debug thread is set to the number of the thread that caused the suspension.
During debug suspension, sentences are executed in the debug thread. Commands that end suspension, giving a line number to resume at or a value to be used as the value of the debugged sentence, execute in the debug thread but the value they produce is applied in the thread that caused the suspension.
T. y takes effect when its result becomes the result of a sentence entered from the keyboard during debug suspension.
Related Primitives
Execute as Task (t.)
x T. y Threads and Tasks Verb
Rank Infinity -- operates on x and y as a whole -- WHY IS THIS IMPORTANT?
x T. y performs a thread- and task-related function depending on the value of x:
x T. y functions Description x Type/
Precision
of ResultType/
Precision
of yAction Create thread 0 Integer atom [pool#] Create a thread in threadpool pool# (default 0), if possible. Result is the sequential thread number, or _1 if the thread could not be created. The master thread is thread 0 and is not a member of any threadpool.
Even if your code does not create tasks, the system can take advantage of threadpool 0 to make primitives run faster; you should use 8 T. '' to query the number of cores N in your system, and create N-1 threads in threadpool 0.
{{0 T.0}}^:] <: {. 8 T. ''Number of worker threads 1 Integer atom '' The total number of worker threads that have been created. Thread statistics for a threadpool 2 Integer list
#idle,#unfinished,#threads[pool#] Statistics are reported for threadpool pool# (default 0). #idle is the number of threads not working on a user task or an internal task. #unfinished is the number of user tasks that have not completed. #threads is the number of worker threads in the threadpool. Number of executing thread 3 Integer atom '' The number of the currently-executing thread. The master thread is thread 0. Rattle a box to get status 4 Integer array, one for each atom in y A box or array of boxes The threads continue to run between calculation of each atom of this result Status Result atom Pyx waiting to run _ Pyx running in thread n n Pyx completed with error number n -n Pyx completed with no error _1000 Not a pyx _1001 Note: non-negative status codes indicate tasks which are not done yet.
Create a pyx 5 The created pyx The maximum number of seconds to wait for the result, or 0 for no limit A pyx is created. It is very easy to lock up the system with pyxes. For example, the sentence
5 T. 0
entered from the keyboard will lock up.Install a value into a pyx 6 i. 0 0 pyx,<value value becomes the value of pyx, waking up any tasks that were waiting for it. It is illegal to store a value or errorcode into a pyx more than once. Install errorcode into a pyx 7 i. 0 0 pyx,<errorcode pyx becomes a pyx in error, with error code errorcode, waking up any tasks that were waiting for it. It is illegal to store a value or errorcode into a pyx more than once. Read system characteristics relating to threads 8 Integer list
corecount,maxthreads'' corecount is the number of cores in your machine. maxthreads is the maximum number of threads supported, including the master thread. Mutexes 10 mutex shared Create a mutex. shared is 0 for an exclusive mutex, 1 for a shared mutex (also called a recursive mutex). The mutex is opaque; its type, shape, and value are meaningful only as an argument to a mutex function, and they may not be displayed or modified; but the mutex may safely be passed as an argument or put into a box, and it is not considered boxed for the purposes of ;, L., and similar. 11 Integer
errorcodemutex[;timeout] Take an exclusive lock on mutex, waiting up to timeout seconds (or forever if timeout is _ or omitted). errorcode is 0 if the lock was taken, 1 if the request timed out. A timeout value of 0 will always return immediately. The behavior when a mutex-owner requests a lock on the mutex it owns depends on the type of mutex: an exclusive mutex will never get the lock, while a shared mutex will return immediately with the lock.
13 i. 0 0 mutex Release the lock on the mutex. For shared mutexes, the lock is released only after every execution of (11 T. mutex) has been matched by a (13 T. mutex). Set lingertime for a threadpool 14 Previous value of lingertime pool# lingertime instruct threads in threadpool pool# to stay active, waiting for jobs, for lingertime seconds after they complete the last task, before they go into a wait state. This is useful if you expect your code to create tasks so fast that a new task would be requested before a thread could come out of a wait state. Wake up all threads in a threadpool 15 i. 0 0 pool# Start all threads in theadpool pool#. If you expect that a task will be dispatched to the threadpool within the threadpool's lingertime (set by 14 T., the threads will be immediately ready for work without the operating system's thread-start delay. Atomically
Modifiable
Values
(AMV)16 AMV initial value Create an Atomically Modifiable Value (AMV) and set its value to initial value. An AMV is a boxed integer atom, but it should be accessed only through AMV primitives (17 T. and 18 T.). An AMV may be assigned to a name 17 value of AMV before addition AMV,<increment Add increment to the value of AMV, and return the value of AMV before the change. The modification is performed atomically, that is, the read, increment, and store cannot be interrupted by other threads. 18 '' if modification performed; value of AMV if modification not performed AMV,desired;expected Perform compare and swap on AMV: if the value of AMV is expected, it is replaced with desired, and the result is 0$0; otherwise the result is the value of AMV. The modification is performed atomically, that is, the read, compare, and conditional store cannot be interrupted by other threads. Destroy thread 55 i. 0 0 '' Immediately decrement the count of worker threads, and destroy the most-recently-created thread after it has finished execution.
A shared mutex (sometimes called a recursive mutex) is one which can be locked multiple times on the same thread. It must be unlocked as many times as it has been locked before it will be available to other threads. If an exclusive mutex is locked more than once on the same thread, an error will be thrown.
Exclusive and shared mutexes have similar performance; you should choose whichever one does a better job of enforcing application invariants.
Threadpools
Parallelizable primitives use threadpool 0. For best results, you should create one fewer worker thread in threadpool 0 than you have cores in your CPU. Note that a J thread can use all the resources of a core, making it a bad idea to create J threads for more than one hyperthread per core.
You should use threadpool 0 for your heavy computation also.
If you have threads that are often idle, consider allocating them in a different threadpool. That will avoid the thrashing that would result if you had too many threads in threadpool 0.
Details
User-created pyxes can be used as semaphores using the following protocol. Note that attempting to display a pyx will wait for its value to be assigned.
Originating task Responding task localpyx=.5 T. 30
function t. '' localpyx;local_stuff'remotepyx remote_stuff'=.y Set up shared data for responding task to use Get ready to receive 'remotepyx remote_stuff'=.>localpyx 6 T. remotepyx,<(localpyx =. 5 T. 30);<local_stuff *** The responding task has control of the shared data *** 6 T. remotepyx,<(localpyx =. 5 T. 30);<local_stuff 'remotepyx remote_stuff'=.>localpyx *** The originating task has control of the shared data *** Control can be passed back and forth indefinitely
Oddities
Threads cannot be created on Raspberry Pi distribution.
Related Primitives
Execute as Task (t.)