From nobody Fri May 9 07:06:36 2025 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2071.outbound.protection.outlook.com [40.107.94.71]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D66D79CF; Sun, 6 Apr 2025 13:02:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.94.71 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743944530; cv=fail; b=VdKbA3yN/cY2OTzTWUyM8tSGBSxMXI+yIllqJc3t/jY8lW7/JdoMyIzoaVK2neBiDf2gyjac+Y+0wo3NWANdW2pHGoFvHsRoigM8rAdDy1ACluSfzHV6hCXfUc23hoUbT5FyBK9ksqEhKm9r2bwI8PI3yfvIfUD49JtgRMAHf+c= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743944530; c=relaxed/simple; bh=ZBjVutlg8NztvQwoYYuXzReP4+NkTLFWM99bT1MI0Y8=; h=From:Date:Subject:Content-Type:Message-Id:To:Cc:MIME-Version; b=h+6mnLWzqHf4hWKLerFXfvruZ1Kp+p7sHP7RDwB5eYmRmOmzFAr9VDRnxWJmS9W6KMQaQ9Bw2MtSa0Tj+sF+M4wpv6Z1ePy0/qPzIJ+v16HXszU2jchjN++JOiECCWzIRhbzMoFQ0xU0EqKLzC5z58QFuBpK8S/Yy9eYPM4nRw8= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=RcyMZYDj; arc=fail smtp.client-ip=40.107.94.71 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="RcyMZYDj" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=TZTR4QvtybiO/r2kKShy3z3G8eanKWvdKFKnNOV4K1uB7o8vCOtp+oxaQYSojcLCH6ei0ZZX9kYjMFUEsCeTGAXIyKZOo86+SvtvPX3LiOxfpt3sI+ZfAi0F3yt4zeHtJvLJA9gwUR9ej5uSl/EIHeZ8vEv5ERNpk9qgPnNAPD7DpSsdhCLUMNjP6To7f52M0KAEVevPmVtpD7a00Pjq4kWbUbzXbLMQzTzEnbgXobN6kYOr7Wc3ywELuf2gz7ETsRNigsaQKDb5d2YIhWIU673COlQtcWiGhBYP5HBhp6Q4QIMlmDxWfBHqKHyjmrDKSp9O4VeLqwxDVZqFAmOIEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=5uHNQ7+7NbAzT8RsOF8E/1GUB0tOA99CNGBtmmgE+W8=; b=V2WiUwZzp64550S4z6+oU6PwIIFJ17Oq6gaT81te7fMUoA5Ep84lIuj/NkyxSAGkc8mCQMF/ILkJFBZvpWJkJSkkJdEeAv2XEpNg245iKSMSXEyTOwYamVcoyiF1nARF5QqtFCGR3buS39WbDhhCoA0Xybr0XdT2bJSEozxjqxAMy9G3lzvVvWeqeHMmfUnHVAxyBEqtju6j7E4wiHth6f8urUmbHHiaFzvcICEdkadkM3oMRsFU7y9b7dwJbwskyO7jYy3LQDN16O3m7SMkAnZFApr0c4UDbLsOb02lTVKyOVHN3hnlGArHAjquCf7KCWtJ0koKg8XE9oSpj6jz9A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=5uHNQ7+7NbAzT8RsOF8E/1GUB0tOA99CNGBtmmgE+W8=; b=RcyMZYDjUdNx1SxIrP7QvyQXIp87gapM1lQIKgK4R+pxEyQvYE4SP1ZMG6YOvFiyrU1IXJIhUBN/dzj1vzscHoDPxrvT4g3UGST2Fm8IItHT3q/g/k/12E35oF7A0AN5lPlv1SSzaY0o20oQkCbVdyfFRY7cqF3pWA889NGRFlnY4epJSxTFZWmmeXQmW4ktyEp2dTY/iHTECl8/kPxPR8hqyJjhHREQtd+C1n4YGd7OpIiv44+P2+gsbVYhfL1Lbm1bssuZQu4GouXQykbZ2HMDAnawMP7GlvGLPzi+yB7sbuSMR6sy7XvEp3VBwRBYEXjP2bzB2RHP3WMwGGgiJA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from CH2PR12MB3990.namprd12.prod.outlook.com (2603:10b6:610:28::18) by IA0PR12MB8087.namprd12.prod.outlook.com (2603:10b6:208:401::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8606.33; Sun, 6 Apr 2025 13:02:05 +0000 Received: from CH2PR12MB3990.namprd12.prod.outlook.com ([fe80::6e37:569f:82ee:3f99]) by CH2PR12MB3990.namprd12.prod.outlook.com ([fe80::6e37:569f:82ee:3f99%6]) with mapi id 15.20.8606.029; Sun, 6 Apr 2025 13:02:05 +0000 From: Alexandre Courbot <acourbot@nvidia.com> Date: Sun, 06 Apr 2025 22:01:55 +0900 Subject: [PATCH v3] rust: alloc: implement `extend` for `Vec` Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250406-vec_extend-v3-1-ec5c5c0acf2a@nvidia.com> X-B4-Tracking: v=1; b=H4sIAEJ78mcC/3WNywrCMBBFf6XM2kjzourK/xCRPEY7C1NNaqiU/ rtpXYigy3PhnDtCwkiYYFeNEDFToi4UkKsKXGvCBRn5wiBqoWtVa5bRnXDoMXimpOBCc+Oc4FC EW8QzDUvscHxzxPujNPvP2FLqu/hcDjOf15/tzBln1jaeb61qjHf7kMmTWbvuCnMni/+uKC4qs 9HmrKSz8sudpukFccb1GfYAAAA= X-Change-ID: 20250405-vec_extend-4321251acc21 To: Danilo Krummrich <dakr@kernel.org>, Miguel Ojeda <ojeda@kernel.org>, Alex Gaynor <alex.gaynor@gmail.com>, Boqun Feng <boqun.feng@gmail.com>, Gary Guo <gary@garyguo.net>, =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= <bjorn3_gh@protonmail.com>, Benno Lossin <benno.lossin@proton.me>, Andreas Hindborg <a.hindborg@kernel.org>, Alice Ryhl <aliceryhl@google.com>, Trevor Gross <tmgross@umich.edu> Cc: Joel Fernandes <joelagnelf@nvidia.com>, John Hubbard <jhubbard@nvidia.com>, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Alexandre Courbot <acourbot@nvidia.com> X-Mailer: b4 0.14.2 X-ClientProxiedBy: TYCP301CA0053.JPNP301.PROD.OUTLOOK.COM (2603:1096:400:384::20) To CH2PR12MB3990.namprd12.prod.outlook.com (2603:10b6:610:28::18) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CH2PR12MB3990:EE_|IA0PR12MB8087:EE_ X-MS-Office365-Filtering-Correlation-Id: ca9e2adf-7431-46bd-646f-08dd750b3b38 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|366016|10070799003|1800799024|921020; X-Microsoft-Antispam-Message-Info: =?utf-8?B?MDFEMEZXUVZ0Mk5BKzZtaFozUVFiZTdZcEgzWmU2NEtpVlF4eFd1eU5VazVz?= =?utf-8?B?dVMzU09acnc5UUdneGErbXlVakU0N1VtQlNrUEx4QkxicEwyM1l4Uml4SE0v?= =?utf-8?B?UlV2RjJNR3dybHkwMFNpb3lGdUpJZHorZVoxSTVnOTNNc0piYWRkUktiSVdh?= =?utf-8?B?dHljd1daNlZad2ZWT3NiMzNRNTZneHNmQWp4ZEF3MUt6N2h1bnlkcDV1aTgw?= =?utf-8?B?UmtsdjVOYmZFK3RKN1NqWHZxc25kcWtjZlhUcXhDZjRaa3ZmanJiR0U3NVRC?= =?utf-8?B?b1dqcVRvckdHNk5pdEV6Y3Jmb01QaEM0eVg5NWN0OXo4ME5aRkErb0xXRU5P?= =?utf-8?B?d3RCbFdxdHUvelNhNCswZ2tKbWRsSFdqNSswSmRMbXd4MFVUbWtEdzc4b2Fi?= =?utf-8?B?c1BkbDlnMVRxY0xxL1N2b2NpWDVKYldXV0R3VFNQdStZclg2R1BxSlNCaUVh?= =?utf-8?B?Y0JqU3VIK2ZtQmp4THY4VnNmVDlsK21JaS9CN3NwUnZncTI3OW04NmE1Q0s3?= =?utf-8?B?YWEzTzZJek5XUGMyZW1jZDkxSThicCt6N0R1Wml5cGh6eS80UDhwLzh4eDU0?= =?utf-8?B?TjhtV01rU3ZONjFpNnVVODJpdEN2RTFKeC8rVlpraG5mRzcxa1RUL09Sak5H?= =?utf-8?B?OCtQUnVxbVlBcFNza3FrWTRKVjRnNU12aWwvRVYrUXBlUU53MHozT1JBbkcv?= =?utf-8?B?Nzk2N3NDcXUxNTJZbkFxWitVWmx0TTJmMzc2ejN5MHRUTC9jVjMrNFpJOFd4?= =?utf-8?B?RHFOa011WEUrd2JUdnR5VWFnNVRva0U2VytCMndLbGFRc2I1YXBENWxCQ2Ft?= =?utf-8?B?V2QvWjZ6ckFBM2NCTFVrQUt4c3IyZGJzamtDT3hVZzVLNENzTnJuSlkyT1Vq?= =?utf-8?B?cW9oNy9rOW9xeGR2KzJTOXJpSVA5b0hYbDlVUUErVDNTU1dhdUx6b2RmS3M4?= =?utf-8?B?WGo0OVV6L096OHJyaXVHNDlHYVRUNFhIL2hsWTN1aEFRaW1NKzZVRk5JR0ZW?= =?utf-8?B?QzNlMXhlQXNaVnpMRDRmVDhJZmpGQTZMZWFlVzdoeE9ITzJ1NGtOckJTdE9O?= =?utf-8?B?VlVHZjdBMFZmd0ZHVjZXWVQvN2xFcUpoUDNCbXM1bEhUdEdMWUxvVjdXZUFz?= =?utf-8?B?NkxramdxbDlrRGJoUFhkWThRZW4zcTNjdDB4ZmhuWGp5VzZNM2UyK3Q1VGRz?= =?utf-8?B?eGtkOWZ1eUY0RFQ4TkpsbFN0QlVmUE8yYUxZdVhXclcyYU1pVWZKcmkyMEJl?= =?utf-8?B?OWk2alZ4YVB3b05hVHRwQ1VaMElOYTBOSzNGd1NuV28yTmwybnltYjZFaE52?= =?utf-8?B?UlppeG04RzIxVjVESzZobFYwMk5qd2xwdHhaT0ExaERmdXFNVUMvQkMrRjNo?= =?utf-8?B?aDVoVEZkeVRoS3NXTkFGeFJqOWE0YXJCbmh0aXU1RXRjRG9BVGdXclVtTHYw?= =?utf-8?B?WmRkMkxXYmRncWJmM1pxS1pBU29qZlVuYjFzc2tBQ0t0L2lZaCt3aXZwM2Fp?= =?utf-8?B?bFdNRUVzTVp2dURPRVY3NGgxN3R4VHBwcjUyc0RIbU1UNm02bXNBNU5sbXY2?= =?utf-8?B?OVVONGFWZ0c5bmh0TXZCRnRKYjd4QWIvc25JVGx0a1ZudmgzNUM5T3M2Nndj?= =?utf-8?B?aEZDVVpzbGZEdnNFTTJuZGE4SklTYURNR0JBVURxV3Z0WjNXb1RWakdLamtQ?= =?utf-8?B?UTVYU2d4Z29yWDgwQ1MrKzY0dVBLRGMzenlLZzRjT29DbkJiclpsTjJ0VGFS?= =?utf-8?B?ZFd5Nk5ZZE9sYzFNVTYrNGlrYmZmSGUyaWFNOUJsd3BQblFwTitKQVRIaExk?= =?utf-8?B?SVJlNndQWTBGM2FzL1JjQ3p0VzFiQW1yWFVUVkpaek8ybG1QWUNXTnUzd1Ex?= =?utf-8?B?KzN2UEk0cjFkbnU2ek5jRXA5V1RsUjF0NXVvUHhyUHY0bHB1azlLSFpWcHll?= =?utf-8?Q?QU++W6JkfUw=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CH2PR12MB3990.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(7416014)(376014)(366016)(10070799003)(1800799024)(921020);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?aVFNd0RJZHhpN2hkblk1RUt1eTc4YjZ6cUg5ZlZNMG9RVUpwSGUrQm9YVkMx?= =?utf-8?B?SVBOdmVjbDlPeVZTRVZnVTdVM3FPMEpuUGZXZ2FncDcyVEZLUlEwRW0vYTlz?= =?utf-8?B?YVdrbnR6OGViMUFaOVA0VXpUUkxPRXJYUnU3aWF6ME5INTF5aEppdnl1TlFT?= =?utf-8?B?MzVraEh3THo2UlFKVHE3YWFuWGpoNERXd3FFVXpwVEdkbXREcVBpWWRHZ3N6?= =?utf-8?B?eWZoNzVWVXQvMGEzQXo1azBoRUVmclFHVGhVY1RJYllkNy9wMkNrTTVOZmtM?= =?utf-8?B?ZXNnejNFKythdjIyUUJJNkE0ck5UMkZQajNKL25CUXNYSTJGY0N0NEdqYXM3?= =?utf-8?B?M2R1Ni9TRENNTGozellGYjFuMmEvdGU5RXZZVGFobTh5a0RmNUFMdEJKL09i?= =?utf-8?B?QnRYZ1JiZXY0eW11U29nYlR4YjR3RFBHM1IwSzUra1FycHJNOThCbVJkWjdR?= =?utf-8?B?MEZvMktqSjVKcDdWaVpWc25mVUszQVZVbWRrSmNyNHZGV1BlOEhtcGY1Uzd4?= =?utf-8?B?bnFZd3lXUkd6amdFdlJqY3ZpMWlYWCtiTmJWUWc0YytTNFlDS1RSUENQVVMy?= =?utf-8?B?YzhtY3pUek9DdTVKYWVCUkhLd20yWnlmNkhDS2JjQmo4cWZQWGpza3lZWisz?= =?utf-8?B?dmI5SGlKQjNZSjB5ZTZVck1YSVBZVm5ub2pDRjlQc1J0NndyUzZtN0Q5bFJs?= =?utf-8?B?OEFvanU5Z1pvVWxPUGl4TXhkd01QSVU1dUVXbk8zNTEwMFN0bHRzYXVoM0Rk?= =?utf-8?B?ZDZwKzE1ZlRjSWJlUGRvNVBsT29BZFZ2WlkzNVhLek5sakUwSVFQM3F0YThz?= =?utf-8?B?c05ZQkY0S0tHdzFmZ2huN0dUQk1TclBnaDQzdTlQRlhRM084SE5FUkd5SDBl?= =?utf-8?B?N2VHRmQxd3ZjdmtVZm5jR1NuTHZPZWl1TnRiQ1h5K3pwVTd2Z2t1U2NXank4?= =?utf-8?B?Y29BTHJCSkdEcU5IbmNXUUVjVlJraUZLZXpuRDBkSnBEemF0VzNzMjBvVWlE?= =?utf-8?B?NWsvNlYrZ3VFNlFlTlcyMS9IS2pIWDhtbGNLSEFGSHpqcGVhYUt3ZFlQcm9k?= =?utf-8?B?Z1hxbHlaSUUzbS9IcWNhZEhvYnJIQWVkSU4vS3J2RXU0Y3NCQlBYWEhudExN?= =?utf-8?B?aXh3OW9NT2hacEhaMzFidmVHVFhnVzJoWVBvWWZPMnNEQmYxdjBRQnlBVFda?= =?utf-8?B?a0p6S0xVbWV6dzhZWVUzc0hSL0dnaSs5NUtEeDFGUkczOHhUaHVGVFJGNXMv?= =?utf-8?B?ekowYjEvb3Y3VE9BbjI5WnI3SkFDeEk4RFY5L1daUEh5S0ZWTzE2aEQycHVy?= =?utf-8?B?NVg4ejJXL1R1SCtGc2NIRmFTbUl0eE5FRTVOY3FwNnBuTWZaMDBuMEYrdFFG?= =?utf-8?B?UTFVRjh4aGc0Q3hvdWNOT1dBL3ZxdWhESlZjMFFlTE9ROGlCY0lrTzlxbUM5?= =?utf-8?B?NkNYaTFETEd2U3h2aVpTUWN3YldtdTJteXkyTXVFUUp6N0Q3a1A1Z0ZBVVND?= =?utf-8?B?MXl1bURTd1IyZy9KKzNLSk9JZVRMWTJ5dEM1Zk1HbWV3dFR4UGFvZEhrZ2Zo?= =?utf-8?B?MDBCcUV6dnRiMGFKaFRaMXNaTjV2bmp0RUtzdXNmRndqMzgzZmhMTmZHc091?= =?utf-8?B?VzcrcGdIN2VLQ0hyRUptanF1U29KbFhlbmpaTW5EN2xQZ2NzcjhhUEVUYnYv?= =?utf-8?B?d1JJRXhiWE9qUUltZytwYUoxV1FhaDhKeGtORTY1RkZkVEZ2UWNQajV5bE9K?= =?utf-8?B?RHp1TGVOblF5NTNtYW9GS1krSXVyNnRCdzFSWURtTmFxMU5ZeERnS2hoRGEr?= =?utf-8?B?Z1hpejViRlJOU1BVMjMwcnBidkppQThJY21TUHJTTE1WSUVjTXlHNXFYUCtz?= =?utf-8?B?blh4KzNGcmRuUnVocjU4enhkYXFYUlVQbGgwSDFUVXFBcUJPaTdrblRVbm1G?= =?utf-8?B?dFdKVXBCRjZXRVpOM2lVSHpUcjdkMU1vZE1NK2hyb2lBY1hBdFQyQXpKOVc2?= =?utf-8?B?aU9WREViZ2RleFRyZk5XZGdXSGZoTkg2OGFFaURtWSs5dmd4NiswT3BhTWMr?= =?utf-8?B?QXZLVG1jUTNtMnhKdXBFUUFwMmlHbld0VFVxM2xrWkcxTU5nb2VrMFNzYkY5?= =?utf-8?B?MDZXQ2dCaFRpSDJCVjd4U0lhR3l2UEgxdnJhVVFORTFmSjRFTE9vdG91R2JT?= =?utf-8?Q?zOSgzPQwEhjcIXe8/LlmVdT/XaL611KO3flV8tEzj7+9?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: ca9e2adf-7431-46bd-646f-08dd750b3b38 X-MS-Exchange-CrossTenant-AuthSource: CH2PR12MB3990.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Apr 2025 13:02:05.6669 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2ihOJqbrOpM7OiTKjAY2ne0Yb2QuCQGH5Ahw13pZl9Z7aHqYBXU3+UeFZ7G40v54F4T6shLSfMhx1CFLZpmybA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA0PR12MB8087 KVec currently has `extend_with` and `extend_from_slice` methods, but no way extend a vector from a regular iterator as provided by the `Extend` trait. Due to the need to provide the GFP flags, `Extend` cannot be implemented directly, so simply define a homonymous method that takes an extra `flags` argument. The aforementioned `extend_with` and `extend_from_slice` can then be reimplemented as direct invocations of this new method - maybe they can eventually be removed. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> --- I was a bit surprised to find no equivalent of the `Extend` trait for KVec, and while I anticipate to be told the reason for this, I also didn't hit any hard wall trying to come with my own implementation so here it is. I expect the new `extend_with` and `extend_from_slice` to be optimized into something close to their previous implementations, but am not sure how I can simply verify that this is the case - any hint would be appreciated! --- Changes in v3: - Use repeat_n() instead of repeat() for extend_with() in order to avoid an extra clone of the value. - Be more precise about the cases where extend() will perform optimally or not in its documentation, and how the vector might be modified even in case of an error. - Replace into_iter() with iter() and iter_mut() where suggested by the kernel test robot. - Link to v2: https://lore.kernel.org/r/20250405-vec_extend-v2-1-e4a85af43c= b3@nvidia.com Changes in v2: - Changed the diff algorithm to histogram for a more readable patch. --- rust/kernel/alloc/kvec.rs | 111 ++++++++++++++++++++++++++++++++----------= ---- 1 file changed, 78 insertions(+), 33 deletions(-) diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index ae9d072741cedbb34bed0be0c20cc75472aa53be..b3c4227e232cca3b5c17930abc6= 3810240b9c4da 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -454,30 +454,86 @@ pub fn reserve(&mut self, additional: usize, flags: F= lags) -> Result<(), AllocEr } } =20 +impl<T, A: Allocator> Vec<T, A> { + /// Extends the vector by the elements of `iter`. + /// + /// This uses [`Iterator::size_hint`] to optimize memory reallocations= , but will work even with + /// imprecise implementations - albeit in a non-optimal way. + /// + /// This method returns an error if a memory reallocation required to = accommodate the new items + /// failed. In this case, callers must assume that some (but not all) = elements of `iter` might + /// have been added to the vector. + /// + /// # Note on optimal behavior and correctness + /// + /// The efficiency of this method depends on how reliable the [`Iterat= or::size_hint`] + /// implementation of the `iter` is. + /// + /// It performs optimally with at most a single memory reallocation if= the lower bound of + /// `size_hint` is the exact number of items actually yielded. + /// + /// If `size_hint` is more vague, there may be as many memory realloca= tions as necessary to + /// cover the whole iterator from the successive lower bounds returned= by `size_hint`. + /// + /// If `size_hint` signals more items than actually yielded by the ite= rator, some unused memory + /// might be reserved. + /// + /// Finally, whenever `size_hint` returns `(0, Some(0))`, the method a= ssumes that no more items + /// are yielded by the iterator and returns. This may result in some i= tems not being added if + /// there were still some remaining. + /// + /// In the kernel most iterators are expected to have a precise and co= rrect `size_hint` + /// implementation, so this should nicely optimize out for these cases. + pub fn extend<I>(&mut self, iter: I, flags: Flags) -> Result<(), Alloc= Error> + where + I: IntoIterator<Item =3D T>, + { + let mut iter =3D iter.into_iter(); + + loop { + let low_bound =3D match iter.size_hint() { + // No more items expected, we can return. + (0, Some(0)) =3D> break, + // Possibly more items but not certain, tentatively add on= e. + (0, _) =3D> 1, + // More items pending, reserve space for the lower bound. + (low_bound, _) =3D> low_bound, + }; + + self.reserve(low_bound, flags)?; + + // Number of items we actually added. + let added_items =3D self + .spare_capacity_mut() + .iter_mut() + // Take a mutable reference to the iterator so we can reus= e it in the next + // iteration of the loop if needed. + .zip(&mut iter) + .fold(0, |count, (dst, src)| { + dst.write(src); + + count + 1 + }); + + // SAFETY: + // - `self.len() + added_items <=3D self.capacity()` due to th= e call to `reserve` above, + // - items `[self.len()..self.len() + added_items - 1]` are in= itialized. + unsafe { self.set_len(self.len() + added_items) }; + + // `size_hint` was incorrect and our iterator ended before its= advertized lower bound. + if added_items < low_bound { + break; + } + } + + Ok(()) + } +} + impl<T: Clone, A: Allocator> Vec<T, A> { /// Extend the vector by `n` clones of `value`. pub fn extend_with(&mut self, n: usize, value: T, flags: Flags) -> Res= ult<(), AllocError> { - if n =3D=3D 0 { - return Ok(()); - } - - self.reserve(n, flags)?; - - let spare =3D self.spare_capacity_mut(); - - for item in spare.iter_mut().take(n - 1) { - item.write(value.clone()); - } - - // We can write the last element directly without cloning needless= ly. - spare[n - 1].write(value); - - // SAFETY: - // - `self.len() + n < self.capacity()` due to the call to reserve= above, - // - the loop and the line above initialized the next `n` elements. - unsafe { self.set_len(self.len() + n) }; - - Ok(()) + self.extend(core::iter::repeat_n(value, n), flags) } =20 /// Pushes clones of the elements of slice into the [`Vec`] instance. @@ -496,18 +552,7 @@ pub fn extend_with(&mut self, n: usize, value: T, flag= s: Flags) -> Result<(), Al /// # Ok::<(), Error>(()) /// ``` pub fn extend_from_slice(&mut self, other: &[T], flags: Flags) -> Resu= lt<(), AllocError> { - self.reserve(other.len(), flags)?; - for (slot, item) in core::iter::zip(self.spare_capacity_mut(), oth= er) { - slot.write(item.clone()); - } - - // SAFETY: - // - `other.len()` spare entries have just been initialized, so it= is safe to increase - // the length by the same number. - // - `self.len() + other.len() <=3D self.capacity()` is guaranteed= by the preceding `reserve` - // call. - unsafe { self.set_len(self.len() + other.len()) }; - Ok(()) + self.extend(other.iter().cloned(), flags) } =20 /// Create a new `Vec<T, A>` and extend it by `n` clones of `value`. --- base-commit: a2cc6ff5ec8f91bc463fd3b0c26b61166a07eb11 change-id: 20250405-vec_extend-4321251acc21 Best regards, --=20 Alexandre Courbot <acourbot@nvidia.com>