#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_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, int thread_index);
+
+ /* 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,
- unsigned num_threads,
- void (*execute_job)(void *, int));
+ 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