From patchwork Tue May 16 15:42:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Szabolcs Nagy X-Patchwork-Id: 20466 Received: (qmail 64381 invoked by alias); 16 May 2017 15:42:43 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 62902 invoked by uid 89); 16 May 2017 15:42:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=stdiocommon, stdio-common, H*u:31.0, fct X-HELO: EUR01-HE1-obe.outbound.protection.outlook.com Authentication-Results: arm.com; dkim=none (message not signed) header.d=none;arm.com; dmarc=none action=none header.from=arm.com; Message-ID: <591B1DE9.90805@arm.com> Date: Tue, 16 May 2017 16:42:33 +0100 From: Szabolcs Nagy User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.8.0 MIME-Version: 1.0 To: GNU C Library CC: Subject: [RFC PATCH] Single threaded stdio optimization X-ClientProxiedBy: DB6PR07CA0161.eurprd07.prod.outlook.com (2603:10a6:6:43::15) To HE1PR0802MB2491.eurprd08.prod.outlook.com (2603:10a6:3:d9::23) X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: HE1PR0802MB2491: X-MS-Office365-Filtering-Correlation-Id: 2d727991-5b84-4be9-2555-08d49c722df6 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081)(201703131423075)(201703031133081); SRVR:HE1PR0802MB2491; X-Microsoft-Exchange-Diagnostics: 1; HE1PR0802MB2491; 3:fZHZHS2xF6Alc9TFBhqUaLoufuDOloEXPLuM7aWdimo0p4bSHXK++spS3niNwI+7jNTNP6rKfuuHkLH6DH0g5IxO6ULXmFIXAZj2AcxbBr241eMuy/oxLtXDNEI90xKMCLVrB3To/+gky3DQllTkBGjg8imXadIQ4dSUQ+bpjWvr/lEtAdQSSC0c5pGHkD7phBsP7nzgP4jCIrgvWBAQgeeci/6nuin6kDDALm5H5Yi3OmvJpxGMRtft++ruM0KsTImndC2BctadVbGry/kDrEsMAQjYoohDoOodxrZZcdOWnwdYVO6QeGXoZZLq5kIVhDw33id96d1exBp1jx6RoCyJUWRkexackNbidSZ0Ghk=; 25:jFUpuNgJlmzRtmRj6UFqvqFB3Wyh/CcOksRbLWmz4JiW57n75MsLeOe8BYlAUUu6Z/Hcwn92kYHvJ2F1N1Xe9cOpLxdi64JkFcuKigO4z0O18ATcqApCm213zLF9zZ8AG1mcOqdt1D52C/vOJly8d1Mxxz5/THsxdvojCkHpsWbLg6XMcaTQ90C/IeIfkgnARpuEFuQoYnVQBUcw6LsO7zrH5lEKpSR3ryyM2jvmQirEsoQEDoolX3BW40mPnsv9FHF7+M9ahC+rVomlMLcsadSkaRnfUet3foMMoPXNz/7+kxPluLwcBzIWRTJwmFdKxBht383PDXhCk9Wpj98WagPgLYkjMy3T2pjOsGA+E8XKpD+C3xbrLyAYqYKFyr9rXuDySYioGbYig+7ZgctII2uU8CHvi531CL+rDwDbWnBi+ojJte1M/fR4Jxziv/R2ex55z3m5EwxTHeALgVgHRDNqt9InEueahb2YjFOdg5fsNcktewgieuadFYmkuJf3vE8pC1FX0CTSe5Rzb+uV6A== X-Microsoft-Exchange-Diagnostics: 1; HE1PR0802MB2491; 31:EwdwQNv3F9TMmqz5Dd/lCAYKsGLjVPkQ7ZTeoWgXjm0WfR8MzQwkPrtzgv6qhUlQBDhfkHyZli4JahdCUcXbWFX/NcGdGjnroXMKDvqNC9JLVOFyuDoqK9fl2f/+ZPOEdKqUS9oyUDKvuGh1E2h1WF5Q7P5MqZo9XptAzMJ3b+w/429EOqT0FAw7VTNFDoxyypVcONnv9uSU0jmP5h3C0NMEgxz9d6WJwb3VGwXUDzsj54tDpXz/uT1mzJSRinGJ4JOuk5t6qSc6g5PeVOtPSA==; 20:7hizbXzAzicNa+MXYprDRQuXozYQT2OMSkVX4Ry/uLmxt42gw0JN9xRwQblTbdhZg/1X85hCIVZ+CWzEen5+hFLRdbTUPzU1Gyl/l4LkcjHm6vTTYv4+kjoN0XSf3Ls0AHPyX5xAYPZzKRhh+/x/wYYFxmb4HcWVWxvH1K1dzEQ= NoDisclaimer: True X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917)(278428928389397); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(102415395)(6040450)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(93006095)(93001095)(6055026)(6041248)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123555025)(20161123560025)(20161123558100)(6072148); SRVR:HE1PR0802MB2491; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0802MB2491; X-Microsoft-Exchange-Diagnostics: 1; HE1PR0802MB2491; 4:1fVHp8T5BVFuzb1rns42geAQHiRBLjut7TQG/9qHAGGdn0+iT/uhP7Ltn5d3XrMwcFhohguLD6wBKcqfLlykn/0JhO+sMpvxiTcZNhp1GxXqAApGOYyB9sWn/BOi1iOvFgpLEwuVKTiO9mE1CmPLG5PUOVIOkPplRvN9yaY7++15OJH+VeU6HeAGv15l4JpIr13HBAbrGNoVE0Rj4uHZvs/EBasd+yJ6C1dccrwG7JVMIr8Lyi5npZCd2nYAg5HhvOog/bIT+lbtvTkWPe3ObXvUgQvbmc7hS8BD4Z2/e0AbBdEMIxUBxhNspyRshMC3GDTvTXFNJ0yBuEygwx/Xchpyi5MUNliiI25ofm33UTN7+p2pOw94YfFpDoW/OHGLUpJfyNdrgXcUcPP/cat8U5hM3mNpFcGnUNh/TNI/8WXPPfmLDFynt+jU+OoQ5L7uPvxdviKWkVUcZKMDyBec3/ysNrj7oIFEU6sZbxAVPQ1H/1pb7ZdsjMfTVkNki922G4OKPh8SPUY9lsah8lYVM+6x0L5qm1OKhGPsR5nySuLIJ5zk+z4dck6AcoIVOBQw2N7qU6+SmLivgRJD/T6r0lqCqGsIrsh+5jJaEtDoMDmFVuRhcS4qk0hHgMP2uN0eXYDxiSN3BsbgOASxA/BRMvVh/hv/kPII5/XnbMkqR0cyI+djXGbjvp4xgXGVTKnwm9rZ+fGbeU5F/JUKsM8IeontIDbUQmhY1ei/Z9eMMegVFCcX3QsNhfX0qkDntm/Xrpx+XQv8fx80oNHilFc04HVDJb8TE/WSHKpfYWMOIrsgN5VP8XnGsl5sOMYA9DlhTVlKh/s0E1gLeAaGzZMj/pth7ZR/zs2RE4vleNptc9ldrclrkNj3DdMDjdmsLJFSgUO7orC5we7Ch2q6UgxGyQ== X-Forefront-PRVS: 03094A4065 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(6049001)(39400400002)(39850400002)(39450400003)(39840400002)(39410400002)(39860400002)(377424004)(21490400002)(53936002)(66066001)(2476003)(4610100001)(6666003)(6916009)(110136004)(4001350100001)(84326002)(4326008)(72206003)(38730400002)(83506001)(478600001)(64126003)(36756003)(5660300001)(3846002)(6116002)(512874002)(6486002)(81166006)(54356999)(50986999)(65816999)(8676002)(2906002)(77096006)(25786009)(568964002)(305945005)(86362001)(7736002)(189998001)(33656002)(5890100001)(270700001)(42186005); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR0802MB2491; H:[10.2.206.69]; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; HE1PR0802MB2491; 23:F1LtUsmZsJNQgpU2tNjuoZ0j3Mk3L7RgmDjFGr+?= =?us-ascii?Q?oWq1bJFqyZemzUREWg2JcJx1QO18Y4XNCptp+y42VIJHBpQOGaRvYvvxF3px?= =?us-ascii?Q?DpOqmZKGcLrd/MmHNKpiMA5Kbejdr0RaxeR1/dVhTaP+rIjAFfCPYEuHaJei?= =?us-ascii?Q?AfKo14DsqJTTLij/Wz2A2T8hOWqz/NrnuPAz7GL8u8eGc55IGyq5ejZGr2Va?= =?us-ascii?Q?RbFYsW465RDSxT5k0RctcihSuU5DDVd2YS41hePF63revJOoBvj5kpcD5++a?= =?us-ascii?Q?0L0mAvpUsYoJPKRkdTx5uPCgbMysN3VifDgegjv6Cxgo/G61R9pLB/FvVNvD?= =?us-ascii?Q?GYbX5Bclx676S9rp9jutyFul90m7uUY6OKR228FQEQPyRGgI7eZjFQIjPnc/?= =?us-ascii?Q?OkUZJzNo7FnMBfkaUNCkYcsrQjJlfGoB0aDnXwMP3iZfOB3CwDK0wX9JVUz2?= =?us-ascii?Q?zxW/rPOJxeXVKv57Zf04+6x+CwcnBVF8KEsAs3MNP4ruc3krgq6KBnaQjtJF?= =?us-ascii?Q?v1USkWya2UzoDLqzvWdI3lxPy1e3BSk7QisxhxKyeI4kU0RqbvdrCaZ3AQ1h?= =?us-ascii?Q?J6hoR62KuogPAACeD+YEoEFzonuJxQNwpaFP7V8albPguGjUZxYW99uIHs0E?= =?us-ascii?Q?bvxNuSBo6OJ60OmdSWCWuAtDH9g+R/VrUEkokJ7ZRkXcXniS6my/81bglY1D?= =?us-ascii?Q?Znd51KwgMUhHh1few79ab1SVxmDPfaUmcevwicPMUMjXpujmsMJfEDRPOUcx?= =?us-ascii?Q?R4cAC3vap80vQW2laWJVNaNuLvVNkFhwa4zyOMw72DJplSRHo2UoeHzCdFVA?= =?us-ascii?Q?2XCe7xjPFTBsZmmNLEQqUBix1Q17wQ4TA8sa+Mmq9sQRAphoT82LwQ6X4xqh?= =?us-ascii?Q?9A2cmN8kX8vb42EG+UTCbPMwRLOJ5ErlnSi07lBqLP7oxwt/WW16VYIxtQbl?= =?us-ascii?Q?1o0IOgeY8o1hk/mwl8gimo6wxP73SMQaqqY6qIXeT9Q2SREOjfpLK1SE/F5w?= =?us-ascii?Q?18NIP43tfL90wBC/IAlcyRSoTdRLtq5s8KUVvcEHrdDCtvbzg05gmtbfYFYH?= =?us-ascii?Q?Jgn7D5g7DoGo1M9xfNL7OR8DOfOYUiV7FtChlrF+az5/AkvUCRN+5KP6eE3T?= =?us-ascii?Q?OiQw58VjiosN8U+7H1FqQzRGyj0M266klLq1U16SOBHiZ2jYq4xmgYqnVTJn?= =?us-ascii?Q?buKNabh7ibruPcLSglbzY5QvatCmVgXxmBWhCgzcCsIqYvk360YppFM/Go2X?= =?us-ascii?Q?Onr/etnigFYxUlp3EsY4=3D?= X-Microsoft-Exchange-Diagnostics: 1; HE1PR0802MB2491; 6:c4BT/OGipS67/r3LCmKAFBiN0lBBexziH3ZwMPFOb4JE7u93f0X+BLfobKu9aB8+OquiRzPVnpVJws4n+N3waPYz1QoTb5SamaXMXN/vSz5iaMUkIHvShZxpk1W/yeiyoLzy5HyqQZJXg7K8RxQw0KTCA0lCSxt08oxw0Ui+efrn2LyPY1L+ycZ8e8MlDqtnp/M/GlJJeIc1HSon8WXYrdV+1WLabieCw89/Q6SI9cnwtk/iIDyGyV+1NlRpR9a/Vjn4g8FOUK14m454uIKRNIrEMMimuGor1JgAcQqQulf4AL8P/zOtzUj/nIe8tPysh6lYykBTJgAlsGKVCdYhautCRnIMKqvieiwc+QDgWh9Oq9FkOXPeDc+sXCqeww2HYE+H/FhvQCd5K2MBy/3zxH/b1y8+n8v493h3YgIjLQbJKuWdUP4t4Hp+cVqhUEalkIeiA5nG9wJduwPV31sM6sg74ldp7reeVx3gMz83oFZ7tPGUeTuTM+IvZHNN/tlzBNwPXDDjwLCKGxb3HzT+b4S+t3DFNqnYnmdNvk1UbSo=; 5:dqvGbRgmqQTISRuz8S3y41grJkkPH23EXD+ivNyYzJ2yzaBFghHXlWKkDcUFFd2Z04+iF/hzeticBmm86E8cRQm5gBdh8XsNpwFdp/zyfNgUcBN1amnlxjru04Mcoetqb1SDiHUpSk/LoxMdUuuF5Q==; 24:n44lAzgIYd4T5D14E4iGOnrKRUNXDstRp5GjMwpqAqlmS+a21uRrKOL0qJrNUsWfXeJ0xwKEc2VjpXn0E+7yxM+YgaS3qYymxMNhWgH/73I= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; HE1PR0802MB2491; 7:hd0tqQhHpvv0q0gnCi1ash+8nUZhdo0e/FFGNt+l1lJxRlcnox/dtpSYTPnsy9aryWuKJ+9FTzFFz1lL2aLZk7TUk9ovaDxxYrXoUJeuBsG+2SoqESp2Q61NRJURJ4BZ0NPDXN8TLUEKa3cF6CzQ2lO1y1G50Lh7YT4/ZWDQ9MjC2OiFmEUnRGr/Q5K8/R6VLmY6BESJ9gjQA9IPbBrUfgLzqgst1ROpSLr7rkHzH7IH5ZodV7gDAQRLFhpJ+BH/1i1/jLEkF9iJa5z3w7ae4RfLC2z78xxmVv7C0DwG50IK5hpzT+jJSCIf52zArOySmR3UhKRtxie35Nxw4dixuA== X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 May 2017 15:42:37.4280 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0802MB2491 Locking overhead can be significant in some stdio operations which are common in single threaded applications so it makes sense to optimize that case. there are two basic approaches: 1) avoid the use of expensive atomics in the lowlevellock code while there is only one thread (x86 already implements this). 2) jump to the _unlocked variant of an stdio function in case the file needs no locking (the process will be single threaded until the end of the stdio function). this patch is an incomplete implementation of 2) which is target independent and improves stdio performance more (however it does not affect lock usage in malloc for example). issues not tackled: - files with _IO_USER_LOCK flag set could use the same mechanism which would mean less checks. - malloc interposition is not handled yet. whenever (non-as-safe) user code may run between flockfile and funlockfile the optimization must be disabled in case a thread is created, i just don't know what's the best way to detect malloc interposition at libc startup. - i used a new libc symbol (_IO_enable_locks) that pthread_create can call to enable the stdio locks, there might be a better way. (abilists are not updated yet). - stdio has various configurations that i did not test (non-linux or non-multi-threaded setups). my question is if this approach is acceptable or if the target specific lowlevellock optimization (like x86 does it) preferred. (a further performance improvement is possible if the flag check is inlined in user code, but then the flag bit becomes abi.) 2017-05-16 Szabolcs Nagy * libio/libio.h (_IO_FLAGS2_NEED_LOCK, _IO_need_lock): Define. * libio/libioP.h (_IO_enable_locks): Declare. * libio/Versions (_IO_enable_locks): New symbol. * libio/genops.c (_IO_enable_locks): Define. (_IO_old_init): Initialize flags2. * include/libio.h (_IO_flockfile): Avoid locking when possible. (_IO_funlockfile): Likewise. * libio/fputc.c (fputc): Likewise. * libio/putc.c (_IO_putc): Likewise. * libio/getc.c (_IO_getc): Likewise. * libio/getchar.c (getchar): Likewise * nptl/pthread_create.c (__pthread_create_2_1): Enable stdio locks. * stdio-common/reg-printf.c (__register_printf_specifier): Likewise. * stdio-common/reg-type.c (__register_printf_type): Likwise. * libio/iofopncook.c (_IO_fopencookie): Enable locking for the file. * sysdeps/pthread/flockfile.c (__flockfile): Likewise. diff --git a/include/libio.h b/include/libio.h index d2fa796758..6d23f5f337 100644 --- a/include/libio.h +++ b/include/libio.h @@ -30,14 +30,14 @@ libc_hidden_proto (_IO_vfscanf) # define _IO_peekc(_fp) _IO_peekc_locked (_fp) # if _IO_lock_inexpensive # define _IO_flockfile(_fp) \ - if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_lock (*(_fp)->_lock) + if (_IO_need_lock(_fp) && ((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_lock (*(_fp)->_lock) # define _IO_funlockfile(_fp) \ - if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_unlock (*(_fp)->_lock) + if (_IO_need_lock(_fp) && ((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_unlock (*(_fp)->_lock) # else # define _IO_flockfile(_fp) \ - if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp) + if (_IO_need_lock(_fp) && ((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp) # define _IO_funlockfile(_fp) \ - if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp) + if (_IO_need_lock(_fp) && ((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp) # endif #endif /* _IO_MTSAFE_IO */ diff --git a/libio/Versions b/libio/Versions index 2a1d6e6c85..a22285ab53 100644 --- a/libio/Versions +++ b/libio/Versions @@ -152,6 +152,9 @@ libc { # f* fmemopen; } + GLIBC_2.25 { + _IO_enable_locks; + } GLIBC_PRIVATE { # Used by NPTL and librt __libc_fatal; diff --git a/libio/fputc.c b/libio/fputc.c index a7cd682fe2..b72305c06f 100644 --- a/libio/fputc.c +++ b/libio/fputc.c @@ -32,6 +32,8 @@ fputc (int c, _IO_FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_putc_unlocked (c, fp); _IO_acquire_lock (fp); result = _IO_putc_unlocked (c, fp); _IO_release_lock (fp); diff --git a/libio/genops.c b/libio/genops.c index a466cfa337..0cbf7e2eaf 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -570,11 +570,28 @@ _IO_init (_IO_FILE *fp, int flags) _IO_init_internal (fp, flags); } +static int stdio_needs_locking; + +void +_IO_enable_locks (void) +{ + _IO_ITER i; + + if (stdio_needs_locking) + return; + stdio_needs_locking = 1; + for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i)) + _IO_iter_file(i)->_flags2 |= _IO_FLAGS2_NEED_LOCK; +} +libc_hidden_def (_IO_enable_locks) + void _IO_old_init (_IO_FILE *fp, int flags) { fp->_flags = _IO_MAGIC|flags; fp->_flags2 = 0; + if (stdio_needs_locking) + fp->_flags2 |= _IO_FLAGS2_NEED_LOCK; fp->_IO_buf_base = NULL; fp->_IO_buf_end = NULL; fp->_IO_read_base = NULL; diff --git a/libio/getc.c b/libio/getc.c index b58fd62308..fd66ef93cf 100644 --- a/libio/getc.c +++ b/libio/getc.c @@ -34,6 +34,8 @@ _IO_getc (FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_getc_unlocked (fp); _IO_acquire_lock (fp); result = _IO_getc_unlocked (fp); _IO_release_lock (fp); diff --git a/libio/getchar.c b/libio/getchar.c index 5b41595d17..d79932114e 100644 --- a/libio/getchar.c +++ b/libio/getchar.c @@ -33,6 +33,8 @@ int getchar (void) { int result; + if (!_IO_need_lock (_IO_stdin)) + return _IO_getc_unlocked (_IO_stdin); _IO_acquire_lock (_IO_stdin); result = _IO_getc_unlocked (_IO_stdin); _IO_release_lock (_IO_stdin); diff --git a/libio/iofopncook.c b/libio/iofopncook.c index a08dfdaa42..982f464a68 100644 --- a/libio/iofopncook.c +++ b/libio/iofopncook.c @@ -172,6 +172,8 @@ _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, _IO_mask_flags (&cfile->__fp.file, read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + cfile->__fp.file._flags2 |= _IO_FLAGS2_NEED_LOCK; + /* We use a negative number different from -1 for _fileno to mark that this special stream is not associated with a real file, but still has to be treated as such. */ diff --git a/libio/libio.h b/libio/libio.h index 518ffd8e44..14bcb92332 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -119,6 +119,7 @@ # define _IO_FLAGS2_SCANF_STD 16 # define _IO_FLAGS2_NOCLOSE 32 # define _IO_FLAGS2_CLOEXEC 64 +# define _IO_FLAGS2_NEED_LOCK 128 #endif /* These are "formatting flags" matching the iostream fmtflags enum values. */ @@ -451,6 +452,9 @@ extern int _IO_ftrylockfile (_IO_FILE *) __THROW; #define _IO_cleanup_region_end(_Doit) /**/ #endif +#define _IO_need_lock(_fp) \ + (((_fp)->_flags2 & _IO_FLAGS2_NEED_LOCK) != 0) + extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, _IO_va_list, int *__restrict); extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, diff --git a/libio/libioP.h b/libio/libioP.h index eb93418c8d..1832b44cc7 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -444,6 +444,8 @@ extern void _IO_list_unlock (void) __THROW; libc_hidden_proto (_IO_list_unlock) extern void _IO_list_resetlock (void) __THROW; libc_hidden_proto (_IO_list_resetlock) +extern void _IO_enable_locks (void) __THROW; +libc_hidden_proto (_IO_enable_locks) /* Default jumptable functions. */ diff --git a/libio/putc.c b/libio/putc.c index b591c5538b..6e1fdeef3a 100644 --- a/libio/putc.c +++ b/libio/putc.c @@ -25,6 +25,8 @@ _IO_putc (int c, _IO_FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_putc_unlocked (c, fp); _IO_acquire_lock (fp); result = _IO_putc_unlocked (c, fp); _IO_release_lock (fp); diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index c7d1b8f413..7ffecd9c3e 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -33,6 +33,11 @@ #include #include +/* hack */ +#include "libioP.h" +#undef mmap +#undef munmap + #include #include @@ -756,6 +761,9 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, collect_default_sched (pd); } + if (__glibc_unlikely (__nptl_nthreads == 1)) + _IO_enable_locks (); + /* Pass the descriptor to the caller. */ *newthread = (pthread_t) pd; diff --git a/stdio-common/reg-printf.c b/stdio-common/reg-printf.c index cbb9307795..92ab2b2d07 100644 --- a/stdio-common/reg-printf.c +++ b/stdio-common/reg-printf.c @@ -21,6 +21,7 @@ #include #include #include +#include "libioP.h" /* Array of functions indexed by format character. */ @@ -67,6 +68,8 @@ __register_printf_specifier (int spec, printf_function converter, __printf_function_table[spec] = converter; __printf_arginfo_table[spec] = arginfo; + _IO_enable_locks (); + out: __libc_lock_unlock (lock); diff --git a/stdio-common/reg-type.c b/stdio-common/reg-type.c index cc8952754a..083233d1b0 100644 --- a/stdio-common/reg-type.c +++ b/stdio-common/reg-type.c @@ -19,6 +19,7 @@ #include #include #include +#include "libioP.h" /* Array of functions indexed by format character. */ @@ -53,6 +54,8 @@ __register_printf_type (printf_va_arg_function fct) __printf_va_arg_table[result - PA_LAST] = fct; } + _IO_enable_locks (); + out: __libc_lock_unlock (lock); diff --git a/sysdeps/pthread/flockfile.c b/sysdeps/pthread/flockfile.c index 7fe8e99161..a8e6c28ed9 100644 --- a/sysdeps/pthread/flockfile.c +++ b/sysdeps/pthread/flockfile.c @@ -25,6 +25,7 @@ void __flockfile (FILE *stream) { + stream->_flags2 |= _IO_FLAGS2_NEED_LOCK; _IO_lock_lock (*stream->_lock); } strong_alias (__flockfile, _IO_flockfile)