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?

--
Roman

Reply via email to