rng: switch request queue to QSIMPLEQ
QSIMPLEQ supports appending to tail in O(1) and is intrusive so it doesn't require extra memory allocations for the bookkeeping data. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Ladi Prosek <lprosek@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Amit Shah <amit.shah@redhat.com> Message-Id: <1457010971-24771-1-git-send-email-lprosek@redhat.com> Signed-off-by: Amit Shah <amit.shah@redhat.com>
This commit is contained in:
parent
97556fe80e
commit
443590c204
@ -49,11 +49,10 @@ static void rng_egd_request_entropy(RngBackend *b, RngRequest *req)
|
|||||||
static int rng_egd_chr_can_read(void *opaque)
|
static int rng_egd_chr_can_read(void *opaque)
|
||||||
{
|
{
|
||||||
RngEgd *s = RNG_EGD(opaque);
|
RngEgd *s = RNG_EGD(opaque);
|
||||||
GSList *i;
|
RngRequest *req;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
for (i = s->parent.requests; i; i = i->next) {
|
QSIMPLEQ_FOREACH(req, &s->parent.requests, next) {
|
||||||
RngRequest *req = i->data;
|
|
||||||
size += req->size - req->offset;
|
size += req->size - req->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,8 +64,8 @@ static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
|
|||||||
RngEgd *s = RNG_EGD(opaque);
|
RngEgd *s = RNG_EGD(opaque);
|
||||||
size_t buf_offset = 0;
|
size_t buf_offset = 0;
|
||||||
|
|
||||||
while (size > 0 && s->parent.requests) {
|
while (size > 0 && !QSIMPLEQ_EMPTY(&s->parent.requests)) {
|
||||||
RngRequest *req = s->parent.requests->data;
|
RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests);
|
||||||
int len = MIN(size, req->size - req->offset);
|
int len = MIN(size, req->size - req->offset);
|
||||||
|
|
||||||
memcpy(req->data + req->offset, buf + buf_offset, len);
|
memcpy(req->data + req->offset, buf + buf_offset, len);
|
||||||
|
@ -35,8 +35,8 @@ static void entropy_available(void *opaque)
|
|||||||
{
|
{
|
||||||
RndRandom *s = RNG_RANDOM(opaque);
|
RndRandom *s = RNG_RANDOM(opaque);
|
||||||
|
|
||||||
while (s->parent.requests != NULL) {
|
while (!QSIMPLEQ_EMPTY(&s->parent.requests)) {
|
||||||
RngRequest *req = s->parent.requests->data;
|
RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests);
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
len = read(s->fd, req->data, req->size);
|
len = read(s->fd, req->data, req->size);
|
||||||
@ -58,7 +58,7 @@ static void rng_random_request_entropy(RngBackend *b, RngRequest *req)
|
|||||||
{
|
{
|
||||||
RndRandom *s = RNG_RANDOM(b);
|
RndRandom *s = RNG_RANDOM(b);
|
||||||
|
|
||||||
if (s->parent.requests == NULL) {
|
if (QSIMPLEQ_EMPTY(&s->parent.requests)) {
|
||||||
/* If there are no pending requests yet, we need to
|
/* If there are no pending requests yet, we need to
|
||||||
* install our fd handler. */
|
* install our fd handler. */
|
||||||
qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
|
qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
|
||||||
|
@ -33,7 +33,7 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
|
|||||||
|
|
||||||
k->request_entropy(s, req);
|
k->request_entropy(s, req);
|
||||||
|
|
||||||
s->requests = g_slist_append(s->requests, req);
|
QSIMPLEQ_INSERT_TAIL(&s->requests, req, next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,24 +83,27 @@ static void rng_backend_free_request(RngRequest *req)
|
|||||||
|
|
||||||
static void rng_backend_free_requests(RngBackend *s)
|
static void rng_backend_free_requests(RngBackend *s)
|
||||||
{
|
{
|
||||||
GSList *i;
|
RngRequest *req, *next;
|
||||||
|
|
||||||
for (i = s->requests; i; i = i->next) {
|
QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) {
|
||||||
rng_backend_free_request(i->data);
|
rng_backend_free_request(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_slist_free(s->requests);
|
QSIMPLEQ_INIT(&s->requests);
|
||||||
s->requests = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
|
void rng_backend_finalize_request(RngBackend *s, RngRequest *req)
|
||||||
{
|
{
|
||||||
s->requests = g_slist_remove(s->requests, req);
|
QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next);
|
||||||
rng_backend_free_request(req);
|
rng_backend_free_request(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rng_backend_init(Object *obj)
|
static void rng_backend_init(Object *obj)
|
||||||
{
|
{
|
||||||
|
RngBackend *s = RNG_BACKEND(obj);
|
||||||
|
|
||||||
|
QSIMPLEQ_INIT(&s->requests);
|
||||||
|
|
||||||
object_property_add_bool(obj, "opened",
|
object_property_add_bool(obj, "opened",
|
||||||
rng_backend_prop_get_opened,
|
rng_backend_prop_get_opened,
|
||||||
rng_backend_prop_set_opened,
|
rng_backend_prop_set_opened,
|
||||||
|
@ -39,6 +39,7 @@ struct RngRequest
|
|||||||
void *opaque;
|
void *opaque;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
QSIMPLEQ_ENTRY(RngRequest) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RngBackendClass
|
struct RngBackendClass
|
||||||
@ -56,7 +57,7 @@ struct RngBackend
|
|||||||
|
|
||||||
/*< protected >*/
|
/*< protected >*/
|
||||||
bool opened;
|
bool opened;
|
||||||
GSList *requests;
|
QSIMPLEQ_HEAD(requests, RngRequest) requests;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user