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

Reply via email to