On Mon, Oct 14, 2024 at 5:58 PM Roman Penyaev <r.peni...@gmail.com> wrote:
> On Mon, Oct 14, 2024 at 3:20 PM Marc-André Lureau > <marcandre.lur...@gmail.com> wrote: > > > > > > > > On Mon, Oct 14, 2024 at 3:45 PM Roman Penyaev <r.peni...@gmail.com> > wrote: > >> > >> Frontends can be attached and detached during run-time (although detach > >> is not implemented, but will follow). Counter variable of muxes is not > >> enough for proper attach/detach management, so this patch implements > >> bitset: if bit is set for the `mux_bitset` variable, then frontend > >> device can be found in the `backend` array (yes, huge confusion with > >> backend and frontends names). > >> > >> Signed-off-by: Roman Penyaev <r.peni...@gmail.com> > >> Cc: "Marc-André Lureau" <marcandre.lur...@redhat.com> > >> Cc: qemu-devel@nongnu.org > >> --- > >> chardev/char-mux.c | 41 +++++++++++++++++++++++++------------- > >> chardev/char.c | 2 +- > >> chardev/chardev-internal.h | 2 +- > >> 3 files changed, 29 insertions(+), 16 deletions(-) > >> > >> diff --git a/chardev/char-mux.c b/chardev/char-mux.c > >> index 9294f955462e..9c3cacb2fecd 100644 > >> --- a/chardev/char-mux.c > >> +++ b/chardev/char-mux.c > >> @@ -26,6 +26,7 @@ > >> #include "qapi/error.h" > >> #include "qemu/module.h" > >> #include "qemu/option.h" > >> +#include "qemu/bitops.h" > >> #include "chardev/char.h" > >> #include "sysemu/block-backend.h" > >> #include "qapi/qapi-commands-control.h" > >> @@ -168,12 +169,19 @@ static int mux_proc_byte(Chardev *chr, MuxChardev > *d, int ch) > >> case 'b': > >> qemu_chr_be_event(chr, CHR_EVENT_BREAK); > >> break; > >> - case 'c': > >> - assert(d->mux_cnt > 0); /* handler registered with first > fe */ > >> + case 'c': { > >> + unsigned int bit; > >> + > >> + /* Handler registered with first fe */ > >> + assert(d->mux_bitset != 0); > >> /* Switch to the next registered device */ > >> - mux_set_focus(chr, (d->focus + 1) % d->mux_cnt); > >> + bit = find_next_bit(&d->mux_bitset, MAX_MUX, d->focus + 1); > >> + if (bit >= MAX_MUX) { > >> + bit = find_next_bit(&d->mux_bitset, MAX_MUX, 0); > >> + } > >> + mux_set_focus(chr, bit); > >> break; > >> - case 't': > >> + } case 't': > >> d->timestamps = !d->timestamps; > >> d->timestamps_start = -1; > >> d->linestart = false; > >> @@ -243,15 +250,16 @@ static void mux_chr_read(void *opaque, const > uint8_t *buf, int size) > >> void mux_chr_send_all_event(Chardev *chr, QEMUChrEvent event) > >> { > >> MuxChardev *d = MUX_CHARDEV(chr); > >> - unsigned int i; > >> + int bit; > >> > >> if (!muxes_opened) { > >> return; > >> } > >> > >> /* Send the event to all registered listeners */ > >> - for (i = 0; i < d->mux_cnt; i++) { > >> - mux_chr_send_event(d, i, event); > >> + bit = -1; > >> + while ((bit = find_next_bit(&d->mux_bitset, MAX_MUX, bit + 1)) < > MAX_MUX) { > >> + mux_chr_send_event(d, bit, event); > >> } > >> } > >> > >> @@ -276,10 +284,11 @@ static GSource *mux_chr_add_watch(Chardev *s, > GIOCondition cond) > >> static void char_mux_finalize(Object *obj) > >> { > >> MuxChardev *d = MUX_CHARDEV(obj); > >> - unsigned int i; > >> + int bit; > >> > >> - for (i = 0; i < d->mux_cnt; i++) { > >> - CharBackend *be = d->backends[i]; > >> + bit = -1; > >> + while ((bit = find_next_bit(&d->mux_bitset, MAX_MUX, bit + 1)) < > MAX_MUX) { > >> + CharBackend *be = d->backends[bit]; > >> if (be) { > >> be->chr = NULL; > >> } > >> @@ -304,7 +313,10 @@ static void mux_chr_update_read_handlers(Chardev > *chr) > >> bool mux_chr_attach_frontend(MuxChardev *d, CharBackend *b, > >> unsigned int *tag, Error **errp) > >> { > >> - if (d->mux_cnt >= MAX_MUX) { > >> + unsigned int bit; > >> + > >> + bit = find_next_zero_bit(&d->mux_bitset, MAX_MUX, 0); > >> + if (bit >= MAX_MUX) { > >> error_setg(errp, > >> "too many uses of multiplexed chardev '%s'" > >> " (maximum is " stringify(MAX_MUX) ")", > >> @@ -312,8 +324,9 @@ bool mux_chr_attach_frontend(MuxChardev *d, > CharBackend *b, > >> return false; > >> } > >> > >> - d->backends[d->mux_cnt] = b; > >> - *tag = d->mux_cnt++; > >> + d->mux_bitset |= (1 << bit); > >> + d->backends[bit] = b; > >> + *tag = bit; > >> > >> return true; > >> } > >> @@ -322,7 +335,7 @@ void mux_set_focus(Chardev *chr, unsigned int focus) > >> { > >> MuxChardev *d = MUX_CHARDEV(chr); > >> > >> - assert(focus < d->mux_cnt); > >> + assert(find_next_bit(&d->mux_bitset, MAX_MUX, focus) < MAX_MUX); > > > > > > Wouldn't this be more correct? > > > > + assert(find_next_bit(&d->mux_bitset, MAX_MUX, focus) == focus); > > > > Yes, makes sense. Thanks. > > Do you want the whole patchset to be resend, > or only changed patches with "v2" prefix in subject? > Yes, please send a v2 with the change and r-b. For the other series, use Based-on tag as necessary ( https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg01288.html) thanks -- Marc-André Lureau