mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 08:43:10 +00:00
task queue: Implement running tasks retrieval mechanism
This commit is contained in:
parent
10fe532d29
commit
8f6bb23f38
@ -56,6 +56,14 @@ enum task_queue_ctl_state
|
|||||||
*/
|
*/
|
||||||
TASK_QUEUE_CTL_FIND,
|
TASK_QUEUE_CTL_FIND,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls func for every running task when handler
|
||||||
|
* parameter matches task handler, allowing the
|
||||||
|
* list parameter to be filled with user-defined
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
TASK_QUEUE_CTL_RETRIEVE,
|
||||||
|
|
||||||
/* Blocks until all tasks have finished.
|
/* Blocks until all tasks have finished.
|
||||||
* This must only be called from the main thread. */
|
* This must only be called from the main thread. */
|
||||||
TASK_QUEUE_CTL_WAIT,
|
TASK_QUEUE_CTL_WAIT,
|
||||||
@ -99,6 +107,8 @@ typedef void (*retro_task_handler_t)(retro_task_t *task);
|
|||||||
typedef bool (*retro_task_finder_t)(retro_task_t *task,
|
typedef bool (*retro_task_finder_t)(retro_task_t *task,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
|
|
||||||
|
typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *source_file;
|
char *source_file;
|
||||||
@ -149,10 +159,28 @@ typedef struct task_finder_data
|
|||||||
void *userdata;
|
void *userdata;
|
||||||
} task_finder_data_t;
|
} task_finder_data_t;
|
||||||
|
|
||||||
|
typedef struct task_retriever_info
|
||||||
|
{
|
||||||
|
struct task_retriever_info *next;
|
||||||
|
void *data;
|
||||||
|
} task_retriever_info_t;
|
||||||
|
|
||||||
|
typedef struct task_retriever_data
|
||||||
|
{
|
||||||
|
retro_task_handler_t handler;
|
||||||
|
size_t element_size;
|
||||||
|
retro_task_retriever_t func;
|
||||||
|
task_retriever_info_t *list;
|
||||||
|
} task_retriever_data_t;
|
||||||
|
|
||||||
void task_queue_push_progress(retro_task_t *task);
|
void task_queue_push_progress(retro_task_t *task);
|
||||||
|
|
||||||
bool task_queue_ctl(enum task_queue_ctl_state state, void *data);
|
bool task_queue_ctl(enum task_queue_ctl_state state, void *data);
|
||||||
|
|
||||||
|
void *task_queue_retriever_info_next(task_retriever_info_t **link);
|
||||||
|
|
||||||
|
void task_queue_retriever_info_free(task_retriever_info_t *list);
|
||||||
|
|
||||||
void task_queue_cancel_task(void *task);
|
void task_queue_cancel_task(void *task);
|
||||||
|
|
||||||
RETRO_END_DECLS
|
RETRO_END_DECLS
|
||||||
|
@ -44,6 +44,7 @@ struct retro_task_impl
|
|||||||
void (*wait)(void);
|
void (*wait)(void);
|
||||||
void (*gather)(void);
|
void (*gather)(void);
|
||||||
bool (*find)(retro_task_finder_t, void*);
|
bool (*find)(retro_task_finder_t, void*);
|
||||||
|
void (*retrieve)(task_retriever_data_t *data);
|
||||||
void (*init)(void);
|
void (*init)(void);
|
||||||
void (*deinit)(void);
|
void (*deinit)(void);
|
||||||
};
|
};
|
||||||
@ -237,6 +238,43 @@ static bool retro_task_regular_find(retro_task_finder_t func, void *user_data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void retro_task_regular_retrieve(task_retriever_data_t *data)
|
||||||
|
{
|
||||||
|
retro_task_t *task;
|
||||||
|
task_retriever_info_t *info;
|
||||||
|
task_retriever_info_t *tail = NULL;
|
||||||
|
|
||||||
|
/* Parse all running tasks and handle matching handlers */
|
||||||
|
for (task = tasks_running.front; task != NULL; task = task->next)
|
||||||
|
if (task->handler == data->handler)
|
||||||
|
{
|
||||||
|
/* Create new link */
|
||||||
|
info = malloc(sizeof(task_retriever_info_t));
|
||||||
|
info->data = malloc(data->element_size);
|
||||||
|
info->next = NULL;
|
||||||
|
|
||||||
|
/* Call retriever function and fill info-specific data */
|
||||||
|
if (!data->func(task, info->data))
|
||||||
|
{
|
||||||
|
free(info->data);
|
||||||
|
free(info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add link to list */
|
||||||
|
if (data->list == NULL)
|
||||||
|
{
|
||||||
|
data->list = info;
|
||||||
|
tail = data->list;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tail->next = info;
|
||||||
|
tail = tail->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct retro_task_impl impl_regular = {
|
static struct retro_task_impl impl_regular = {
|
||||||
retro_task_regular_push_running,
|
retro_task_regular_push_running,
|
||||||
retro_task_regular_cancel,
|
retro_task_regular_cancel,
|
||||||
@ -244,6 +282,7 @@ static struct retro_task_impl impl_regular = {
|
|||||||
retro_task_regular_wait,
|
retro_task_regular_wait,
|
||||||
retro_task_regular_gather,
|
retro_task_regular_gather,
|
||||||
retro_task_regular_find,
|
retro_task_regular_find,
|
||||||
|
retro_task_regular_retrieve,
|
||||||
retro_task_regular_init,
|
retro_task_regular_init,
|
||||||
retro_task_regular_deinit
|
retro_task_regular_deinit
|
||||||
};
|
};
|
||||||
@ -341,6 +380,20 @@ static bool retro_task_threaded_find(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void retro_task_threaded_retrieve(task_retriever_data_t *data)
|
||||||
|
{
|
||||||
|
retro_task_t *task;
|
||||||
|
|
||||||
|
/* Protect access to running tasks */
|
||||||
|
slock_lock(running_lock);
|
||||||
|
|
||||||
|
/* Call regular retrieve function */
|
||||||
|
retro_task_regular_retrieve(data);
|
||||||
|
|
||||||
|
/* Release access to running tasks */
|
||||||
|
slock_unlock(running_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void threaded_worker(void *userdata)
|
static void threaded_worker(void *userdata)
|
||||||
{
|
{
|
||||||
(void)userdata;
|
(void)userdata;
|
||||||
@ -430,6 +483,7 @@ static struct retro_task_impl impl_threaded = {
|
|||||||
retro_task_threaded_wait,
|
retro_task_threaded_wait,
|
||||||
retro_task_threaded_gather,
|
retro_task_threaded_gather,
|
||||||
retro_task_threaded_find,
|
retro_task_threaded_find,
|
||||||
|
retro_task_threaded_retrieve,
|
||||||
retro_task_threaded_init,
|
retro_task_threaded_init,
|
||||||
retro_task_threaded_deinit
|
retro_task_threaded_deinit
|
||||||
};
|
};
|
||||||
@ -480,6 +534,9 @@ bool task_queue_ctl(enum task_queue_ctl_state state, void *data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TASK_QUEUE_CTL_RETRIEVE:
|
||||||
|
impl_current->retrieve(data);
|
||||||
|
break;
|
||||||
case TASK_QUEUE_CTL_CHECK:
|
case TASK_QUEUE_CTL_CHECK:
|
||||||
{
|
{
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
@ -526,3 +583,32 @@ void task_queue_cancel_task(void *task)
|
|||||||
{
|
{
|
||||||
task_queue_ctl(TASK_QUEUE_CTL_CANCEL, task);
|
task_queue_ctl(TASK_QUEUE_CTL_CANCEL, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *task_queue_retriever_info_next(task_retriever_info_t **link)
|
||||||
|
{
|
||||||
|
void *data = NULL;
|
||||||
|
|
||||||
|
/* Grab data and move to next link */
|
||||||
|
if (*link)
|
||||||
|
{
|
||||||
|
data = (*link)->data;
|
||||||
|
*link = (*link)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void task_queue_retriever_info_free(task_retriever_info_t *list)
|
||||||
|
{
|
||||||
|
task_retriever_info_t *info;
|
||||||
|
|
||||||
|
/* Free links including retriever-specific data */
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
info = list->next;
|
||||||
|
free(list->data);
|
||||||
|
free(list);
|
||||||
|
list = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user