From nobody Mon Feb 9 09:08:44 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=crudebyte.com ARC-Seal: i=1; a=rsa-sha256; t=1629580390; cv=none; d=zohomail.com; s=zohoarc; b=Bq9nOorTkT/PEXGaoDC7af/CN78VSu76AmpL9kd+//vLBiF6VbQmSh0bcJeXoOlkokHE47O5lT/9vSxuPLC5Uevd1+qFk3fxxX63Cy3acfFuy16H6Oow6RXIi3OMoLlO06WzQZyge6eWeOfuCQybkCAiD8qO/SF4BcFOSDKZwl4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629580390; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=Ihfx/i5DNU+G4x66QNtBztFtNjftz3znLfp5inBsl2c=; b=Ha2XeJP8s6qViUdEeWZiqJPt1KtOzPFoIcjc9zEpwm9GJsqSL1aCHb/o/X6ZK1/vGUnOK498fvxhT1aX0Y7TIZXX+B8Yl/0Mv3Rh50NE6r3G+oYH5QCLHTiUZzP2Jwo5GYVwqmKtNzo38IEJvFMS+K27YYFSfvWhO/RGDTU9H1M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1629580390264297.74252552940186; Sat, 21 Aug 2021 14:13:10 -0700 (PDT) Received: from localhost ([::1]:58552 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mHYIf-0002AI-7g for importer@patchew.org; Sat, 21 Aug 2021 17:13:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57432) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mHYHG-00007H-Eh for qemu-devel@nongnu.org; Sat, 21 Aug 2021 17:11:42 -0400 Received: from lizzy.crudebyte.com ([91.194.90.13]:43873) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mHYHC-0001WJ-6e for qemu-devel@nongnu.org; Sat, 21 Aug 2021 17:11:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=lizzy; h=Cc:To:Subject:Date:From:References:In-Reply-To: Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Content-ID: Content-Description; bh=Ihfx/i5DNU+G4x66QNtBztFtNjftz3znLfp5inBsl2c=; b=XH5Oz LhB+4tiX0w5g+MfP7h1502rt6GzM1ecxyGrj3tpwIHxLt0UYF2kw17qEfUWqH/phA+nzNFQljROa6 KD8/I54KKd08lUaxXIBEFbhCuOMtFkWZoUY5VgWrT1tt8S7OCDxdqnkLOnX4UbBsRTAetdb8bWlEH M5O/Efh2+zCr9oPmo+IJqgFlCOXDwRpMpS+LP1tqZUNE5B9iLDtPen4Wbdc1uVd7oWgeJ4J9x9VLt yUdfzd/wWr9L4z2E3q5RK896a9PWhNQ5icSQoOEguWJJbq0it0sjZMUb9pK9t4oKak5BUltmVuSyT /cnEfUSLRfU68vpBuhkIXyXbFLQqQ==; Message-Id: In-Reply-To: References: From: Christian Schoenebeck Date: Sat, 21 Aug 2021 22:18:18 +0200 Subject: [PATCH 1/5] qemu/qarray.h: introduce QArray To: qemu-devel@nongnu.org Cc: Greg Kurz Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=91.194.90.13; envelope-from=a1925f3bb2560f2f19558dbc6d4309d3bb17529d@lizzy.crudebyte.com; helo=lizzy.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @crudebyte.com) X-ZM-MESSAGEID: 1629581295156100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Implements deep auto free of arrays while retaining common C-style squared bracket access. Signed-off-by: Christian Schoenebeck --- include/qemu/qarray.h | 148 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 include/qemu/qarray.h diff --git a/include/qemu/qarray.h b/include/qemu/qarray.h new file mode 100644 index 0000000000..230a556e81 --- /dev/null +++ b/include/qemu/qarray.h @@ -0,0 +1,148 @@ +/* + * QArray - deep auto free C-array + * + * Copyright (c) 2021 Crudebyte + * + * Authors: + * Christian Schoenebeck + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ +#ifndef QEMU_QARRAY_H +#define QEMU_QARRAY_H + +/** + * QArray provides a mechanism to access arrays in common C-style (e.g. by + * square bracket [] operator) in conjunction with reference variables that + * perform deep auto free of the array when leaving the scope of the auto + * reference variable. That means not only is the array itself automatical= ly + * freed, but also memory dynamically allocated by the individual array + * elements. + * + * Example: + * + * Consider the following user struct @c Foo which shall be used as scalar + * (element) type of an array: + * @code + * typedef struct Foo { + * int i; + * char *s; + * } Foo; + * @endcode + * and assume it has the following function to free memory allocated by @c= Foo + * instances: + * @code + * void free_foo(Foo *foo) { + * free(foo->s); + * } + * @endcode + * Add the following to a shared header file: + * @code + * DECLARE_QARRAY_TYPE(Foo); + * @endcode + * and the following to a C unit file: + * @code + * DEFINE_QARRAY_TYPE(Foo, free_foo); + * @endcode + * Finally the array may then be used like this: + * @code + * void doSomething(int n) { + * QArrayRef(Foo) foos =3D NULL; + * QARRAY_CREATE(Foo, foos, n); + * for (size_t i =3D 0; i < n; ++i) { + * foos[i].i =3D i; + * foos[i].s =3D calloc(4096, 1); + * snprintf(foos[i].s, 4096, "foo %d", i); + * } + * } + * @endcode + */ + +/** + * Declares an array for the passed @a scalar_type. + * + * This is typically used from a shared header file. + * + * @param scalar_type - type of the individual array elements + */ +#define DECLARE_QARRAY_TYPE(scalar_type) \ + typedef struct QArray##scalar_type { \ + size_t len; \ + scalar_type first[]; \ + } QArray##scalar_type; \ + \ + void qarray_create_##scalar_type(scalar_type **auto_var, size_t len); \ + void qarray_auto_free_##scalar_type(scalar_type **auto_var); \ + +/** + * Defines an array for the passed @a scalar_type and appropriate + * @a scalar_cleanup_func. + * + * @param scalar_type - type of the individual array elements + * @param scalar_cleanup_func - appropriate function to free memory dynami= cally + * allocated by individual array elements bef= ore + */ +#define DEFINE_QARRAY_TYPE(scalar_type, scalar_cleanup_func) \ + void qarray_create_##scalar_type(scalar_type **auto_var, size_t len) \ + { \ + qarray_auto_free_##scalar_type(auto_var); \ + QArray##scalar_type *arr =3D g_malloc0(sizeof(QArray##scalar_type)= + \ + len * sizeof(scalar_type)); \ + arr->len =3D len; \ + *auto_var =3D &arr->first[0]; \ + } \ + \ + void qarray_auto_free_##scalar_type(scalar_type **auto_var) \ + { \ + scalar_type *first =3D (*auto_var); \ + if (!first) { \ + return; \ + } \ + QArray##scalar_type *arr =3D (QArray##scalar_type *) ( \ + ((char *)first) - offsetof(QArray##scalar_type, first) \ + ); \ + for (size_t i =3D 0; i < arr->len; ++i) { \ + scalar_cleanup_func(&arr->first[i]); \ + } \ + g_free(arr); \ + } \ + +/** + * Used to declare a reference variable (unique pointer) for an array. Aft= er + * leaving the scope of the reference variable, the associated array is + * automatically freed. + * + * @param scalar_type - type of the individual array elements + */ +#define QArrayRef(scalar_type) \ + __attribute((__cleanup__(qarray_auto_free_##scalar_type))) scalar_type* + +/** + * Allocates a new array of passed @a scalar_type with @a len number of ar= ray + * elements and assigns the created array to the reference variable + * @a auto_var. + * + * @param scalar_type - type of the individual array elements + * @param auto_var - destination reference variable + * @param len - amount of array elements to be allocated immediately + */ +#define QARRAY_CREATE(scalar_type, auto_var, len) \ + qarray_create_##scalar_type((&auto_var), len) + +#endif /* QEMU_QARRAY_H */ --=20 2.20.1