@@ -82,8 +82,8 @@ function _threadsfor(iter,lbody)
82
82
end
83
83
end
84
84
end
85
- if threadid () != 1
86
- # only thread 1 can enter/exit _threadedregion
85
+ if threadid () != 1 || ccall ( :jl_in_threaded_region , Cint, ()) != 0
86
+ # only use threads when called from thread 1, outside @threads
87
87
Base. invokelatest (threadsfor_fun, true )
88
88
else
89
89
threading_run (threadsfor_fun)
@@ -93,31 +93,45 @@ function _threadsfor(iter,lbody)
93
93
end
94
94
95
95
"""
96
- Threads.@threads
96
+ Threads.@threads [schedule] for ... end
97
97
98
- A macro to parallelize a for-loop to run with multiple threads. This spawns [`nthreads()`](@ref)
99
- number of threads, splits the iteration space amongst them, and iterates in parallel.
100
- A barrier is placed at the end of the loop which waits for all the threads to finish
101
- execution, and the loop returns.
98
+ A macro to parallelize a `for` loop to run with multiple threads. Splits the iteration
99
+ space among multiple tasks and runs those tasks on threads according to a scheduling
100
+ policy.
101
+ A barrier is placed at the end of the loop which waits for all tasks to finish
102
+ execution.
103
+
104
+ The `schedule` argument can be used to request a particular scheduling policy.
105
+ The only currently supported value is `static`, which creates one task per thread
106
+ and divides the iterations equally among them. If called from inside another
107
+ `@threads` loop, or from a thread other than 1, then all iterations run on the
108
+ current thread.
109
+
110
+ The default schedule (used when no `schedule` argument is present) is subject to change.
111
+
112
+ !!! compat "Julia 1.5"
113
+ The `schedule` argument is available as of Julia 1.5.
102
114
"""
103
115
macro threads (args... )
104
116
na = length (args)
105
- if na != 1
117
+ if na == 2
118
+ sched, ex = args
119
+ elseif na == 1
120
+ sched = :static
121
+ ex = args[1 ]
122
+ else
106
123
throw (ArgumentError (" wrong number of arguments in @threads" ))
107
124
end
108
- ex = args[1 ]
109
- if ! isa (ex, Expr)
110
- throw (ArgumentError (" need an expression argument to @threads" ))
125
+ if ! (isa (ex, Expr) && ex. head === :for )
126
+ throw (ArgumentError (" @threads requires a `for` loop expression" ))
111
127
end
112
- if ex. head === :for
113
- if ex. args[1 ] isa Expr && ex. args[1 ]. head === :(= )
114
- return _threadsfor (ex. args[1 ], ex. args[2 ])
115
- else
116
- throw (ArgumentError (" nested outer loops are not currently supported by @threads" ))
117
- end
118
- else
119
- throw (ArgumentError (" unrecognized argument to @threads" ))
128
+ if sched != :static
129
+ throw (ArgumentError (" unsupported schedule argument in @threads" ))
130
+ end
131
+ if ! (ex. args[1 ] isa Expr && ex. args[1 ]. head === :(= ))
132
+ throw (ArgumentError (" nested outer loops are not currently supported by @threads" ))
120
133
end
134
+ return _threadsfor (ex. args[1 ], ex. args[2 ])
121
135
end
122
136
123
137
"""
0 commit comments