All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: marc.mari.barcelo@gmail.com, pbonzini@redhat.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 3/4] libqos: add a simple first-fit memory allocator
Date: Thu, 31 Jul 2014 17:14:12 -0400	[thread overview]
Message-ID: <53DAB1A4.7030900@redhat.com> (raw)
In-Reply-To: <20140731101351.GD25929@stefanha-thinkpad.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 3803 bytes --]


On 07/31/2014 06:13 AM, Stefan Hajnoczi wrote:
> On Wed, Jul 30, 2014 at 06:28:28PM -0400, John Snow wrote:
>> +#define bitany(X, MASK) ((X) & (MASK))
>> +#define bitset(X, MASK) (bitany((X), (MASK)) == (MASK))
> This is subjective but macros like this should be avoided.  This macro does not
> encapsulate anything substantial.  It forces the reader to jump to the
> definition of this macro to understand the code, making code harder to read.
>
> IMO a cleaner solution is to drop the macros:
>
>    PCAllocOpts mask = PC_ALLOC_PARANOID | PC_ALLOC_LEAK_ASSERT;
>    if (s->opts & mask == mask) {                                 (1)
>        if ((node->addr != s->start) ||
>            (node->size != s->end - s->start)) {
>            fprintf(stderr, "Free list is corrupted.\n");
>            if (s->opts & PC_ALLOC_LEAK_ASSERT) {                 (2)
>                g_assert_not_reached();
>            }
>        }
>    }
>
> Now that I read the expanded code, a bug becomes exposed:
>
> In (1) we check that PC_ALLOC_PARANOID and PC_ALLOC_LEAK_ASSERT are both set.
> Then in (2) we check whether PC_ALLOC_LEAK_ASSERT is set.  But we already knew
> that PC_ALLOC_LEAK_ASSERT must be set in (1), so I guess the logic should have
> really been:
>
>    if (s->opts & (PC_ALLOC_PARANOID | PC_ALLOC_LEAK_ASSERT)) {
>        if ((node->addr != s->start) ||
>            (node->size != s->end - s->start)) {
>            fprintf(stderr, "Free list is corrupted.\n");
>            if (s->opts & PC_ALLOC_LEAK_ASSERT) {
>                g_assert_not_reached();
>            }
>        }
>    }
>
>> +#define MLIST_ENTNAME entries
>> +#define MLIST_FOREACH(node, head) QTAILQ_FOREACH((node), (head), MLIST_ENTNAME)
>> +#define MLIST_PREV(node) QTAILQ_PREV((node), MemList, MLIST_ENTNAME);
>> +#define MLIST_NEXT(node) QTAILQ_NEXT((node), MLIST_ENTNAME);
> For the same reasons as my previous comment, please don't hide straightforward
> expressions behind a macro.
>
>> +typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
>> +typedef struct MemBlock {
>> +    QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
>> +    uint64_t size;
>> +    uint64_t addr;
>> +} MemBlock;
>>   
>>   typedef struct PCAlloc
>>   {
>>       QGuestAllocator alloc;
>> -
>> +    PCAllocOpts opts;
>>       uint64_t start;
>>       uint64_t end;
>> +
>> +    MemList used;
>> +    MemList free;
>>   } PCAlloc;
>>   
>> -static uint64_t pc_alloc(QGuestAllocator *allocator, size_t size)
>> +static inline void mlist_insert(MemList *head, MemBlock *insr)
>>   {
>> -    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
>> -    uint64_t addr;
>> +    QTAILQ_INSERT_HEAD(head, insr, MLIST_ENTNAME);
>> +}
>> +
>> +static inline void mlist_append(MemList *head, MemBlock *node)
>> +{
>> +    QTAILQ_INSERT_TAIL(head, node, MLIST_ENTNAME);
>> +}
>> +
>> +static inline void mlist_unlink(MemList *head, MemBlock *rem)
>> +{
>> +    QTAILQ_REMOVE(head, rem, MLIST_ENTNAME);
>> +}
> For the same reasons as my comments about the macros, these trivial functions
> are boilerplate.  Why not use the QTAILQ macros directly?
For /at least/ the append and insert cases, I desired call-by-value 
semantics.
As a matter of taste, I find macros annoying for the reason that you 
cannot inline things such as:
mlist_insert(list, mlist_new(...));

but unlink is certainly superfluous, and just something I did for some 
consistency.

If there is a matter of style where in-line function call is to be 
avoided entirely, I'll just nix all of these trivial inlines.
>
> (It would be good to hide the list implementation if this was an external API
> and you want to avoid exposing the implementation details, but within this
> source file there is no point in extra layers of indirection.)
Force of habit, but you're right. I'm not exporting the interface.

[-- Attachment #2: Type: text/html, Size: 4558 bytes --]

  reply	other threads:[~2014-07-31 21:14 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-30 22:28 [Qemu-devel] [PATCH v2 0/4] libqos: add a simple first-fit memory allocator John Snow
2014-07-30 22:28 ` [Qemu-devel] [PATCH 1/4] libqos: Correct mask to align size to PAGE_SIZE in malloc-pc John Snow
2014-07-30 22:28 ` [Qemu-devel] [PATCH 2/4] libqos: Change free function called in malloc John Snow
2014-07-30 22:28 ` [Qemu-devel] [PATCH 3/4] libqos: add a simple first-fit memory allocator John Snow
2014-07-31 10:13   ` Stefan Hajnoczi
2014-07-31 21:14     ` John Snow [this message]
2014-08-01 15:08       ` Stefan Hajnoczi
2014-08-04  8:22         ` Markus Armbruster
2014-07-30 22:28 ` [Qemu-devel] [PATCH 4/4] qtest/ide: Uninitialize PC allocator John Snow
2014-07-31 10:14 ` [Qemu-devel] [PATCH v2 0/4] libqos: add a simple first-fit memory allocator Stefan Hajnoczi
  -- strict thread matches above, loose matches on Subject: below --
2014-07-29 21:54 [Qemu-devel] [PATCH " John Snow
2014-07-29 21:54 ` [Qemu-devel] [PATCH 3/4] " John Snow
2014-07-30 15:24   ` Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53DAB1A4.7030900@redhat.com \
    --to=jsnow@redhat.com \
    --cc=marc.mari.barcelo@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.