|
@@ -23,9 +23,9 @@
|
|
#include "block/thread-pool.h"
|
|
#include "block/thread-pool.h"
|
|
#include "qemu/main-loop.h"
|
|
#include "qemu/main-loop.h"
|
|
|
|
|
|
-static void do_spawn_thread(ThreadPool *pool);
|
|
|
|
|
|
+static void do_spawn_thread(ThreadPoolAio *pool);
|
|
|
|
|
|
-typedef struct ThreadPoolElement ThreadPoolElement;
|
|
|
|
|
|
+typedef struct ThreadPoolElementAio ThreadPoolElementAio;
|
|
|
|
|
|
enum ThreadState {
|
|
enum ThreadState {
|
|
THREAD_QUEUED,
|
|
THREAD_QUEUED,
|
|
@@ -33,9 +33,9 @@ enum ThreadState {
|
|
THREAD_DONE,
|
|
THREAD_DONE,
|
|
};
|
|
};
|
|
|
|
|
|
-struct ThreadPoolElement {
|
|
|
|
|
|
+struct ThreadPoolElementAio {
|
|
BlockAIOCB common;
|
|
BlockAIOCB common;
|
|
- ThreadPool *pool;
|
|
|
|
|
|
+ ThreadPoolAio *pool;
|
|
ThreadPoolFunc *func;
|
|
ThreadPoolFunc *func;
|
|
void *arg;
|
|
void *arg;
|
|
|
|
|
|
@@ -47,13 +47,13 @@ struct ThreadPoolElement {
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
/* Access to this list is protected by lock. */
|
|
/* Access to this list is protected by lock. */
|
|
- QTAILQ_ENTRY(ThreadPoolElement) reqs;
|
|
|
|
|
|
+ QTAILQ_ENTRY(ThreadPoolElementAio) reqs;
|
|
|
|
|
|
/* This list is only written by the thread pool's mother thread. */
|
|
/* This list is only written by the thread pool's mother thread. */
|
|
- QLIST_ENTRY(ThreadPoolElement) all;
|
|
|
|
|
|
+ QLIST_ENTRY(ThreadPoolElementAio) all;
|
|
};
|
|
};
|
|
|
|
|
|
-struct ThreadPool {
|
|
|
|
|
|
+struct ThreadPoolAio {
|
|
AioContext *ctx;
|
|
AioContext *ctx;
|
|
QEMUBH *completion_bh;
|
|
QEMUBH *completion_bh;
|
|
QemuMutex lock;
|
|
QemuMutex lock;
|
|
@@ -62,10 +62,10 @@ struct ThreadPool {
|
|
QEMUBH *new_thread_bh;
|
|
QEMUBH *new_thread_bh;
|
|
|
|
|
|
/* The following variables are only accessed from one AioContext. */
|
|
/* The following variables are only accessed from one AioContext. */
|
|
- QLIST_HEAD(, ThreadPoolElement) head;
|
|
|
|
|
|
+ QLIST_HEAD(, ThreadPoolElementAio) head;
|
|
|
|
|
|
/* The following variables are protected by lock. */
|
|
/* The following variables are protected by lock. */
|
|
- QTAILQ_HEAD(, ThreadPoolElement) request_list;
|
|
|
|
|
|
+ QTAILQ_HEAD(, ThreadPoolElementAio) request_list;
|
|
int cur_threads;
|
|
int cur_threads;
|
|
int idle_threads;
|
|
int idle_threads;
|
|
int new_threads; /* backlog of threads we need to create */
|
|
int new_threads; /* backlog of threads we need to create */
|
|
@@ -76,14 +76,14 @@ struct ThreadPool {
|
|
|
|
|
|
static void *worker_thread(void *opaque)
|
|
static void *worker_thread(void *opaque)
|
|
{
|
|
{
|
|
- ThreadPool *pool = opaque;
|
|
|
|
|
|
+ ThreadPoolAio *pool = opaque;
|
|
|
|
|
|
qemu_mutex_lock(&pool->lock);
|
|
qemu_mutex_lock(&pool->lock);
|
|
pool->pending_threads--;
|
|
pool->pending_threads--;
|
|
do_spawn_thread(pool);
|
|
do_spawn_thread(pool);
|
|
|
|
|
|
while (pool->cur_threads <= pool->max_threads) {
|
|
while (pool->cur_threads <= pool->max_threads) {
|
|
- ThreadPoolElement *req;
|
|
|
|
|
|
+ ThreadPoolElementAio *req;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
if (QTAILQ_EMPTY(&pool->request_list)) {
|
|
if (QTAILQ_EMPTY(&pool->request_list)) {
|
|
@@ -131,7 +131,7 @@ static void *worker_thread(void *opaque)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-static void do_spawn_thread(ThreadPool *pool)
|
|
|
|
|
|
+static void do_spawn_thread(ThreadPoolAio *pool)
|
|
{
|
|
{
|
|
QemuThread t;
|
|
QemuThread t;
|
|
|
|
|
|
@@ -148,14 +148,14 @@ static void do_spawn_thread(ThreadPool *pool)
|
|
|
|
|
|
static void spawn_thread_bh_fn(void *opaque)
|
|
static void spawn_thread_bh_fn(void *opaque)
|
|
{
|
|
{
|
|
- ThreadPool *pool = opaque;
|
|
|
|
|
|
+ ThreadPoolAio *pool = opaque;
|
|
|
|
|
|
qemu_mutex_lock(&pool->lock);
|
|
qemu_mutex_lock(&pool->lock);
|
|
do_spawn_thread(pool);
|
|
do_spawn_thread(pool);
|
|
qemu_mutex_unlock(&pool->lock);
|
|
qemu_mutex_unlock(&pool->lock);
|
|
}
|
|
}
|
|
|
|
|
|
-static void spawn_thread(ThreadPool *pool)
|
|
|
|
|
|
+static void spawn_thread(ThreadPoolAio *pool)
|
|
{
|
|
{
|
|
pool->cur_threads++;
|
|
pool->cur_threads++;
|
|
pool->new_threads++;
|
|
pool->new_threads++;
|
|
@@ -173,8 +173,8 @@ static void spawn_thread(ThreadPool *pool)
|
|
|
|
|
|
static void thread_pool_completion_bh(void *opaque)
|
|
static void thread_pool_completion_bh(void *opaque)
|
|
{
|
|
{
|
|
- ThreadPool *pool = opaque;
|
|
|
|
- ThreadPoolElement *elem, *next;
|
|
|
|
|
|
+ ThreadPoolAio *pool = opaque;
|
|
|
|
+ ThreadPoolElementAio *elem, *next;
|
|
|
|
|
|
defer_call_begin(); /* cb() may use defer_call() to coalesce work */
|
|
defer_call_begin(); /* cb() may use defer_call() to coalesce work */
|
|
|
|
|
|
@@ -184,8 +184,8 @@ restart:
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- trace_thread_pool_complete(pool, elem, elem->common.opaque,
|
|
|
|
- elem->ret);
|
|
|
|
|
|
+ trace_thread_pool_complete_aio(pool, elem, elem->common.opaque,
|
|
|
|
+ elem->ret);
|
|
QLIST_REMOVE(elem, all);
|
|
QLIST_REMOVE(elem, all);
|
|
|
|
|
|
if (elem->common.cb) {
|
|
if (elem->common.cb) {
|
|
@@ -217,10 +217,10 @@ restart:
|
|
|
|
|
|
static void thread_pool_cancel(BlockAIOCB *acb)
|
|
static void thread_pool_cancel(BlockAIOCB *acb)
|
|
{
|
|
{
|
|
- ThreadPoolElement *elem = (ThreadPoolElement *)acb;
|
|
|
|
- ThreadPool *pool = elem->pool;
|
|
|
|
|
|
+ ThreadPoolElementAio *elem = (ThreadPoolElementAio *)acb;
|
|
|
|
+ ThreadPoolAio *pool = elem->pool;
|
|
|
|
|
|
- trace_thread_pool_cancel(elem, elem->common.opaque);
|
|
|
|
|
|
+ trace_thread_pool_cancel_aio(elem, elem->common.opaque);
|
|
|
|
|
|
QEMU_LOCK_GUARD(&pool->lock);
|
|
QEMU_LOCK_GUARD(&pool->lock);
|
|
if (elem->state == THREAD_QUEUED) {
|
|
if (elem->state == THREAD_QUEUED) {
|
|
@@ -234,16 +234,16 @@ static void thread_pool_cancel(BlockAIOCB *acb)
|
|
}
|
|
}
|
|
|
|
|
|
static const AIOCBInfo thread_pool_aiocb_info = {
|
|
static const AIOCBInfo thread_pool_aiocb_info = {
|
|
- .aiocb_size = sizeof(ThreadPoolElement),
|
|
|
|
|
|
+ .aiocb_size = sizeof(ThreadPoolElementAio),
|
|
.cancel_async = thread_pool_cancel,
|
|
.cancel_async = thread_pool_cancel,
|
|
};
|
|
};
|
|
|
|
|
|
BlockAIOCB *thread_pool_submit_aio(ThreadPoolFunc *func, void *arg,
|
|
BlockAIOCB *thread_pool_submit_aio(ThreadPoolFunc *func, void *arg,
|
|
BlockCompletionFunc *cb, void *opaque)
|
|
BlockCompletionFunc *cb, void *opaque)
|
|
{
|
|
{
|
|
- ThreadPoolElement *req;
|
|
|
|
|
|
+ ThreadPoolElementAio *req;
|
|
AioContext *ctx = qemu_get_current_aio_context();
|
|
AioContext *ctx = qemu_get_current_aio_context();
|
|
- ThreadPool *pool = aio_get_thread_pool(ctx);
|
|
|
|
|
|
+ ThreadPoolAio *pool = aio_get_thread_pool(ctx);
|
|
|
|
|
|
/* Assert that the thread submitting work is the same running the pool */
|
|
/* Assert that the thread submitting work is the same running the pool */
|
|
assert(pool->ctx == qemu_get_current_aio_context());
|
|
assert(pool->ctx == qemu_get_current_aio_context());
|
|
@@ -290,7 +290,7 @@ int coroutine_fn thread_pool_submit_co(ThreadPoolFunc *func, void *arg)
|
|
return tpc.ret;
|
|
return tpc.ret;
|
|
}
|
|
}
|
|
|
|
|
|
-void thread_pool_update_params(ThreadPool *pool, AioContext *ctx)
|
|
|
|
|
|
+void thread_pool_update_params(ThreadPoolAio *pool, AioContext *ctx)
|
|
{
|
|
{
|
|
qemu_mutex_lock(&pool->lock);
|
|
qemu_mutex_lock(&pool->lock);
|
|
|
|
|
|
@@ -317,7 +317,7 @@ void thread_pool_update_params(ThreadPool *pool, AioContext *ctx)
|
|
qemu_mutex_unlock(&pool->lock);
|
|
qemu_mutex_unlock(&pool->lock);
|
|
}
|
|
}
|
|
|
|
|
|
-static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
|
|
|
|
|
|
+static void thread_pool_init_one(ThreadPoolAio *pool, AioContext *ctx)
|
|
{
|
|
{
|
|
if (!ctx) {
|
|
if (!ctx) {
|
|
ctx = qemu_get_aio_context();
|
|
ctx = qemu_get_aio_context();
|
|
@@ -337,14 +337,14 @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
|
|
thread_pool_update_params(pool, ctx);
|
|
thread_pool_update_params(pool, ctx);
|
|
}
|
|
}
|
|
|
|
|
|
-ThreadPool *thread_pool_new(AioContext *ctx)
|
|
|
|
|
|
+ThreadPoolAio *thread_pool_new_aio(AioContext *ctx)
|
|
{
|
|
{
|
|
- ThreadPool *pool = g_new(ThreadPool, 1);
|
|
|
|
|
|
+ ThreadPoolAio *pool = g_new(ThreadPoolAio, 1);
|
|
thread_pool_init_one(pool, ctx);
|
|
thread_pool_init_one(pool, ctx);
|
|
return pool;
|
|
return pool;
|
|
}
|
|
}
|
|
|
|
|
|
-void thread_pool_free(ThreadPool *pool)
|
|
|
|
|
|
+void thread_pool_free_aio(ThreadPoolAio *pool)
|
|
{
|
|
{
|
|
if (!pool) {
|
|
if (!pool) {
|
|
return;
|
|
return;
|