#define U_QUEUE_H
#include "os/os_thread.h"
+#include "util/list.h"
/* Job completion fence.
* Put this into your job structure.
int signalled;
};
+typedef void (*util_queue_execute_func)(void *job, int thread_index);
+
struct util_queue_job {
void *job;
struct util_queue_fence *fence;
+ util_queue_execute_func execute;
+ util_queue_execute_func cleanup;
};
/* Put this into your context. */
struct util_queue {
+ const char *name;
pipe_mutex lock;
- pipe_semaphore has_space;
- pipe_semaphore queued;
- pipe_thread thread;
- int kill_thread;
+ pipe_condvar has_queued_cond;
+ pipe_condvar has_space_cond;
+ pipe_thread *threads;
+ int num_queued;
+ unsigned num_threads;
+ int kill_threads;
int max_jobs;
int write_idx, read_idx; /* ring buffer pointers */
struct util_queue_job *jobs;
- void (*execute_job)(void *job);
+
+ /* for cleanup at exit(), protected by exit_mutex */
+ struct list_head head;
};
bool util_queue_init(struct util_queue *queue,
+ const char *name,
unsigned max_jobs,
- void (*execute_job)(void *));
+ unsigned num_threads);
void util_queue_destroy(struct util_queue *queue);
void util_queue_fence_init(struct util_queue_fence *fence);
void util_queue_fence_destroy(struct util_queue_fence *fence);
+/* optional cleanup callback is called after fence is signaled: */
void util_queue_add_job(struct util_queue *queue,
void *job,
- struct util_queue_fence *fence);
-void util_queue_job_wait(struct util_queue_fence *fence);
+ struct util_queue_fence *fence,
+ util_queue_execute_func execute,
+ util_queue_execute_func cleanup);
+
+void util_queue_fence_wait(struct util_queue_fence *fence);
+int64_t util_queue_get_thread_time_nano(struct util_queue *queue,
+ unsigned thread_index);
/* util_queue needs to be cleared to zeroes for this to work */
static inline bool
util_queue_is_initialized(struct util_queue *queue)
{
- return queue->thread != 0;
+ return queue->threads != NULL;
}
static inline bool