Create a macro say inject_profile
    
    
    inject_profile:
      proc foo() =
        discard
      
      proc bar() =
        discard
      
      proc baz() =
        discard
    
    
    Run

In the inject_profile macro you iterate on all items contained in the 
nnkStmtList, if you find a RoutineNode (proc, template, iterator, macro), you 
replace the nnkStmtList body with prologue+body+epilogue.

However I recommend you go the template way instead, it will give you much more 
granularity for example this is what I use for [profiling my multithreading 
runtime](https://github.com/mratsim/weave/blob/2bb0284e5555ec8882412886fb15c948b2826b81/e04_channel_based_work_stealing/profile.nim#L52-L55):

> 
>     template profile*(name, body: untyped): untyped {.dirty.} =
>       profile_start(name)
>       body
>       profile_stop(name)
>     
>     
>     Run

And 
[usage](https://github.com/mratsim/weave/blob/330a5113e62f332441397208b1084008a576f83f/e04_channel_based_work_stealing/runtime.nim#L920-L969):
 
    
    
    proc schedule() =
      ## Executed by worker threads
      
      while true: # Scheduling loop
        # 1. Private task queue
        while (let task = pop(); not task.isNil):
          assert not task.fn.isNil, "Thread: " & $ID & " received a null task 
function."
          profile(run_task):
            run_task(task)
          profile(enq_deq_task):
            deque_list_tl_task_cache(deque, task)
        
        # 2. Work-stealing request
        try_send_steal_request(idle = true)
        assert requested != 0
        
        var task: Task
        profile(idle):
          while not recv_task(task):
            assert deque.deque_list_tl_empty()
            assert requested != 0
            decline_all_steal_requests()
        
        assert not task.fn.isNil, "Thread: " & $ID & " received a null task 
function."
        
        let loot = task.batch
        when defined(StealLastVictim):
          if task.victim != -1:
            last_victim = task.victim
            assert last_victim != ID
        if loot > 1:
          profile(enq_deq_task):
            task = deque_list_tl_pop(deque_list_tl_prepend(deque, task, loot))
            have_tasks()
        
        when defined(VictimCheck):
          if loot == 1 and splittable(task):
            have_tasks()
        when StealStrategy == StealKind.adaptative:
          inc num_steals_exec_recently
        
        share_work()
        
        profile(run_task):
          run_task(task)
        profile(enq_deq_task):
          deque_list_tl_task_cache(deque, task)
        
        if tasking_done():
          return
    
    
    Run

Reply via email to