From patchwork Mon Feb 7 06:05:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Frysinger X-Patchwork-Id: 82245 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id F3DE9B70EA for ; Tue, 8 Feb 2011 10:48:10 +1100 (EST) Received: from localhost ([127.0.0.1]:34769 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmKGr-0002s7-Gq for incoming@patchwork.ozlabs.org; Mon, 07 Feb 2011 01:08:21 -0500 Received: from [140.186.70.92] (port=34888 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmKEs-0002qv-Qw for qemu-devel@nongnu.org; Mon, 07 Feb 2011 01:06:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PmKEq-0001Wk-SY for qemu-devel@nongnu.org; Mon, 07 Feb 2011 01:06:18 -0500 Received: from smtp.gentoo.org ([140.211.166.183]:48149) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PmKEq-0001WG-Ga for qemu-devel@nongnu.org; Mon, 07 Feb 2011 01:06:16 -0500 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.gentoo.org (Postfix) with ESMTP id C56071B4119; Mon, 7 Feb 2011 06:05:54 +0000 (UTC) From: Mike Frysinger To: qemu-devel@nongnu.org, Riku Voipio Date: Mon, 7 Feb 2011 01:05:56 -0500 Message-Id: <1297058757-7611-8-git-send-email-vapier@gentoo.org> X-Mailer: git-send-email 1.7.4 In-Reply-To: <1297058757-7611-1-git-send-email-vapier@gentoo.org> References: <1297058757-7611-1-git-send-email-vapier@gentoo.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.211.166.183 Cc: Subject: [Qemu-devel] [PATCH 8/9] user: speed up init_paths a bit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The current init_paths code will attempt to opendir() every single file it finds. This can obviously generated a huge number of syscalls with even a moderately small sysroot that will fail. Since the readdir() call provides the file type in the struct itself, use it. On my system, this prevents over 1000 syscalls from being made at every invocation of a target binary, and I only have a C library installed. Signed-off-by: Mike Frysinger --- path.c | 28 ++++++++++++++++++++++------ 1 files changed, 22 insertions(+), 6 deletions(-) diff --git a/path.c b/path.c index 0d2bf14..ef3f277 100644 --- a/path.c +++ b/path.c @@ -38,7 +38,8 @@ static int strneq(const char *s1, unsigned int n, const char *s2) return s2[i] == 0; } -static struct pathelem *add_entry(struct pathelem *root, const char *name); +static struct pathelem *add_entry(struct pathelem *root, const char *name, + unsigned char type); static struct pathelem *new_entry(const char *root, struct pathelem *parent, @@ -56,6 +57,15 @@ static struct pathelem *new_entry(const char *root, #define streq(a,b) (strcmp((a), (b)) == 0) +/* Not all systems provide this feature */ +#if defined(DT_DIR) && defined(DT_UNKNOWN) +# define dirent_type(dirent) ((dirent)->d_type) +# define is_dir_maybe(type) ((type) == DT_DIR || (type) == DT_UNKNOWN) +#else +# define dirent_type(dirent) (1) +# define is_dir_maybe(type) (type) +#endif + static struct pathelem *add_dir_maybe(struct pathelem *path) { DIR *dir; @@ -65,7 +75,7 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) while ((dirent = readdir(dir)) != NULL) { if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){ - path = add_entry(path, dirent->d_name); + path = add_entry(path, dirent->d_name, dirent_type(dirent)); } } closedir(dir); @@ -73,16 +83,22 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) return path; } -static struct pathelem *add_entry(struct pathelem *root, const char *name) +static struct pathelem *add_entry(struct pathelem *root, const char *name, + unsigned char type) { + struct pathelem **e; + root->num_entries++; root = realloc(root, sizeof(*root) + sizeof(root->entries[0])*root->num_entries); + e = &root->entries[root->num_entries-1]; + + *e = new_entry(root->pathname, root, name); + if (is_dir_maybe(type)) { + *e = add_dir_maybe(*e); + } - root->entries[root->num_entries-1] = new_entry(root->pathname, root, name); - root->entries[root->num_entries-1] - = add_dir_maybe(root->entries[root->num_entries-1]); return root; }