#include "taskqueue.h"\r
\r
cvar_t taskqueue_maxthreads = { CVAR_SAVE, "taskqueue_maxthreads", "32", "how many threads to use for executing tasks" };\r
-cvar_t taskqueue_linkedlist = { CVAR_SAVE, "taskqueue_linkedlist", "1", "whether to use a doubly linked list or an array for the FIFO queue" };\r
\r
typedef struct taskqueue_state_thread_s\r
{\r
int numthreads;\r
taskqueue_state_thread_t threads[1024];\r
\r
- // we can enqueue this many tasks before execution of them must proceed\r
- int queue_used;\r
- int queue_max; // size of queue array\r
- taskqueue_task_t **queue_tasks;\r
-\r
// command \r
Thread_SpinLock command_lock;\r
\r
\r
static taskqueue_state_t taskqueue_state;\r
\r
-int TaskQueue_Init(void)\r
+void TaskQueue_Init(void)\r
{\r
Cvar_RegisterVariable(&taskqueue_maxthreads);\r
- Cvar_RegisterVariable(&taskqueue_linkedlist);\r
// initialize the doubly-linked list header\r
taskqueue_state.list.next = &taskqueue_state.list;\r
taskqueue_state.list.prev = &taskqueue_state.list;\r
- return 0;\r
}\r
\r
void TaskQueue_Shutdown(void)\r
{\r
if (taskqueue_state.numthreads)\r
TaskQueue_Frame(true);\r
- if (taskqueue_state.queue_tasks)\r
- Mem_Free(taskqueue_state.queue_tasks);\r
- taskqueue_state.queue_tasks = NULL;\r
}\r
\r
static taskqueue_task_t *TaskQueue_GetPending(void)\r
t->prev->next = t->next;\r
t->prev = t->next = NULL;\r
}\r
- if (t == NULL)\r
- {\r
- if (taskqueue_state.queue_used > 0)\r
- {\r
- t = taskqueue_state.queue_tasks[0];\r
- taskqueue_state.queue_used--;\r
- memmove(taskqueue_state.queue_tasks, taskqueue_state.queue_tasks + 1, taskqueue_state.queue_used * sizeof(taskqueue_task_t *));\r
- taskqueue_state.queue_tasks[taskqueue_state.queue_used] = NULL;\r
- }\r
- }\r
return t;\r
}\r
\r
for (i = 0; i < numtasks; i++)\r
{\r
taskqueue_task_t *t = &tasks[i];\r
- if (taskqueue_linkedlist.integer)\r
- {\r
- // push to list.prev\r
- t->next = &taskqueue_state.list;\r
- t->prev = taskqueue_state.list.prev;\r
- t->next->prev = t;\r
- t->prev->next = t;\r
- }\r
- else\r
- {\r
- if (taskqueue_state.queue_used >= taskqueue_state.queue_max)\r
- {\r
- taskqueue_state.queue_max *= 2;\r
- if (taskqueue_state.queue_max < 1024)\r
- taskqueue_state.queue_max = 1024;\r
- taskqueue_state.queue_tasks = (taskqueue_task_t **)Mem_Realloc(cls.permanentmempool, taskqueue_state.queue_tasks, taskqueue_state.queue_max * sizeof(taskqueue_task_t *));\r
- }\r
- taskqueue_state.queue_tasks[taskqueue_state.queue_used++] = t;\r
- }\r
+ // push to list.prev\r
+ t->next = &taskqueue_state.list;\r
+ t->prev = taskqueue_state.list.prev;\r
+ t->next->prev = t;\r
+ t->prev->next = t;\r
}\r
Thread_AtomicUnlock(&taskqueue_state.command_lock);\r
}\r
// polls for status of task and waits for it to be done\r
void TaskQueue_WaitForTaskDone(taskqueue_task_t *t);\r
\r
-// updates thread count based on the cvar.\r
-void TaskQueue_Frame(qboolean shutdown);\r
-\r
// convenience function for setting up a task structure. Does not do the Enqueue, just fills in the struct.\r
void TaskQueue_Setup(taskqueue_task_t *t, taskqueue_task_t *preceding, void(*func)(taskqueue_task_t *), size_t i0, size_t i1, void *p0, void *p1);\r
\r
// t->p[0] = array of taskqueue_task_t to check\r
void TaskQueue_Task_CheckTasksDone(taskqueue_task_t *t);\r
\r
+void TaskQueue_Init(void);\r
+void TaskQueue_Shutdown(void);\r
+void TaskQueue_Frame(qboolean shutdown);\r
+\r
#endif\r