Writing a macro for manual @spawn control

In some situations we need to limit the number of simultaneously running tasks, for example, when you @spawn run(...), Julia won’t know about CPU usage resulting an over-spawn.

I find something like this helpful:

julia> x = Threads.Atomic{Int}(0)
Base.Threads.Atomic{Int64}(0)

julia> Threads.@threads for _ = 1:2
           global x
           for i = 1:1000
               Threads.@spawn begin
                   while x[]>6
                       sleep(0.5)
                   end
                   Threads.atomic_add!(x, 1)
                   rand(10000,1000) # replace this with real work load
                   Threads.atomic_sub!(x, 1)
               end
           end
       end

In this example I’m willing to use about 2*6=12 cores (server has 28)

My question is how to make a macro that has a syntax of:

@limit_spawn x 6 rand(10000,1000)

That would generate the corresponding part of the for loop, so one can simply write:

    for i = 1:1000
        @limit_spawn x 6 rand(10000,1000) # replace this with real work loa
    end