char: allocate CharDriverState as a single object

Use a single allocation for CharDriverState, this avoids extra
allocations & pointers, and is a step towards more object-oriented
CharDriver.

Gtk console is a bit peculiar, gd_vc_chr_set_echo() used to have a
temporary VirtualConsole to save the echo bit. Instead now, we consider
whether vcd->console is set or not, and restore the echo bit saved in
VCDriverState when calling gd_vc_vte_init().

The casts added are temporary, they are replaced with QOM type-safe
macros in a later patch in this series.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Marc-André Lureau 2016-10-21 23:44:44 +03:00 committed by Paolo Bonzini
parent 5ebd67030c
commit 41ac54b253
10 changed files with 230 additions and 214 deletions

View File

@ -85,7 +85,7 @@
#define BUF_SIZE 256
typedef struct {
CharDriverState *chr;
CharDriverState parent;
brlapi_handle_t *brlapi;
int brlapi_fd;
@ -255,7 +255,7 @@ static int baum_deferred_init(BaumDriverState *baum)
/* The serial port can receive more of our data */
static void baum_accept_input(struct CharDriverState *chr)
{
BaumDriverState *baum = chr->opaque;
BaumDriverState *baum = (BaumDriverState *)chr;
int room, first;
if (!baum->out_buf_used)
@ -281,22 +281,23 @@ static void baum_accept_input(struct CharDriverState *chr)
/* We want to send a packet */
static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len)
{
CharDriverState *chr = (CharDriverState *)baum;
uint8_t io_buf[1 + 2 * len], *cur = io_buf;
int room;
*cur++ = ESC;
while (len--)
if ((*cur++ = *buf++) == ESC)
*cur++ = ESC;
room = qemu_chr_be_can_write(baum->chr);
room = qemu_chr_be_can_write(chr);
len = cur - io_buf;
if (len <= room) {
/* Fits */
qemu_chr_be_write(baum->chr, io_buf, len);
qemu_chr_be_write(chr, io_buf, len);
} else {
int first;
uint8_t out;
/* Can't fit all, send what can be, and store the rest. */
qemu_chr_be_write(baum->chr, io_buf, room);
qemu_chr_be_write(chr, io_buf, room);
len -= room;
cur = io_buf + room;
if (len > BUF_SIZE - baum->out_buf_used) {
@ -471,7 +472,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
/* The other end is writing some data. Store it and try to interpret */
static int baum_write(CharDriverState *chr, const uint8_t *buf, int len)
{
BaumDriverState *baum = chr->opaque;
BaumDriverState *baum = (BaumDriverState *)chr;
int tocopy, cur, eaten, orig_len = len;
if (!len)
@ -612,14 +613,13 @@ static void baum_chr_read(void *opaque)
static void baum_free(struct CharDriverState *chr)
{
BaumDriverState *baum = chr->opaque;
BaumDriverState *baum = (BaumDriverState *)chr;
timer_free(baum->cellCount_timer);
if (baum->brlapi) {
brlapi__closeConnection(baum->brlapi);
g_free(baum->brlapi);
}
g_free(baum);
}
static CharDriverState *chr_baum_init(const CharDriver *driver,
@ -638,10 +638,7 @@ static CharDriverState *chr_baum_init(const CharDriver *driver,
if (!chr) {
return NULL;
}
baum = g_malloc0(sizeof(BaumDriverState));
baum->chr = chr;
chr->opaque = baum;
baum = (BaumDriverState *)chr;
handle = g_malloc0(brlapi_getHandleSize());
baum->brlapi = handle;
@ -663,13 +660,13 @@ static CharDriverState *chr_baum_init(const CharDriver *driver,
fail_handle:
g_free(handle);
g_free(chr);
g_free(baum);
return NULL;
}
static void register_types(void)
{
static const CharDriver driver = {
.instance_size = sizeof(BaumDriverState),
.kind = CHARDEV_BACKEND_KIND_BRAILLE,
.create = chr_baum_init,
.chr_write = baum_write,

View File

@ -31,7 +31,8 @@
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
typedef struct {
CharDriverState *chr;
CharDriverState parent;
QemuInputHandlerState *hs;
int axis[INPUT_AXIS__MAX];
bool btns[INPUT_BUTTON__MAX];
@ -42,7 +43,7 @@ typedef struct {
static void msmouse_chr_accept_input(CharDriverState *chr)
{
MouseState *mouse = chr->opaque;
MouseState *mouse = (MouseState *)chr;
int len;
len = qemu_chr_be_can_write(chr);
@ -122,9 +123,10 @@ static void msmouse_input_event(DeviceState *dev, QemuConsole *src,
static void msmouse_input_sync(DeviceState *dev)
{
MouseState *mouse = (MouseState *)dev;
CharDriverState *chr = (CharDriverState *)dev;
msmouse_queue_event(mouse);
msmouse_chr_accept_input(mouse->chr);
msmouse_chr_accept_input(chr);
}
static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
@ -135,10 +137,9 @@ static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int
static void msmouse_chr_free(struct CharDriverState *chr)
{
MouseState *mouse = chr->opaque;
MouseState *mouse = (MouseState *)chr;
qemu_input_handler_unregister(mouse->hs);
g_free(mouse);
}
static QemuInputHandler msmouse_handler = {
@ -165,12 +166,10 @@ static CharDriverState *qemu_chr_open_msmouse(const CharDriver *driver,
}
*be_opened = false;
mouse = g_new0(MouseState, 1);
mouse = (MouseState *)chr;
mouse->hs = qemu_input_handler_register((DeviceState *)mouse,
&msmouse_handler);
mouse->chr = chr;
chr->opaque = mouse;
return chr;
}
@ -178,6 +177,7 @@ static CharDriverState *qemu_chr_open_msmouse(const CharDriver *driver,
static void register_types(void)
{
static const CharDriver driver = {
.instance_size = sizeof(MouseState),
.kind = CHARDEV_BACKEND_KIND_MSMOUSE,
.create = qemu_chr_open_msmouse,
.chr_write = msmouse_chr_write,

View File

@ -30,7 +30,8 @@
#define BUF_SIZE 32
typedef struct {
CharDriverState *chr;
CharDriverState parent;
uint8_t in_buf[32];
int in_buf_used;
} TestdevCharState;
@ -79,7 +80,7 @@ static int testdev_eat_packet(TestdevCharState *testdev)
/* The other end is writing some data. Store it and try to interpret */
static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
{
TestdevCharState *testdev = chr->opaque;
TestdevCharState *testdev = (TestdevCharState *)chr;
int tocopy, eaten, orig_len = len;
while (len) {
@ -102,13 +103,6 @@ static int testdev_write(CharDriverState *chr, const uint8_t *buf, int len)
return orig_len;
}
static void testdev_free(struct CharDriverState *chr)
{
TestdevCharState *testdev = chr->opaque;
g_free(testdev);
}
static CharDriverState *chr_testdev_init(const CharDriver *driver,
const char *id,
ChardevBackend *backend,
@ -116,14 +110,10 @@ static CharDriverState *chr_testdev_init(const CharDriver *driver,
bool *be_opened,
Error **errp)
{
TestdevCharState *testdev;
CharDriverState *chr;
testdev = g_new0(TestdevCharState, 1);
testdev->chr = chr = g_new0(CharDriverState, 1);
TestdevCharState *testdev = g_new0(TestdevCharState, 1);;
CharDriverState *chr = (CharDriverState *)testdev;
chr->driver = driver;
chr->opaque = testdev;
return chr;
}
@ -131,10 +121,10 @@ static CharDriverState *chr_testdev_init(const CharDriver *driver,
static void register_types(void)
{
static const CharDriver driver = {
.instance_size = sizeof(TestdevCharState),
.kind = CHARDEV_BACKEND_KIND_TESTDEV,
.create = chr_testdev_init,
.chr_write = testdev_write,
.chr_free = testdev_free,
};
register_char_driver(&driver);
}

View File

@ -1733,6 +1733,7 @@ int gdbserver_start(const char *device)
CharDriverState *mon_chr;
ChardevCommon common = { 0 };
static const CharDriver driver = {
.instance_size = sizeof(CharDriverState),
.kind = -1,
.chr_write = gdb_monitor_write,
};

View File

@ -28,11 +28,11 @@
#include "hw/bt.h"
struct csrhci_s {
CharDriverState chr;
int enable;
qemu_irq *pins;
int pin_state;
int modem_state;
CharDriverState chr;
#define FIFO_LEN 4096
int out_start;
int out_len;
@ -314,7 +314,7 @@ static void csrhci_ready_for_next_inpkt(struct csrhci_s *s)
static int csrhci_write(struct CharDriverState *chr,
const uint8_t *buf, int len)
{
struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
struct csrhci_s *s = (struct csrhci_s *)chr;
int total = 0;
if (!s->enable)
@ -387,7 +387,7 @@ static void csrhci_out_hci_packet_acl(void *opaque,
static int csrhci_ioctl(struct CharDriverState *chr, int cmd, void *arg)
{
QEMUSerialSetParams *ssp;
struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
struct csrhci_s *s = (struct csrhci_s *) chr;
int prev_state = s->modem_state;
switch (cmd) {
@ -455,7 +455,7 @@ static void csrhci_pins(void *opaque, int line, int level)
qemu_irq *csrhci_pins_get(CharDriverState *chr)
{
struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
struct csrhci_s *s = (struct csrhci_s *) chr;
return s->pins;
}
@ -463,6 +463,7 @@ qemu_irq *csrhci_pins_get(CharDriverState *chr)
CharDriverState *uart_hci_init(void)
{
static const CharDriver hci_driver = {
.instance_size = sizeof(struct csrhci_s),
.kind = -1,
.chr_write = csrhci_write,
.chr_ioctl = csrhci_ioctl,
@ -470,7 +471,6 @@ CharDriverState *uart_hci_init(void)
struct csrhci_s *s = (struct csrhci_s *)
g_malloc0(sizeof(struct csrhci_s));
s->chr.opaque = s;
s->chr.driver = &hci_driver;
s->hci = qemu_next_hci();

View File

@ -93,7 +93,6 @@ struct CharDriverState {
const CharDriver *driver;
QemuMutex chr_write_lock;
CharBackend *be;
void *opaque;
char *label;
char *filename;
int logfd;
@ -484,6 +483,7 @@ struct CharDriver {
ChardevBackend *backend,
ChardevReturn *ret, bool *be_opened,
Error **errp);
size_t instance_size;
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
int (*chr_sync_read)(struct CharDriverState *s,

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,8 @@
typedef struct SpiceCharDriver {
CharDriverState* chr;
CharDriverState parent;
SpiceCharDeviceInstance sin;
bool active;
bool blocked;
@ -27,17 +28,18 @@ static QLIST_HEAD(, SpiceCharDriver) spice_chars =
static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
{
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
CharDriverState *chr = (CharDriverState *)scd;
ssize_t out = 0;
ssize_t last_out;
uint8_t* p = (uint8_t*)buf;
while (len > 0) {
int can_write = qemu_chr_be_can_write(scd->chr);
int can_write = qemu_chr_be_can_write(chr);
last_out = MIN(len, can_write);
if (last_out <= 0) {
break;
}
qemu_chr_be_write(scd->chr, p, last_out);
qemu_chr_be_write(chr, p, last_out);
out += last_out;
len -= last_out;
p += last_out;
@ -70,6 +72,7 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
{
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
CharDriverState *chr = (CharDriverState *)scd;
int chr_event;
switch (event) {
@ -81,20 +84,21 @@ static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
}
trace_spice_vmc_event(chr_event);
qemu_chr_be_event(scd->chr, chr_event);
qemu_chr_be_event(chr, chr_event);
}
#endif
static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
{
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
CharDriverState *chr = (CharDriverState *)scd;
if ((scd->chr->be_open && connected) ||
(!scd->chr->be_open && !connected)) {
if ((chr->be_open && connected) ||
(!chr->be_open && !connected)) {
return;
}
qemu_chr_be_event(scd->chr,
qemu_chr_be_event(chr,
connected ? CHR_EVENT_OPENED : CHR_EVENT_CLOSED);
}
@ -168,7 +172,7 @@ static GSourceFuncs SpiceCharSourceFuncs = {
static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond)
{
SpiceCharDriver *scd = chr->opaque;
SpiceCharDriver *scd = (SpiceCharDriver *)chr;
SpiceCharSource *src;
assert(cond & G_IO_OUT);
@ -182,7 +186,7 @@ static GSource *spice_chr_add_watch(CharDriverState *chr, GIOCondition cond)
static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
SpiceCharDriver *s = chr->opaque;
SpiceCharDriver *s = (SpiceCharDriver *)chr;
int read_bytes;
assert(s->datalen == 0);
@ -201,7 +205,7 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
static void spice_chr_free(struct CharDriverState *chr)
{
SpiceCharDriver *s = chr->opaque;
SpiceCharDriver *s = (SpiceCharDriver *)chr;
vmc_unregister_interface(s);
QLIST_REMOVE(s, next);
@ -210,12 +214,11 @@ static void spice_chr_free(struct CharDriverState *chr)
#if SPICE_SERVER_VERSION >= 0x000c02
g_free((char *)s->sin.portname);
#endif
g_free(s);
}
static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open)
{
SpiceCharDriver *s = chr->opaque;
SpiceCharDriver *s = (SpiceCharDriver *)chr;
if (fe_open) {
vmc_register_interface(s);
} else {
@ -226,7 +229,7 @@ static void spice_vmc_set_fe_open(struct CharDriverState *chr, int fe_open)
static void spice_port_set_fe_open(struct CharDriverState *chr, int fe_open)
{
#if SPICE_SERVER_VERSION >= 0x000c02
SpiceCharDriver *s = chr->opaque;
SpiceCharDriver *s = (SpiceCharDriver *)chr;
if (fe_open) {
spice_server_port_event(&s->sin, SPICE_PORT_EVENT_OPENED);
@ -255,7 +258,7 @@ static void print_allowed_subtypes(void)
static void spice_chr_accept_input(struct CharDriverState *chr)
{
SpiceCharDriver *s = chr->opaque;
SpiceCharDriver *s = (SpiceCharDriver *)chr;
spice_server_char_device_wakeup(&s->sin);
}
@ -272,11 +275,9 @@ static CharDriverState *chr_open(const CharDriver *driver,
if (!chr) {
return NULL;
}
s = g_malloc0(sizeof(SpiceCharDriver));
s->chr = chr;
s = (SpiceCharDriver *)chr;
s->active = false;
s->sin.subtype = g_strdup(subtype);
chr->opaque = s;
QLIST_INSERT_HEAD(&spice_chars, s, next);
@ -334,7 +335,7 @@ static CharDriverState *qemu_chr_open_spice_port(const CharDriver *driver,
return NULL;
}
*be_opened = false;
s = chr->opaque;
s = (SpiceCharDriver *)chr;
s->sin.portname = g_strdup(name);
return chr;
@ -386,6 +387,7 @@ static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
static void register_types(void)
{
static const CharDriver vmc_driver = {
.instance_size = sizeof(SpiceCharDriver),
.kind = CHARDEV_BACKEND_KIND_SPICEVMC,
.parse = qemu_chr_parse_spice_vmc,
.create = qemu_chr_open_spice_vmc,
@ -396,6 +398,7 @@ static void register_types(void)
.chr_free = spice_chr_free,
};
static const CharDriver port_driver = {
.instance_size = sizeof(SpiceCharDriver),
.kind = CHARDEV_BACKEND_KIND_SPICEPORT,
.parse = qemu_chr_parse_spice_port,
.create = qemu_chr_open_spice_port,

View File

@ -1046,9 +1046,15 @@ void console_select(unsigned int index)
}
}
typedef struct VCDriverState {
CharDriverState parent;
QemuConsole *console;
} VCDriverState;
static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
{
QemuConsole *s = chr->opaque;
VCDriverState *drv = (VCDriverState *)chr;
QemuConsole *s = drv->console;
int i;
if (!s->ds) {
@ -1958,7 +1964,8 @@ int qemu_console_get_height(QemuConsole *con, int fallback)
static void text_console_set_echo(CharDriverState *chr, bool echo)
{
QemuConsole *s = chr->opaque;
VCDriverState *drv = (VCDriverState *)chr;
QemuConsole *s = drv->console;
s->echo = echo;
}
@ -1998,12 +2005,11 @@ static const GraphicHwOps text_console_ops = {
static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
{
QemuConsole *s;
VCDriverState *drv = (VCDriverState *)chr;
QemuConsole *s = drv->console;
int g_width = 80 * FONT_WIDTH;
int g_height = 24 * FONT_HEIGHT;
s = chr->opaque;
s->out_fifo.buf = s->out_fifo_buf;
s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s);
@ -2056,6 +2062,7 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
{
ChardevCommon *common = qapi_ChardevVC_base(vc);
CharDriverState *chr;
VCDriverState *drv;
QemuConsole *s;
unsigned width = 0;
unsigned height = 0;
@ -2092,7 +2099,8 @@ static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
}
s->chr = chr;
chr->opaque = s;
drv = (VCDriverState *)chr;
drv->console = s;
if (display_state) {
text_console_do_init(chr, display_state);
@ -2196,6 +2204,7 @@ static const TypeInfo qemu_console_info = {
};
static const CharDriver vc_driver = {
.instance_size = sizeof(VCDriverState),
.kind = CHARDEV_BACKEND_KIND_VC,
.parse = qemu_chr_parse_vc,
.create = vc_init,

View File

@ -181,6 +181,12 @@ struct GtkDisplayState {
bool ignore_keys;
};
typedef struct VCDriverState {
CharDriverState parent;
VirtualConsole *console;
bool echo;
} VCDriverState;
static void gd_grab_pointer(VirtualConsole *vc, const char *reason);
static void gd_ungrab_pointer(GtkDisplayState *s);
static void gd_grab_keyboard(VirtualConsole *vc, const char *reason);
@ -1685,7 +1691,8 @@ static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
{
VirtualConsole *vc = chr->opaque;
VCDriverState *vcd = (VCDriverState *)chr;
VirtualConsole *vc = vcd->console;
vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len);
return len;
@ -1693,9 +1700,14 @@ static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
static void gd_vc_chr_set_echo(CharDriverState *chr, bool echo)
{
VirtualConsole *vc = chr->opaque;
VCDriverState *vcd = (VCDriverState *)chr;
VirtualConsole *vc = vcd->console;
vc->vte.echo = echo;
if (vc) {
vc->vte.echo = echo;
} else {
vcd->echo = echo;
}
}
static int nb_vcs;
@ -1704,6 +1716,7 @@ static CharDriverState *vcs[MAX_VCS];
static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp)
{
static const CharDriver gd_vc_driver = {
.instance_size = sizeof(VCDriverState),
.kind = CHARDEV_BACKEND_KIND_VC,
.chr_write = gd_vc_chr_write,
.chr_set_echo = gd_vc_chr_set_echo,
@ -1722,9 +1735,6 @@ static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp)
return NULL;
}
/* Temporary, until gd_vc_vte_init runs. */
chr->opaque = g_new0(VirtualConsole, 1);
vcs[nb_vcs++] = chr;
return chr;
@ -1765,14 +1775,12 @@ static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
GtkWidget *box;
GtkWidget *scrollbar;
GtkAdjustment *vadjustment;
VirtualConsole *tmp_vc = chr->opaque;
VCDriverState *vcd = (VCDriverState *)chr;
vc->s = s;
vc->vte.echo = tmp_vc->vte.echo;
vc->vte.echo = vcd->echo;
vc->vte.chr = chr;
chr->opaque = vc;
g_free(tmp_vc);
vcd->console = vc;
snprintf(buffer, sizeof(buffer), "vc%d", idx);
vc->label = g_strdup_printf("%s", vc->vte.chr->label