From patchwork Thu Dec 6 02:00:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lance Taylor X-Patchwork-Id: 204094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 704DB2C0347 for ; Thu, 6 Dec 2012 13:00:43 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1355364044; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=JTDbSxA h6kHCCFzrZblgQN7dYk8=; b=AF5vgRwgXB10+Ohftt2BCyH07aHDg+9Z2oUUgjl Yl8G9N7zmkO4JVtY/yaPOVYlMplBVtKG7wJUPf+JV3coRxi2dK6+IRfZROqfkbCm uf8h8+7fu3s9BXuKv+qCihhEXCre831eOvzrnCPSUSb8O1M3Q9ke5s0kS/mAe2YA /eIQ= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:X-Google-DKIM-Signature:Received:Received:From:To:Subject:Date:Message-ID:User-Agent:MIME-Version:Content-Type:X-Gm-Message-State:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=hLqTRrejRLVfosUBY1ejEbBQPALoYPVZ0zROAmoed4q2jFfKEiK9MJfW0Gc9hc c8pJPS8XHZvMG8uRW8tj1D8q+lgfOwl49XOch88qDQtcO6LLeWKDhYc8WWRycdus DgHeBWwd1mr3Kb+ySL/BCC7M+BcWjUeVehdw176uTBEMg=; Received: (qmail 18772 invoked by alias); 6 Dec 2012 02:00:34 -0000 Received: (qmail 18740 invoked by uid 22791); 6 Dec 2012 02:00:33 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from mail-da0-f47.google.com (HELO mail-da0-f47.google.com) (209.85.210.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 06 Dec 2012 02:00:26 +0000 Received: by mail-da0-f47.google.com with SMTP id s35so2286737dak.20 for ; Wed, 05 Dec 2012 18:00:26 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:user-agent:mime-version :content-type:x-gm-message-state; bh=zbJHocvxz2swgTMk27PWIP0EFeMp4THgRiTnHWK0T9g=; b=hEcF8TdCkJrir98rOn/vlFf5PLLe0Bko0Y+8ICLAeb6MbwcMkmicLo6s3WRwW1PHZw tPtSwFM5+e7H4wAACw+bQukje0B15Q4djkMhAZfg/beZJNxDtSjgkgxXZDBUufoENOWX tN0p8Uq9mV5z2mlWBJMScJUWjBY92bZAySblSVA+YBwzpBSsBLorH5p3ZHEpoumjF+Os L/i/K4yCr8TAREGmRkqzpShG3TsrcpaDZkfqYDbZgnxdrO+nYNZ52jMmVZDV2brYiX1E 823FBWgPFzG4Jz+pkI77DgtkJ0Mpqn0vrrUWXvGHefwRPCmbK1Nxrf+QS/CKLu8fI0rk VlbQ== Received: by 10.66.83.165 with SMTP id r5mr26457pay.3.1354759226242; Wed, 05 Dec 2012 18:00:26 -0800 (PST) Received: from coign.google.com ([2401:fa00:0:9:224:d7ff:fe8f:f634]) by mx.google.com with ESMTPS id uk9sm3823865pbc.63.2012.12.05.18.00.23 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 05 Dec 2012 18:00:24 -0800 (PST) From: Ian Lance Taylor To: gcc-patches@gcc.gnu.org, gofrontend-dev@googlegroups.com Subject: libgo patch committed: Clean up directory reading code Date: Wed, 05 Dec 2012 18:00:20 -0800 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkmISYddhlAqNjQKVN61sZZQpR8SqOuHomanCXINsKzmeoo8VhQdNUncPNBCpZ+Wb7n2WIQj6blomQx77dlBFe2K+0zWq1JdtfuFmsgAuAFDfdEnJFmDEgU7lpqBHbJo/hX1vC/EsNB9wF/zN7wSLuLc6G0CGChQ7R1U9t1djas/fVQciMBVlK83RajoUEQDTy0nrGv X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch to libgo cleans up the directory reading code. It now calls Entersyscall and Exitsyscall around calls to pathconf and closedir, which are necessary when using a fused file system. It avoids a minor race condition calling pathconf. It generally neatens the code. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian diff -r a35a8711bc0a libgo/go/os/dir.go --- a/libgo/go/os/dir.go Wed Dec 05 00:46:54 2012 -0800 +++ b/libgo/go/os/dir.go Wed Dec 05 17:21:15 2012 -0800 @@ -6,6 +6,7 @@ import ( "io" + "sync/atomic" "syscall" "unsafe" ) @@ -29,27 +30,42 @@ return len(n) } -var elen int +var nameMax int32 func (file *File) readdirnames(n int) (names []string, err error) { - if elen == 0 { - var dummy syscall.Dirent - elen = (int(unsafe.Offsetof(dummy.Name)) + - libc_pathconf(syscall.StringBytePtr(file.name), syscall.PC_NAME_MAX) + - 1) - } + if file.dirinfo == nil { + p, err := syscall.BytePtrFromString(file.name) + if err != nil { + return nil, err + } - if file.dirinfo == nil { + elen := int(atomic.LoadInt32(&nameMax)) + if elen == 0 { + syscall.Entersyscall() + plen := libc_pathconf(p, syscall.PC_NAME_MAX) + syscall.Exitsyscall() + if plen < 1024 { + plen = 1024 + } + var dummy syscall.Dirent + elen = int(unsafe.Offsetof(dummy.Name)) + plen + 1 + atomic.StoreInt32(&nameMax, int32(elen)) + } + + syscall.Entersyscall() + r := libc_opendir(p) + errno := syscall.GetErrno() + syscall.Exitsyscall() + if r == nil { + return nil, &PathError{"opendir", file.name, errno} + } + file.dirinfo = new(dirInfo) file.dirinfo.buf = make([]byte, elen) - p := syscall.StringBytePtr(file.name) - syscall.Entersyscall() - r := libc_opendir(p) - syscall.Exitsyscall() file.dirinfo.dir = r } - entry_dirent := (*syscall.Dirent)(unsafe.Pointer(&file.dirinfo.buf[0])) + entryDirent := (*syscall.Dirent)(unsafe.Pointer(&file.dirinfo.buf[0])) size := n if size <= 0 { @@ -59,24 +75,20 @@ names = make([]string, 0, size) // Empty with room to grow. - dir := file.dirinfo.dir - if dir == nil { - return names, NewSyscallError("opendir", syscall.GetErrno()) - } - for n != 0 { - var result *syscall.Dirent - pr := &result + var dirent *syscall.Dirent + pr := &dirent syscall.Entersyscall() - i := libc_readdir_r(dir, entry_dirent, pr) + i := libc_readdir_r(file.dirinfo.dir, entryDirent, pr) syscall.Exitsyscall() if i != 0 { return names, NewSyscallError("readdir_r", i) } - if result == nil { + if dirent == nil { break // EOF } - var name = string(result.Name[0:clen(result.Name[0:])]) + bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) + var name = string(bytes[0:clen(bytes[:])]) if name == "." || name == ".." { // Useless names continue } diff -r a35a8711bc0a libgo/go/os/file_unix.go --- a/libgo/go/os/file_unix.go Wed Dec 05 00:46:54 2012 -0800 +++ b/libgo/go/os/file_unix.go Wed Dec 05 17:21:15 2012 -0800 @@ -108,8 +108,13 @@ } if file.dirinfo != nil { - if libc_closedir(file.dirinfo.dir) < 0 && err == nil { - err = &PathError{"closedir", file.name, syscall.GetErrno()} + syscall.Entersyscall() + i := libc_closedir(file.dirinfo.dir) + errno := syscall.GetErrno() + syscall.Exitsyscall() + file.dirinfo = nil + if i < 0 && err == nil { + err = &PathError{"closedir", file.name, errno} } }