void kp_final_exit(ktap_state *ks) { if (!list_empty(&G(ks)->probe_events_head) || !list_empty(&G(ks)->timers)) kp_wait(ks); if (G(ks)->trace_task) put_task_struct(G(ks)->trace_task); kp_exit_timers(ks); kp_probe_exit(ks); /* free all resources got by ktap */ kp_tstring_freeall(ks); kp_free_all_gcobject(ks); cfunction_cache_exit(ks); wait_user_completion(ks); kp_transport_exit(ks); kp_exitthread(ks); kp_free(ks, ks->stack); free_all_ci(ks); free_kp_percpu_data(); free_cpumask_var(G(ks)->cpumask); kp_free(ks, ks); }
static void ktap_call_probe_closure(ktap_state *mainthread, ktap_closure *cl, struct ktap_event *e) { ktap_state *ks; ktap_value *func; ks = kp_newthread(mainthread); setcllvalue(ks->top, cl); func = ks->top; incr_top(ks); ks->current_event = e; kp_call(ks, func, 0); ks->current_event = NULL; kp_exitthread(ks); }