35 #define TASK_SIGSET_T sigset_t
38 sigemptyset(&block_sigset);
40 rz_signal_sigmask(SIG_BLOCK, &block_sigset, old_sigset);
44 rz_signal_sigmask(SIG_SETMASK, old_sigset,
NULL);
47 #define TASK_SIGSET_T void *
77 rz_list_foreach (scheduler->
tasks,
iter, task) {
78 if (task != scheduler->
main_task && task->state != RZ_CORE_TASK_STATE_DONE) {
97 if (current &&
id == current->id) {
119 rz_list_foreach (tasks,
iter, task) {
120 if (current == task) {
127 rz_list_foreach (tasks,
iter, task) {
128 if (current == task) {
148 if (task->runner_free) {
149 task->runner_free(task->runner_user);
169 task->running_sem =
NULL;
170 task->dispatched =
false;
173 if (!task->dispatch_cond || !task->dispatch_lock) {
176 task->runner = runner;
177 task->runner_free = runner_free;
178 task->runner_user = runner_user;
180 task->state = RZ_CORE_TASK_STATE_BEFORE_START;
182 task->transient =
false;
208 if (task->refcount <= 0) {
221 rz_list_foreach_safe (sched->
tasks,
iter, iter_tmp, ltask) {
222 if (ltask == exclude) {
225 if (ltask->transient && ltask->state == RZ_CORE_TASK_STATE_DONE) {
233 bool stop = next_state != RZ_CORE_TASK_STATE_RUNNING;
244 current->state = next_state;
274 next->dispatched =
true;
278 while (!current->dispatched) {
281 current->dispatched =
false;
305 current->state = RZ_CORE_TASK_STATE_RUNNING;
321 while (!current->dispatched) {
324 current->dispatched =
false;
358 task->runner(sched, task->runner_user);
366 if (task->running_sem) {
375 if (!scheduler || !task) {
380 if (!task->running_sem) {
383 if (task->running_sem) {
392 if (!scheduler || !func) {
426 task->state = RZ_CORE_TASK_STATE_BEFORE_START;
453 rz_list_foreach (scheduler->
tasks,
iter, task) {
454 if (task->id ==
id) {
477 task->breaked =
true;
487 if (!task || task->state == RZ_CORE_TASK_STATE_DONE) {
500 rz_list_foreach (scheduler->
tasks,
iter, task) {
501 if (task->state != RZ_CORE_TASK_STATE_DONE) {
514 rz_list_foreach (scheduler->
tasks,
iter, task) {
515 if (task->id ==
id) {
519 if (task->state == RZ_CORE_TASK_STATE_DONE) {
522 task->transient =
true;
548 if (!
ctx->cons_context) {
557 if (
ctx->cons_context &&
ctx->cons_context->break_stack) {
586 ctx->cmd_log =
false;
588 ctx->finished_cb = finished_cb;
589 ctx->finished_cb_user = finished_cb_user;
606 if (
ctx->finished_cb) {
607 ctx->finished_cb(res_str,
ctx->finished_cb_user);
611 eprintf(
"\nTask %d finished\n", task->id);
675 ctx->fcn_user = fcn_user;
684 ctx->res =
ctx->fcn(core,
ctx->fcn_user);
728 if (next->runner_user) {
730 if (
ctx->cons_context) {
744 switch (task->state) {
745 case RZ_CORE_TASK_STATE_RUNNING:
747 case RZ_CORE_TASK_STATE_SLEEPING:
749 case RZ_CORE_TASK_STATE_DONE:
751 case RZ_CORE_TASK_STATE_BEFORE_START:
752 return "before start";
772 pj_ki(j,
"id", task->id);
777 switch (task->state) {
778 case RZ_CORE_TASK_STATE_BEFORE_START:
779 state =
"before_start";
781 case RZ_CORE_TASK_STATE_RUNNING:
784 case RZ_CORE_TASK_STATE_SLEEPING:
787 case RZ_CORE_TASK_STATE_DONE:
794 pj_kb(j,
"transient", task->transient);
803 task->transient ?
"(t)" :
"",
805 cmd ?
cmd :
"-- MAIN TASK --");
850 rz_list_foreach_safe (sched->
tasks,
iter, iter2, task) {
static RzBinXtrData * oneshot(RzBin *bin, const ut8 *buf, ut64 size, int subbin_type)
RZ_API int rz_core_cmd(RzCore *core, const char *cstr, int log)
RZ_API char * rz_core_cmd_str(RzCore *core, const char *cmd)
Executes a rizin command and returns the stdout as a string.
RZ_API bool rz_cons_default_context_is_interactive(void)
RZ_API void rz_cons_context_free(RzConsContext *context)
RZ_API RzConsContext * rz_cons_context_new(RZ_NULLABLE RzConsContext *parent)
RZ_API void rz_cons_context_reset(void)
RZ_API RzCons * rz_cons_singleton(void)
RZ_API void rz_cons_context_break(RzConsContext *context)
RZ_API int rz_cons_printf(const char *format,...)
RZ_API void rz_cons_context_break_pop(RzConsContext *context, bool sig)
RZ_API void rz_cons_context_load(RzConsContext *context)
RZ_API void rz_cons_println(const char *str)
RZ_API void rz_cons_context_break_push(RzConsContext *context, RzConsBreak cb, void *user, bool sig)
RZ_API void rz_cons_pop(void)
RZ_API void rz_cons_push(void)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
RZ_API RZ_OWN RzList * rz_list_clone(RZ_NONNULL const RzList *list)
Shallow copies of the list (but doesn't free its elements)
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
RZ_API RZ_OWN void * rz_list_pop_head(RZ_NONNULL RzList *list)
Removes and returns the first element of the list.
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
RZ_API void rz_th_free(RZ_NULLABLE RzThread *th)
Frees a RzThread structure.
RZ_API RZ_OWN RzThread * rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLABLE void *user)
Creates and starts a new thread.
RZ_API bool rz_th_wait(RZ_NONNULL RzThread *th)
Awaits indefinetely for a thread to join.
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define rz_return_if_fail(expr)
#define rz_return_val_if_fail(expr, val)
void(* RzCoreTaskContextSwitch)(RzCoreTask *next, void *user)
struct rz_core_task_t RzCoreTask
void(* RzCoreTaskBreak)(RzCoreTask *task, void *user)
void(* RzListFree)(void *ptr)
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
RZ_API PJ * pj_end(PJ *j)
RZ_API const char * pj_string(PJ *pj)
RZ_API void pj_free(PJ *j)
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
void *(* RzThreadFunction)(void *user)
RzCoreCmdTaskFinished finished_cb
RzConsContext * cons_context
RzCoreTaskScheduler tasks
RzCoreTaskContextSwitch ctx_switch
struct rz_core_task_t * current_task
struct rz_core_task_t * main_task
RZ_API bool rz_core_task_is_cmd(RzCore *core, int id)
static void tasks_lock_enter(RzCoreTaskScheduler *scheduler, TASK_SIGSET_T *old_sigset)
static void function_task_free(FunctionTaskCtx *ctx)
RZ_API void rz_core_task_join(RzCoreTaskScheduler *scheduler, RzCoreTask *current, int id)
RZ_API void rz_core_task_scheduler_init(RzCoreTaskScheduler *sched, RzCoreTaskContextSwitch ctx_switch, void *ctx_switch_user, RzCoreTaskBreak break_cb, void *break_cb_user)
RZ_API RzCoreTask * rz_core_task_new(RzCoreTaskScheduler *sched, RzCoreTaskRunner runner, RzCoreTaskRunnerFree runner_free, void *runner_user)
RZ_API void rz_core_task_decref(RzCoreTask *task)
static FunctionTaskCtx * function_task_ctx_new(RzCore *core, RzCoreTaskFunction fcn, void *fcn_user)
RZ_API void rz_core_task_schedule(RzCoreTask *current, RzTaskState next_state)
static void tasks_lock_leave(RzCoreTaskScheduler *scheduler, TASK_SIGSET_T *old_sigset)
RZ_API void rz_core_task_break_all(RzCoreTaskScheduler *scheduler)
static bool core_task_ctx_init(CoreTaskCtx *ctx, RzCore *core)
static void tasks_lock_block_signals_reset(TASK_SIGSET_T *old_sigset)
RZ_API void rz_core_task_sync_end(RzCoreTaskScheduler *scheduler)
RZ_API void rz_core_task_scheduler_fini(RzCoreTaskScheduler *tasks)
RZ_API void rz_core_task_print(RzCore *core, RzCoreTask *task, int mode, PJ *j)
static void core_task_ctx_fini(CoreTaskCtx *ctx)
RZ_API void rz_core_task_enqueue_oneshot(RzCoreTaskScheduler *scheduler, RzCoreTaskOneShot func, void *user)
RZ_IPI void rz_core_task_ctx_switch(RzCoreTask *next, void *user)
struct core_task_ctx_t CoreTaskCtx
RZ_API void rz_core_task_sleep_end(RzCoreTask *task)
static void cmd_task_runner(RzCoreTaskScheduler *sched, void *user)
static void task_end(RzCoreTask *t)
RZ_API void rz_core_task_incref(RzCoreTask *task)
struct cmd_task_ctx_t CmdTaskCtx
struct function_task_ctx_t FunctionTaskCtx
RZ_API int rz_core_task_del(RzCoreTaskScheduler *scheduler, int id)
static void cleanup_transient(RzCoreTaskScheduler *sched, RzCoreTask *exclude)
RZ_API void rz_core_task_del_all_done(RzCore *core)
static void * task_run_thread(RzCoreTask *task)
static void cmd_task_free(CmdTaskCtx *ctx)
RZ_API int rz_core_task_running_tasks_count(RzCoreTaskScheduler *scheduler)
static RzCoreTask * task_get(RzCoreTaskScheduler *scheduler, int id)
RZ_API int rz_core_task_run_sync(RzCoreTaskScheduler *scheduler, RzCoreTask *task)
RZ_API RzCoreTask * rz_core_function_task_new(RzCore *core, RzCoreTaskFunction fcn, void *fcn_user)
RZ_API void rz_core_task_enqueue(RzCoreTaskScheduler *scheduler, RzCoreTask *task)
RZ_API RzCoreTask * rz_core_task_get_incref(RzCoreTaskScheduler *scheduler, int id)
RZ_API RzCoreTask * rz_core_cmd_task_new(RzCore *core, const char *cmd, RzCoreCmdTaskFinished finished_cb, void *finished_cb_user)
static void function_task_runner(RzCoreTaskScheduler *sched, void *user)
RZ_API void rz_core_task_list(RzCore *core, int mode)
static void task_join(RzCoreTask *task)
RZ_API void rz_core_task_sleep_begin(RzCoreTask *task)
static CmdTaskCtx * cmd_task_ctx_new(RzCore *core, const char *cmd, RzCoreCmdTaskFinished finished_cb, void *finished_cb_user)
RZ_API void rz_core_task_yield(RzCoreTaskScheduler *scheduler)
static void task_wakeup(RzCoreTask *current)
RZ_API const char * rz_core_cmd_task_get_result(RzCoreTask *task)
RZ_API void rz_core_task_sync_begin(RzCoreTaskScheduler *scheduler)
RZ_IPI void rz_core_task_break_cb(RzCoreTask *task, void *user)
RZ_API void rz_core_task_break(RzCoreTaskScheduler *scheduler, int id)
RZ_API RzCoreTask * rz_core_task_self(RzCoreTaskScheduler *scheduler)
static void tasks_lock_block_signals(TASK_SIGSET_T *old_sigset)
RZ_API void * rz_core_function_task_get_result(RzCoreTask *task)
RZ_API const char * rz_core_task_status(RzCoreTask *task)
static void task_break(RzCoreTask *task)
static void task_free(RzCoreTask *task)
RZ_API void rz_th_cond_free(RZ_NULLABLE RzThreadCond *cond)
Frees a RzThreadCond struct.
RZ_API void rz_th_cond_signal(RZ_NONNULL RzThreadCond *cond)
This function shall unblock at least one of the threads that are blocked on the specified condition.
RZ_API void rz_th_cond_wait(RZ_NONNULL RzThreadCond *cond, RZ_NONNULL RzThreadLock *lock)
The function shall block on a condition variable and shall be called with RzThreadLock locked by the ...
RZ_API RZ_OWN RzThreadCond * rz_th_cond_new(void)
Condition variables are intended to be used to communicate changes in the state of data shared betwee...
RZ_API void rz_th_lock_leave(RZ_NONNULL RzThreadLock *thl)
Releases a RzThreadLock structure.
RZ_API void rz_th_lock_free(RZ_NULLABLE RzThreadLock *thl)
Frees a RzThreadLock structure.
RZ_API RZ_OWN RzThreadLock * rz_th_lock_new(bool recursive)
Allocates and initialize a RzThreadLock structure.
RZ_API void rz_th_lock_enter(RZ_NONNULL RzThreadLock *thl)
Acquires a RzThreadLock structure.
RZ_API RZ_OWN RzThreadSemaphore * rz_th_sem_new(unsigned int initial)
Allocates and initialize a RzThreadSemaphore structure.
RZ_API void rz_th_sem_free(RZ_NULLABLE RzThreadSemaphore *sem)
Frees a RzThreadSemaphore struct.
RZ_API void rz_th_sem_post(RZ_NONNULL RzThreadSemaphore *sem)
increments (releases) a semaphore
RZ_API void rz_th_sem_wait(RZ_NONNULL RzThreadSemaphore *sem)
Decrements (acquires) the semaphore (waits indefinetely)