Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #92512 > unrolled thread
| Started by | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| First post | 2016-08-19 14:22 -0700 |
| Last post | 2016-08-22 05:11 -0700 |
| Articles | 20 on this page of 355 — 30 participants |
Back to article view | Back to comp.lang.c
Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-19 14:22 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-20 09:36 +1200
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-19 22:48 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-19 14:56 -0700
Re: Default values in #define Chad <cdalten@gmail.com> - 2016-08-22 07:56 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-22 17:09 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 08:21 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 08:47 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 08:55 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-22 09:27 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 09:41 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-22 20:19 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 12:54 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 09:14 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 05:23 -0700
Re: Default values in #define mark.bluemel@gmail.com - 2016-08-23 05:42 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 05:52 -0700
Re: Default values in #define mark.bluemel@gmail.com - 2016-08-23 06:01 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 06:06 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 06:01 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 15:56 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 06:59 -0700
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-08-23 10:42 -0700
Re: Default values in #define matt@godbolt.org - 2016-08-23 06:47 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 15:57 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 15:31 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 06:43 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 16:06 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 07:15 -0700
Re: Default values in #define albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-12-04 13:26 +0100
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-05 22:07 -0600
Re: Default values in #define supercat@casperkitty.com - 2016-12-06 06:22 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-07 00:50 -0600
Re: Default values in #define supercat@casperkitty.com - 2016-12-07 06:33 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-07 23:06 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-08 01:44 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-08 06:58 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-10 08:16 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-11 02:47 -0600
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-09 15:49 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-09 15:52 -0800
Re: Default values in #define asetofsymbols@gmail.com - 2016-12-09 00:52 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-10 03:19 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-07 04:43 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-08 14:18 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-08 07:22 -0800
Re: Default values in #define supercat@casperkitty.com - 2016-12-08 08:00 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-08 22:14 +0100
Re: Default values in #define supercat@casperkitty.com - 2016-12-08 13:44 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-09 16:07 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-09 17:00 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-09 17:46 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-10 08:37 -0800
Re: Default values in #define supercat@casperkitty.com - 2016-12-10 09:42 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-10 10:05 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-11 02:51 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-11 04:40 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-11 23:06 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-12 03:15 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-12 16:12 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-12 07:33 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-13 01:45 -0600
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-12 16:49 +0000
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-12 10:25 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-13 10:50 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 04:02 -0800
Re: Default values in #define BartC <bc@freeuk.com> - 2016-12-13 13:14 +0000
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 05:57 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-13 14:32 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 05:58 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 06:21 -0800
Re: Default values in #define BartC <bc@freeuk.com> - 2016-12-13 14:41 +0000
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 06:47 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-13 16:24 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 07:30 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-14 14:12 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-14 12:21 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-14 15:02 -0600
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-14 13:19 -0800
Petty and unprofessional (Was: Default values in #define) gazelle@shell.xmission.com (Kenny McCormack) - 2016-12-13 16:46 +0000
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 09:04 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-13 20:06 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 11:19 -0800
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-12-13 11:33 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 11:44 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-14 10:04 +0100
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-13 14:37 -0800
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-12-14 14:28 -0600
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-13 14:23 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 16:10 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-13 18:54 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-13 18:57 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-14 02:53 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-14 05:59 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-14 12:03 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-14 12:22 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-14 17:09 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-14 18:37 -0800
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-12-13 05:25 -0800
Re: Default values in #define supercat@casperkitty.com - 2016-12-12 07:31 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-12 07:35 -0800
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-12-12 09:17 -0800
Re: Default values in #define supercat@casperkitty.com - 2016-12-12 11:03 -0800
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-12-12 11:41 -0800
Re: Default values in #define supercat@casperkitty.com - 2016-12-12 12:31 -0800
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-12-12 13:13 -0800
Re: Default values in #define BartC <bc@freeuk.com> - 2016-12-12 20:22 +0000
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-11 14:49 +0000
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-11 07:10 -0800
Re: Default values in #define luser droog <luser.droog@gmail.com> - 2016-12-11 07:21 -0800
Re: Default values in #define jameskuyper@verizon.net - 2016-12-11 10:33 -0800
Re: Default values in #define Melzzzzz <mel@zzzzz.com> - 2016-12-11 16:22 +0100
Re: Default values in #define luser droog <luser.droog@gmail.com> - 2016-12-11 07:16 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-13 13:54 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 14:09 -0800
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-13 14:31 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-12-13 16:11 -0800
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 06:49 -0700
Re: Default values in #define Andrew Haley <andrew29@littlepinkcloud.invalid> - 2016-12-21 05:50 -0600
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-12-21 13:10 +0100
Re: Default values in #define supercat@casperkitty.com - 2016-08-22 12:56 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-22 21:11 +0100
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-08-22 15:47 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-23 11:54 -0700
Re: Default values in #define Gareth Owen <gwowen@gmail.com> - 2016-08-23 20:07 +0100
Re: Default values in #define supercat@casperkitty.com - 2016-08-23 14:30 -0700
Re: Default values in #define Gareth Owen <gwowen@gmail.com> - 2016-08-24 06:25 +0100
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-24 10:34 +0200
Re: Default values in #define Richard Damon <Richard@Damon-Family.org> - 2016-08-24 08:50 -0400
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-24 15:37 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-24 11:58 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-25 01:27 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-24 22:28 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-24 23:38 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-25 10:44 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 07:29 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-25 07:32 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 10:26 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-25 11:11 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 12:03 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 15:31 +0200
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-08-29 09:28 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 22:51 +0200
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-08-29 16:35 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 01:44 +0200
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-30 10:06 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-30 10:41 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 21:24 +0200
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 12:32 -0700
Re: Default values in #define Jean-Marc Bourguet <jm@bourguet.org> - 2016-08-30 22:30 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-31 09:17 +0200
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-31 22:46 -0700
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-08-31 10:29 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-31 10:12 -0700
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-08-31 12:30 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-31 11:32 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-31 22:56 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-09-01 08:17 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-04 22:18 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-31 22:34 -0700
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-09-01 00:32 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-02 05:19 -0700
Re: Default values in #define Jean-Marc Bourguet <jm@bourguet.org> - 2016-09-01 11:38 +0200
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-09-01 10:03 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-09-01 10:31 -0700
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-09-01 12:50 -0700
Re: Default values in #define Jean-Marc Bourguet <jm@bourguet.org> - 2016-09-01 21:30 +0200
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-02 05:37 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-09-02 08:16 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-04 22:20 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-09-06 07:32 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-11 06:54 -0700
Re: Default values in #define Keith Thompson <kst-u@mib.org> - 2016-09-02 08:40 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-09-02 10:16 -0700
Re: Default values in #define Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-04 15:16 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-25 08:28 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 10:14 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 00:54 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 01:00 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-26 11:17 +0100
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 04:08 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-26 13:45 +0100
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 06:09 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-26 17:11 +0100
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 09:31 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-26 12:48 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-26 09:50 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 16:01 +0200
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-29 10:57 -0700
Re: Default values in #define Ike Naar <ike@iceland.freeshell.org> - 2016-08-31 06:09 +0000
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-26 12:24 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-26 17:27 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-26 17:39 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-26 21:49 +0100
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 15:51 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 15:46 +0200
Re: Default values in #define Richard Damon <Richard@Damon-Family.org> - 2016-08-26 17:37 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-26 15:05 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-27 10:25 +1200
Re: Default values in #define supercat@casperkitty.com - 2016-08-26 16:25 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 18:12 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-27 13:47 +1200
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 19:32 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-26 22:54 -0400
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-26 21:11 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-27 18:25 +1200
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-27 09:11 -0400
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-27 06:33 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-27 10:16 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-27 13:17 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-27 16:26 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-27 13:10 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-27 16:35 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 09:28 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-29 15:38 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 13:27 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-29 16:42 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 14:16 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-29 17:24 -0400
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 13:21 +0200
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-30 08:12 -0400
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 15:24 +0200
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-30 10:53 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-30 10:34 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-30 14:44 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-30 12:48 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-30 17:19 -0400
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-31 11:24 +0200
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-31 10:33 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-31 09:51 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-31 22:46 -0400
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-30 16:26 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-09-03 17:31 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-09 16:03 -0800
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 21:36 +0200
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-30 17:30 -0400
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-31 12:39 +0200
Re: Default values in #define already5chosen@yahoo.com - 2016-08-31 03:57 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-31 15:34 +0200
Re: Default values in #define already5chosen@yahoo.com - 2016-08-31 07:33 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-31 10:46 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-31 10:03 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-31 22:52 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-09-01 07:41 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-01 14:58 -0400
Re: Default values in #define already5chosen@yahoo.com - 2016-08-31 02:27 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-31 08:21 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-31 09:05 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-31 09:15 -0700
Re: Default values in #define Rosario19 <Ros@invalid.invalid> - 2016-09-02 22:22 +0200
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-28 08:41 +1200
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-27 20:34 -0400
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 09:41 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-30 08:07 +1200
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 14:08 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-29 15:41 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 16:30 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-29 17:14 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-29 17:20 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 23:37 -0700
Re: Default values in #define already5chosen@yahoo.com - 2016-08-30 02:19 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 13:26 +0200
Re: Default values in #define already5chosen@yahoo.com - 2016-08-30 04:40 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 13:56 +0200
Re: Default values in #define albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-12-04 15:43 +0100
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-30 19:34 +1200
Re: Default values in #define supercat@casperkitty.com - 2016-08-30 00:51 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-30 20:36 +1200
Re: Default values in #define Robert Wessel <robertwessel2@yahoo.com> - 2016-08-31 00:39 -0500
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-26 21:40 -0700
Re: Default values in #define Jerry Stuckle <jstucklex@attglobal.net> - 2016-08-27 09:22 -0400
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-29 11:36 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-09 16:26 -0800
Re: Default values in #define Gareth Owen <gwowen@gmail.com> - 2016-08-27 06:34 +0100
Re: Default values in #define supercat@casperkitty.com - 2016-08-27 12:48 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 16:12 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 16:10 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 10:18 -0700
Re: Default values in #define already5chosen@yahoo.com - 2016-08-29 10:32 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 10:49 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 23:13 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 14:48 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-26 09:14 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-26 08:59 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 15:43 +0200
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-29 22:58 -0700
Re: Default values in #define Gareth Owen <gwowen@gmail.com> - 2016-08-30 07:14 +0100
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-30 00:14 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 00:26 -0700
Re: Default values in #define already5chosen@yahoo.com - 2016-08-30 02:10 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-30 10:47 +0100
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 03:32 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 13:38 +0200
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 04:44 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 14:00 +0200
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-30 18:55 +0100
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 12:24 -0700
Re: Default values in #define me <crisdunbar@gmail.com> - 2016-08-30 14:11 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 16:28 -0700
Re: Default values in #define me <crisdunbar@gmail.com> - 2016-08-30 16:54 -0700
Re: Default values in #define Gareth Owen <gwowen@gmail.com> - 2016-08-31 06:27 +0100
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-30 23:09 +0100
Re: Default values in #define supercat@casperkitty.com - 2016-08-30 16:06 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 13:35 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-30 13:30 +0200
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-30 04:39 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 15:40 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 15:17 +0200
Re: Default values in #define already5chosen@yahoo.com - 2016-08-29 06:47 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 16:58 +0200
Re: Default values in #define already5chosen@yahoo.com - 2016-08-29 09:09 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 23:16 +0200
Re: Default values in #define already5chosen@yahoo.com - 2016-08-31 02:02 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-31 12:49 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-31 09:02 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-25 10:31 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 10:01 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 16:24 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 10:43 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 23:29 +0200
Re: Default values in #define supercat@casperkitty.com - 2016-08-29 16:27 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-25 10:02 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 10:33 -0700
Re: Default values in #define "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-08-25 14:12 -0700
Re: Default values in #define supercat@casperkitty.com - 2016-08-25 14:22 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-29 16:27 +0200
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-22 23:13 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 14:39 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 09:32 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 05:33 -0700
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-23 06:13 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 06:22 -0700
Re: Default values in #define David Brown <david.brown@hesbynett.no> - 2016-08-23 16:13 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-23 07:35 -0700
Re: Default values in #define Gareth Owen <gwowen@gmail.com> - 2016-08-23 19:08 +0100
Re: Default values in #define Rosario19 <Ros@invalid.invalid> - 2016-08-24 09:05 +0200
Re: Default values in #define mark.bluemel@gmail.com - 2016-08-24 00:49 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-24 05:40 -0700
Re: Default values in #define BartC <bc@freeuk.com> - 2016-08-19 22:56 +0100
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-20 10:14 +1200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-19 18:09 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-20 13:15 +1200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-19 19:10 -0700
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-20 14:50 +1200
Re: Default values in #define BartC <bc@freeuk.com> - 2016-08-20 10:35 +0100
Re: Default values in #define Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-20 03:13 -0700
Re: Default values in #define BartC <bc@freeuk.com> - 2016-08-20 12:24 +0100
Re: Default values in #define Ian Collins <ian-news@hotmail.com> - 2016-08-21 00:14 +1200
Re: Default values in #define gazelle@shell.xmission.com (Kenny McCormack) - 2016-08-20 14:13 +0000
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 05:17 -0700
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-20 12:08 -0700
Re: Default values in #define Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-08-20 14:06 +0100
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-20 12:14 -0700
Re: Default values in #define Philipp Klaus Krause <pkk@spth.de> - 2016-08-21 12:51 +0200
Re: Default values in #define "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2016-08-22 05:11 -0700
Page 16 of 18 — ← Prev page 1 … 14 15 [16] 17 18 Next page →
| From | Gareth Owen <gwowen@gmail.com> |
|---|---|
| Date | 2016-08-31 06:27 +0100 |
| Message-ID | <87inuhzewy.fsf@gmail.com> |
| In reply to | #92970 |
me <crisdunbar@gmail.com> writes: > Can you explain a use-case for this type of thing? Its useful for demonstrating how confused Malcolm is about thread-safety.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2016-08-30 23:09 +0100 |
| Message-ID | <8760qhx61v.fsf@bsb.me.uk> |
| In reply to | #92957 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Tuesday, August 30, 2016 at 6:55:36 PM UTC+1, Ben Bacarisse wrote:
>> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
>>
>> > On Tuesday, August 30, 2016 at 10:47:58 AM UTC+1, Ben Bacarisse wrote:
>> >> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
>> >> <snip>
>> >> > When I actually did this sort of thing.
>> >> >
>> >> > volatile char flag = 0;
>> >> >
>> >> > if(flag == 0)
>> >> > {
>> >> > flag = 1;
>> >> > do_your_stuff();
>> >> > flag = 0;
>> >> > }
>> >> >
>> >> > was fine. You could run as many threads as you wanted.
>> >>
>> >> Not, I hope, in a pacemaker -- there is nothing to prevent two threads
>> >> seeing flag == 0.
>> >>
>> >> You've spoken before about games programming and the idea that getting
>> >> incorrect results quickly is sometimes desirable. That may have been
>> >> the context where you actually did this sort of thing -- where a
>> >> violation of mutual exclusion might won't be a critical failure -- but
>> >> I'd always want to announce that about such code.
>> >>
>> > The interrupt occurs between the if() and the flag = 1?
>>
>> No, I was not assuming any particular model of threading.
>>
>> > The thing is the interrupt routine disables interrupts. So the thread sees 0.
>> > The interrupt routine interrupts at that point, and also sees zero. the
>> > interrupt routine then does its stuff and plays about with buffer. Control
>> > returns to the main thread. The flag is now set to one. The main thread
>> > then plays about with the buffer. There's another interrupt, but now the
>> > flag is one, so the interrupt routine doesn't fiddle about with the buffer
>> > but does its stuff in a secondary or reserve buffer. main thread sets the
>> > flag to zero. theres a third interrupt, and now the interrupt routine does its
>> > stuff.
>>
>> That does not match the usual meaning of "You could run as many threads
>> as you wanted". That suggests the flag provides mutual exclusion
>> between identical thread all running that code fragment. I'm happy that
>> the code worked in whatever environment you are describing. I just
>> wanted to make sure no one thought this was a general solution to mutual
>> exclusion between threads sharing memory.
>>
> It was a general solution in that it worked.
But you don't say what problem it was solving. Apparently some rather
specific one in one rather specific context. That's not a general
solution.
> It is apparently no longer, as I made clear.
What you appeared to say has no not changed. A simple flag has always
been inadequate as a general solution to synchronising threads using
shared memory. It fails for reasons so obvious that I'm sure you are
not suggesting it in the way you appear to be, I just don't know what
problem you think it once did solve.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-30 16:06 -0700 |
| Message-ID | <d128636d-f621-4622-8992-87005b099b77@googlegroups.com> |
| In reply to | #92965 |
On Tuesday, August 30, 2016 at 5:09:41 PM UTC-5, Ben Bacarisse wrote: > What you appeared to say has no not changed. A simple flag has always > been inadequate as a general solution to synchronising threads using > shared memory. On a system with a memory model where volatile variables are positively sequenced with regard to everything else, if one has two tasks that want to share a resource, but any task that cedes control of the resource to the other one won't need that resource again until the other task is done with it, a single volatile flag saying who owns the resource will be sufficient. A simple volatile "busy" flag which is operated by main-line code will also be sufficient in many applications involving interrupts provided that an interrupt handler can deal with being unable to access the resource because it's busy (and provided that, as above, the system ensures that volatile variables are positively sequenced with regard to everything else).
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-30 13:35 +0200 |
| Message-ID | <nq3r20$fgi$1@dont-email.me> |
| In reply to | #92922 |
On 30/08/16 09:26, Malcolm McLean wrote:
> On Tuesday, August 30, 2016 at 8:14:43 AM UTC+1, Chris M. Thomasson wrote:
>> On 8/29/2016 10:58 PM, Malcolm McLean wrote:
>>> On Monday, August 29, 2016 at 2:44:00 PM UTC+1, David Brown wrote:
>>>> On 26/08/16 13:08, Malcolm McLean wrote:
>>>>
>>>>> People hooked up processors to IO ports that sent data at unpredictable
>>>>> intervals long before 2011. You can write a token system in most dialects
>>>>> of C. But supercat might be right, theoretically an aggressive or perverse
>>>>> optimiser could wreck the system if it moves the buffer access outside
>>>>> the token guards.
>>>>>
>>>>
>>>> Please don't listen to Supercat here. He is either ignorant, or being
>>>> intentionally confusing. There is nothing theoretical or aggressive
>>>> about a compiler re-ordering non-volatile accesses with respect to
>>>> volatile ones - it is part of common compiler optimisations. And as Ben
>>>> says, this is a well-understood issue with well-understood solutions.
>>>> The only "problem" occurs when people who /don't/ understand the issues
>>>> present incorrect "solutions" or make false claims about what compilers
>>>> do or did "in the good old days".
>>>>
>>> I see.
>>> So if we implement a semaphore / token /flag system, the buffer must also
>>> be volatile, even though in fact it can't change when the accessor has
>>> the token, to prevent the optimiser moving the buffer accesses from
>>> outside the token guards.
>>
>> You can use volatile and cross your fingers. However, I prefer to use
>> the std atomics/membars when available, or resort to some custom asm wrt
>> implementing a synchronization algorithm. Then, you know where
>> everything is. ;^)
>>
> When I actually did this sort of thing.
>
> volatile char flag = 0;
>
> if(flag == 0)
> {
> flag = 1;
> do_your_stuff();
> flag = 0;
> }
>
> was fine. You could run as many threads as you wanted.
> If everything has become more complex then that is sad, except of
> course in the case where you can have contention for flag - that's
> something that can be inherently hard to solve if the underlying
> hardware doesn't allow two threads to access the same memory
> essentially at the same time.
>
Discussions about race conditions aside, this will only work as long as
the compiler doesn't know about the definition of "do_your_stuff" while
compiling this code. If the compiler knows nothing about the function,
it has to assume it might contain volatile accesses - and therefore it
must order the function between the two volatile accesses to "flag".
But if it knows that do_your_stuff has no observable behaviour, it can
move it before "flag = 1" or after "flag = 0". It may even be able to
move it outside the conditional, depending on the details of the
function - or to split the function into bits that go in different places.
And with modern compilers doing link-time optimisation, you can no
longer assume that it is sufficient to put "do_your_stuff" in a
different C file.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-30 13:30 +0200 |
| Message-ID | <nq3qok$elt$1@dont-email.me> |
| In reply to | #92918 |
On 30/08/16 07:58, Malcolm McLean wrote: > On Monday, August 29, 2016 at 2:44:00 PM UTC+1, David Brown wrote: >> On 26/08/16 13:08, Malcolm McLean wrote: >> >>> People hooked up processors to IO ports that sent data at unpredictable >>> intervals long before 2011. You can write a token system in most dialects >>> of C. But supercat might be right, theoretically an aggressive or perverse >>> optimiser could wreck the system if it moves the buffer access outside >>> the token guards. >>> >> >> Please don't listen to Supercat here. He is either ignorant, or being >> intentionally confusing. There is nothing theoretical or aggressive >> about a compiler re-ordering non-volatile accesses with respect to >> volatile ones - it is part of common compiler optimisations. And as Ben >> says, this is a well-understood issue with well-understood solutions. >> The only "problem" occurs when people who /don't/ understand the issues >> present incorrect "solutions" or make false claims about what compilers >> do or did "in the good old days". >> > I see. > So if we implement a semaphore / token /flag system, the buffer must also > be volatile, even though in fact it can't change when the accessor has > the token, to prevent the optimiser moving the buffer accesses from > outside the token guards. > Usually if you have functions or macros for implementing semaphores or other locks, these will include the required compiler or memory barriers. But if you are doing things manually, then you need to handle things yourself. As has been explained countless times in this thread, you can use volatile declarations for your buffers, forced volatile accesses for the buffer accesses, compiler or memory barriers, intrinsic functions, C11 atomic fences, or whatever other method you prefer. But simply making volatile accesses to a flag or token does not provide any synchronisation with other accesses.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-08-30 04:39 -0700 |
| Message-ID | <8cd4487c-84d2-41d9-b87c-4a3c96823b22@googlegroups.com> |
| In reply to | #92935 |
On Tuesday, August 30, 2016 at 12:30:36 PM UTC+1, David Brown wrote: > On 30/08/16 07:58, Malcolm McLean wrote: > > Usually if you have functions or macros for implementing semaphores or > other locks, these will include the required compiler or memory > barriers. But if you are doing things manually, then you need to handle > things yourself. As has been explained countless times in this thread, > you can use volatile declarations for your buffers, forced volatile > accesses for the buffer accesses, compiler or memory barriers, intrinsic > functions, C11 atomic fences, or whatever other method you prefer. But > simply making volatile accesses to a flag or token does not provide any > synchronisation with other accesses. > Obviously yes, most dev systems will come with macros for threading and so on and you should use them. But it's nice to know how to do it yourself from scratch.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-29 15:40 +0200 |
| Message-ID | <nq1dvg$q6f$1@dont-email.me> |
| In reply to | #92712 |
On 26/08/16 10:00, Malcolm McLean wrote: > On Thursday, August 25, 2016 at 6:15:00 PM UTC+1, supe...@casperkitty.com wrote: >> On Thursday, August 25, 2016 at 10:28:20 AM UTC-5, Malcolm McLean wrote: >>> On Thursday, August 25, 2016 at 3:29:43 PM UTC+1, supercat wrote: >>>> Since many freestanding implementations of C generally won't support the >>>> C11 threading extensions (since that would require that the implementation >>>> be much heavier weight than one which lets programmers operate on bare >>>> metal), by what standard means would you suggest that programmers tell the >>>> compiler that something is locked? >>>> >>> A flag will do. >>> >>> The difficult isn't in setting a flag, assuming that writes of a single byte are atomic >>> and can't be interrupted. It's what to do if the resource is locked. >> >> Do you means a "flag", as in: >> >> unsigned char data_source_1[64], data_source_2[64]; >> unsigned char data_buff[64]; >> >> volatile atomic_byte buffer_busy; >> >> while(buffer_busy) >> ; >> memcpy(data_buff, data_source_1, 64); >> buffer_busy = 1; // Tell interrupt to send data & clear flag >> while(buffer_busy) >> ; >> memcpy(data_buff, data_source_1, 64); >> buffer_busy = 1; >> >> That's the pattern I'd like to use, but nothing in the Standard would >> forbid a compiler from moving the memcpy operation before the "while()" >> statement. >> > Exactly. > Details would vary according to the thread mechanism (interrupt > service routines, threads, etc). But the basic idea is that a > single flag says who owns the data and whether it is safe to read > or safe to write. Because you can only read from the buffer when it > is in a coherent state. > If this is not allowed, then it is deeply problematic for anyone > using C for low-level, hardware interacting routines. The compiler can happily shuffle the accesses to data_buff and data_source around with respect to the reads and writes to the volatile buffer_busy flag. If you don't understand this, you should simply stay away from anything involving C for low-level, hardware interacting routines - as well as anything involving multi-threading or shared memory IPC. Stick to hosted systems, and use the OS's primitives here - they will include the required memory barriers. Those of us who do use C successfully for low-level, hardware interacting routines understand what the compiler can and cannot do here, and use appropriate methods to make the code correct. Often, that will be implementation-dependent (such as a memory barrier), or more use of "volatile". It is not problematic - it's just a matter of knowing what you are doing. And this is not hypothetical - compilers /do/ rearrange code, and move ordinary data accesses back and forth across volatile accesses. >
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-29 15:17 +0200 |
| Message-ID | <nq1cm3$m0i$1@dont-email.me> |
| In reply to | #92696 |
On 25/08/16 16:29, supercat@casperkitty.com wrote: > On Thursday, August 25, 2016 at 1:38:28 AM UTC-5, Malcolm McLean wrote: >> Once you've locked the buffer, it is of course no longer volatile. > > Since many freestanding implementations of C generally won't support the > C11 threading extensions (since that would require that the implementation > be much heavier weight than one which lets programmers operate on bare > metal), by what standard means would you suggest that programmers tell the > compiler that something is locked? > > One of the things that made C useful for embedded systems was that a > programmer who was familiar with a hardware platform could pretty well > guess what needed to be written in C to access it. If a platform has > a uniform linear addressing space and one wants to write a 32-bit word > 0xCAFEBABE to address 0xABCD1234, a non-oddball implementation for that > platform will allow that to be accomplished via > > * ((uint32_t volatile*)0xABCD1234) = 0xCAFEBABE; > > If a compiler treats volatile variables as memory barriers, then code > which ensures that compiler-produced accesses to a variable will be > separated from other accesses by volatile I/O can work correctly without > having to use any further language extensions. > That would be true - /if/ compilers treated volatile accesses as memory barriers. Most compilers don't do that. The only compilers I know that guaranteed such a "feature" did so because they had very poor optimisation and basically considered /all/ memory accesses to be volatile. Please stop dreaming about a compiler past that never existed - or at least, stop posting about it. You don't help anyone.
[toc] | [prev] | [next] | [standalone]
| From | already5chosen@yahoo.com |
|---|---|
| Date | 2016-08-29 06:47 -0700 |
| Message-ID | <f469d2d7-b945-4f7c-a087-9ef5fce66335@googlegroups.com> |
| In reply to | #92856 |
On Monday, August 29, 2016 at 4:18:03 PM UTC+3, David Brown wrote: > On 25/08/16 16:29, supercat@casperkitty.com wrote: > > On Thursday, August 25, 2016 at 1:38:28 AM UTC-5, Malcolm McLean wrote: > >> Once you've locked the buffer, it is of course no longer volatile. > > > > Since many freestanding implementations of C generally won't support the > > C11 threading extensions (since that would require that the implementation > > be much heavier weight than one which lets programmers operate on bare > > metal), by what standard means would you suggest that programmers tell the > > compiler that something is locked? > > > > One of the things that made C useful for embedded systems was that a > > programmer who was familiar with a hardware platform could pretty well > > guess what needed to be written in C to access it. If a platform has > > a uniform linear addressing space and one wants to write a 32-bit word > > 0xCAFEBABE to address 0xABCD1234, a non-oddball implementation for that > > platform will allow that to be accomplished via > > > > * ((uint32_t volatile*)0xABCD1234) = 0xCAFEBABE; > > > > If a compiler treats volatile variables as memory barriers, then code > > which ensures that compiler-produced accesses to a variable will be > > separated from other accesses by volatile I/O can work correctly without > > having to use any further language extensions. > > > > That would be true - /if/ compilers treated volatile accesses as memory > barriers. Most compilers don't do that. The only compilers I know that > guaranteed such a "feature" did so because they had very poor > optimisation and basically considered /all/ memory accesses to be volatile. > > Please stop dreaming about a compiler past that never existed - or at > least, stop posting about it. You don't help anyone. You mean, you had seen production compiler that reorders non-const non-volatile accesses across volatile? Care to post code snippet and compiler output?
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-29 16:58 +0200 |
| Message-ID | <nq1iio$iv3$1@dont-email.me> |
| In reply to | #92863 |
On 29/08/16 15:47, already5chosen@yahoo.com wrote:
> On Monday, August 29, 2016 at 4:18:03 PM UTC+3, David Brown wrote:
>> On 25/08/16 16:29, supercat@casperkitty.com wrote:
>>> On Thursday, August 25, 2016 at 1:38:28 AM UTC-5, Malcolm McLean wrote:
>>>> Once you've locked the buffer, it is of course no longer volatile.
>>>
>>> Since many freestanding implementations of C generally won't support the
>>> C11 threading extensions (since that would require that the implementation
>>> be much heavier weight than one which lets programmers operate on bare
>>> metal), by what standard means would you suggest that programmers tell the
>>> compiler that something is locked?
>>>
>>> One of the things that made C useful for embedded systems was that a
>>> programmer who was familiar with a hardware platform could pretty well
>>> guess what needed to be written in C to access it. If a platform has
>>> a uniform linear addressing space and one wants to write a 32-bit word
>>> 0xCAFEBABE to address 0xABCD1234, a non-oddball implementation for that
>>> platform will allow that to be accomplished via
>>>
>>> * ((uint32_t volatile*)0xABCD1234) = 0xCAFEBABE;
>>>
>>> If a compiler treats volatile variables as memory barriers, then code
>>> which ensures that compiler-produced accesses to a variable will be
>>> separated from other accesses by volatile I/O can work correctly without
>>> having to use any further language extensions.
>>>
>>
>> That would be true - /if/ compilers treated volatile accesses as memory
>> barriers. Most compilers don't do that. The only compilers I know that
>> guaranteed such a "feature" did so because they had very poor
>> optimisation and basically considered /all/ memory accesses to be volatile.
>>
>> Please stop dreaming about a compiler past that never existed - or at
>> least, stop posting about it. You don't help anyone.
>
> You mean, you had seen production compiler that reorders non-const non-volatile accesses across volatile?
> Care to post code snippet and compiler output?
>
gcc does it all the time - if it makes sense from an optimisation
viewpoint. Supercat's example from another post does this:
#include <stdint.h>
unsigned char foo;
volatile unsigned char bar;
int test(void) {
foo = 0;
for (int i = 0; i <= 10; i++) foo += i;
bar = 1;
while (bar);
foo++;
return foo;
}
<http://gcc.godbolt.org/#>
Give it a shot with various compiler versions, and at least -O2
optimisation.
[toc] | [prev] | [next] | [standalone]
| From | already5chosen@yahoo.com |
|---|---|
| Date | 2016-08-29 09:09 -0700 |
| Message-ID | <5b2081c7-b641-4ca8-82d2-1528cf6d6107@googlegroups.com> |
| In reply to | #92870 |
On Monday, August 29, 2016 at 5:58:40 PM UTC+3, David Brown wrote:
> On 29/08/16 15:47, already5chosen@yahoo.com wrote:
> > On Monday, August 29, 2016 at 4:18:03 PM UTC+3, David Brown wrote:
> >> On 25/08/16 16:29, supercat@casperkitty.com wrote:
> >>> On Thursday, August 25, 2016 at 1:38:28 AM UTC-5, Malcolm McLean wrote:
> >>>> Once you've locked the buffer, it is of course no longer volatile.
> >>>
> >>> Since many freestanding implementations of C generally won't support the
> >>> C11 threading extensions (since that would require that the implementation
> >>> be much heavier weight than one which lets programmers operate on bare
> >>> metal), by what standard means would you suggest that programmers tell the
> >>> compiler that something is locked?
> >>>
> >>> One of the things that made C useful for embedded systems was that a
> >>> programmer who was familiar with a hardware platform could pretty well
> >>> guess what needed to be written in C to access it. If a platform has
> >>> a uniform linear addressing space and one wants to write a 32-bit word
> >>> 0xCAFEBABE to address 0xABCD1234, a non-oddball implementation for that
> >>> platform will allow that to be accomplished via
> >>>
> >>> * ((uint32_t volatile*)0xABCD1234) = 0xCAFEBABE;
> >>>
> >>> If a compiler treats volatile variables as memory barriers, then code
> >>> which ensures that compiler-produced accesses to a variable will be
> >>> separated from other accesses by volatile I/O can work correctly without
> >>> having to use any further language extensions.
> >>>
> >>
> >> That would be true - /if/ compilers treated volatile accesses as memory
> >> barriers. Most compilers don't do that. The only compilers I know that
> >> guaranteed such a "feature" did so because they had very poor
> >> optimisation and basically considered /all/ memory accesses to be volatile.
> >>
> >> Please stop dreaming about a compiler past that never existed - or at
> >> least, stop posting about it. You don't help anyone.
> >
> > You mean, you had seen production compiler that reorders non-const non-volatile accesses across volatile?
> > Care to post code snippet and compiler output?
> >
>
> gcc does it all the time - if it makes sense from an optimisation
> viewpoint. Supercat's example from another post does this:
>
> #include <stdint.h>
>
> unsigned char foo;
> volatile unsigned char bar;
>
> int test(void) {
> foo = 0;
> for (int i = 0; i <= 10; i++) foo += i;
> bar = 1;
> while (bar);
> foo++;
> return foo;
> }
>
>
> <http://gcc.godbolt.org/#>
>
> Give it a shot with various compiler versions, and at least -O2
> optimisation.
O.k. I see.
But it seems compiler never moves stores across volatile without good reason, like, like in case above, when the non-volatile location overwritten soon thereafter.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-29 23:16 +0200 |
| Message-ID | <nq28nl$9fn$2@dont-email.me> |
| In reply to | #92874 |
On 29/08/16 18:09, already5chosen@yahoo.com wrote:
> On Monday, August 29, 2016 at 5:58:40 PM UTC+3, David Brown wrote:
>> On 29/08/16 15:47, already5chosen@yahoo.com wrote:
>>> On Monday, August 29, 2016 at 4:18:03 PM UTC+3, David Brown
>>> wrote:
>>>> On 25/08/16 16:29, supercat@casperkitty.com wrote:
>>>>> On Thursday, August 25, 2016 at 1:38:28 AM UTC-5, Malcolm
>>>>> McLean wrote:
>>>>>> Once you've locked the buffer, it is of course no longer
>>>>>> volatile.
>>>>>
>>>>> Since many freestanding implementations of C generally won't
>>>>> support the C11 threading extensions (since that would
>>>>> require that the implementation be much heavier weight than
>>>>> one which lets programmers operate on bare metal), by what
>>>>> standard means would you suggest that programmers tell the
>>>>> compiler that something is locked?
>>>>>
>>>>> One of the things that made C useful for embedded systems was
>>>>> that a programmer who was familiar with a hardware platform
>>>>> could pretty well guess what needed to be written in C to
>>>>> access it. If a platform has a uniform linear addressing
>>>>> space and one wants to write a 32-bit word 0xCAFEBABE to
>>>>> address 0xABCD1234, a non-oddball implementation for that
>>>>> platform will allow that to be accomplished via
>>>>>
>>>>> * ((uint32_t volatile*)0xABCD1234) = 0xCAFEBABE;
>>>>>
>>>>> If a compiler treats volatile variables as memory barriers,
>>>>> then code which ensures that compiler-produced accesses to a
>>>>> variable will be separated from other accesses by volatile
>>>>> I/O can work correctly without having to use any further
>>>>> language extensions.
>>>>>
>>>>
>>>> That would be true - /if/ compilers treated volatile accesses
>>>> as memory barriers. Most compilers don't do that. The only
>>>> compilers I know that guaranteed such a "feature" did so
>>>> because they had very poor optimisation and basically
>>>> considered /all/ memory accesses to be volatile.
>>>>
>>>> Please stop dreaming about a compiler past that never existed -
>>>> or at least, stop posting about it. You don't help anyone.
>>>
>>> You mean, you had seen production compiler that reorders
>>> non-const non-volatile accesses across volatile? Care to post
>>> code snippet and compiler output?
>>>
>>
>> gcc does it all the time - if it makes sense from an optimisation
>> viewpoint. Supercat's example from another post does this:
>>
>> #include <stdint.h>
>>
>> unsigned char foo; volatile unsigned char bar;
>>
>> int test(void) { foo = 0; for (int i = 0; i <= 10; i++) foo += i;
>> bar = 1; while (bar); foo++; return foo; }
>>
>>
>> <http://gcc.godbolt.org/#>
>>
>> Give it a shot with various compiler versions, and at least -O2
>> optimisation.
>
> O.k. I see. But it seems compiler never moves stores across volatile
> without good reason, like, like in case above, when the non-volatile
> location overwritten soon thereafter.
>
Compilers don't usually move /anything/ without good reason. It is
easier for people to understand generated assembly code if it follows
the pattern of the source code. And keeping data around longer than
necessary uses up valuable registers. But if the compiler /does/ have
good reason to move loads or stores, or to remove them completely, then
a good compiler will do so - with a total disregard for ordering of
non-volatile accesses with respect to volatile accesses.
[toc] | [prev] | [next] | [standalone]
| From | already5chosen@yahoo.com |
|---|---|
| Date | 2016-08-31 02:02 -0700 |
| Message-ID | <ebcae815-f5aa-40fb-86ab-91438ba490e4@googlegroups.com> |
| In reply to | #92906 |
On Tuesday, August 30, 2016 at 12:16:44 AM UTC+3, David Brown wrote:
> On 29/08/16 18:09, already5chosen@yahoo.com wrote:
> > On Monday, August 29, 2016 at 5:58:40 PM UTC+3, David Brown wrote:
> >> On 29/08/16 15:47, already5chosen@yahoo.com wrote:
> >>>
> >>> You mean, you had seen production compiler that reorders
> >>> non-const non-volatile accesses across volatile? Care to post
> >>> code snippet and compiler output?
> >>>
> >>
> >> gcc does it all the time - if it makes sense from an optimisation
> >> viewpoint. Supercat's example from another post does this:
> >>
> >> #include <stdint.h>
> >>
> >> unsigned char foo; volatile unsigned char bar;
> >>
> >> int test(void) { foo = 0; for (int i = 0; i <= 10; i++) foo += i;
> >> bar = 1; while (bar); foo++; return foo; }
> >>
> >>
> >> <http://gcc.godbolt.org/#>
> >>
> >> Give it a shot with various compiler versions, and at least -O2
> >> optimisation.
> >
> > O.k. I see. But it seems compiler never moves stores across volatile
> > without good reason, like, like in case above, when the non-volatile
> > location overwritten soon thereafter.
> >
>
> Compilers don't usually move /anything/ without good reason. It is
> easier for people to understand generated assembly code if it follows
> the pattern of the source code. And keeping data around longer than
> necessary uses up valuable registers. But if the compiler /does/ have
> good reason to move loads or stores, or to remove them completely, then
> a good compiler will do so - with a total disregard for ordering of
> non-volatile accesses with respect to volatile accesses.
What is a *good* compiler is a matter of opinion.
My opinion is that, other things being equal, less surprising compiler is better than more surprising. So, as far as I am concerned, the fact that gcc reorders non-volatile global accesses across volatile accesses makes it less good than, for example, Microsoft Visual C/C++ (from VS2013) that, according to my tests, never does it.
Proponents of this and of similar surprising optimizations often say that they improve performance. It seems to me that comparison of Microsoft Visual C vs gcc (about the same performance for majority of non-trivial 'C' software) is a good hint that it is not a case.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-31 12:49 +0200 |
| Message-ID | <nq6co3$8qn$1@dont-email.me> |
| In reply to | #92979 |
On 31/08/16 11:02, already5chosen@yahoo.com wrote:
> On Tuesday, August 30, 2016 at 12:16:44 AM UTC+3, David Brown wrote:
>> On 29/08/16 18:09, already5chosen@yahoo.com wrote:
>>> On Monday, August 29, 2016 at 5:58:40 PM UTC+3, David Brown wrote:
>>>> On 29/08/16 15:47, already5chosen@yahoo.com wrote:
>>>>>
>>>>> You mean, you had seen production compiler that reorders
>>>>> non-const non-volatile accesses across volatile? Care to post
>>>>> code snippet and compiler output?
>>>>>
>>>>
>>>> gcc does it all the time - if it makes sense from an optimisation
>>>> viewpoint. Supercat's example from another post does this:
>>>>
>>>> #include <stdint.h>
>>>>
>>>> unsigned char foo; volatile unsigned char bar;
>>>>
>>>> int test(void) { foo = 0; for (int i = 0; i <= 10; i++) foo += i;
>>>> bar = 1; while (bar); foo++; return foo; }
>>>>
>>>>
>>>> <http://gcc.godbolt.org/#>
>>>>
>>>> Give it a shot with various compiler versions, and at least -O2
>>>> optimisation.
>>>
>>> O.k. I see. But it seems compiler never moves stores across volatile
>>> without good reason, like, like in case above, when the non-volatile
>>> location overwritten soon thereafter.
>>>
>>
>> Compilers don't usually move /anything/ without good reason. It is
>> easier for people to understand generated assembly code if it follows
>> the pattern of the source code. And keeping data around longer than
>> necessary uses up valuable registers. But if the compiler /does/ have
>> good reason to move loads or stores, or to remove them completely, then
>> a good compiler will do so - with a total disregard for ordering of
>> non-volatile accesses with respect to volatile accesses.
>
> What is a *good* compiler is a matter of opinion.
True.
It might have been better to say "a highly optimising compiler" rather
than a "good compiler".
>
> My opinion is that, other things being equal, less surprising
> compiler is better than more surprising.
Agreed.
> So, as far as I am
> concerned, the fact that gcc reorders non-volatile global accesses
> across volatile accesses makes it less good than, for example,
> Microsoft Visual C/C++ (from VS2013) that, according to my tests,
> never does it.
I disagree (though of course you can pick your own meaning for "good").
gcc will leave the ordering unchanged when all other things are equal
(avoiding surprises, which is good). But if other things are /not/
equal, and you have asked for heavy optimisation, then the compiler will
re-arrange code and re-schedule instructions in order to generate
smaller and/or faster code. To my mind, that is "good" - but only when
the programmer understands that such re-arrangement is allowed. Then
the re-arrangement is not surprising - though it might be a pain for
some kinds of debugging.
> Proponents of this and of similar surprising
> optimizations often say that they improve performance. It seems to me
> that comparison of Microsoft Visual C vs gcc (about the same
> performance for majority of non-trivial 'C' software) is a good hint
> that it is not a case.
>
MSVC is better at some kinds of optimisation than gcc, and worse at
others. You can't tell the effect of any particular optimisation by
looking at rough average figures - the final result is the sum of many
drops. And you certainly can't tell anything from an optimisation that
affects the kind of code you would almost never see in MSVC-compiled
code, unless you were doing Windows driver development - volatile
accesses are rare in application level code.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-31 09:02 -0700 |
| Message-ID | <2cc150ea-ca3e-4f38-b17d-137b3c528b67@googlegroups.com> |
| In reply to | #92983 |
On Wednesday, August 31, 2016 at 5:49:49 AM UTC-5, David Brown wrote: > I disagree (though of course you can pick your own meaning for "good"). > > gcc will leave the ordering unchanged when all other things are equal > (avoiding surprises, which is good). But if other things are /not/ > equal, and you have asked for heavy optimisation, then the compiler will > re-arrange code and re-schedule instructions in order to generate > smaller and/or faster code. To my mind, that is "good" - but only when > the programmer understands that such re-arrangement is allowed. Then > the re-arrangement is not surprising - though it might be a pain for > some kinds of debugging. The question is whether should be possible to achieve correct performance without having to either rely upon compiler-specific extensions, write code in such a fashion as to block many optimizations that would be useful and safe, or write code in excessively verbose fashion. If there are variables which may be written in any order provided that all writes are completed before a particular volatile write is performed, which will be most efficient: 1. Have the programmer qualify everything "volatile", so that the compiler would be forbidden from reordering any of the operations on those variables even when doing so could safely improve performance. 2. Have the programmer use an option to force the compiler to do all loads and stores of any object whose address is "visible" in strict sequence. 3. Have the programmer use "volatile" qualifiers on the things which need to be treated as having ordering barriers around them, and then plan on using whatever options are necessary to provide such semantics. Code will then be able to run efficiently on compilers with options which can treat volatile operations as strictly sequenced relative to everything else without having to force everything to be executed in strict sequence. I would suggest that #1 will guarantee sub-optimal performance on any compiler. Approach #3 would seem like the best approach which does not rely upon language extensions. It may be possible to combine the approaches #1 and #3 by #define'ing a macro "quasivolatile" as either "volatile" or nothing depending upon whether a compiler can be made to respect ordering barriers without making everything "volatile", but I'm not sure what real advantages that has over requiring that the code be compiled with options that will force the compiler to honor the memory barriers, even if that means restricting what should have been useful optimizations.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-25 10:31 +0200 |
| Message-ID | <npmadt$7q1$1@dont-email.me> |
| In reply to | #92691 |
On 25/08/16 07:28, supercat@casperkitty.com wrote:
> On Wednesday, August 24, 2016 at 6:28:07 PM UTC-5, David Brown wrote:
>> I don't know what embedded compilers /you/ have been using, but I have
>> been using ones that do "aggressive optimisations" such as type-based
>> alias analysis for 20+ years.
>
> Got some names? How aggressively did they do type-based analysis, and to
> what extent did they try to recognize indications that aliasing was likely?
Diab Data was one I remember from that age (it's now owned by Wind
River, which is in turn owned by Intel).
> Given a construct like:
>
> void set_lower_half_to_0x8000(uint32_t *n)
> {
> ((uint16_t*)n)[IS_BIG_ENDIAN] = 0x8000;
> }
I would not write such code - not even 20 years ago - so I can't say for
sure.
>
> would the compilers of 20 years ago assume that the method would only be
> called with the addresses of uint16_t objects, or would they recognize
> that the code is modifying something that has been identified with a
> pointer of type uint32_t, and thus is likely modifying something of type
> uint32_t?
>
> How do the compilers you use regard the relative sequencing of volatile-
> qualified and non-volatile-qualified operations? If volatile accesses
> aren't treated as memory barriers, how would you handle something like
> copying arbitrary-type data to a buffer and then starting a DMA transfer?
Volatile access are not, and never have been, memory barriers. If you
think compilers sequence non-volatile and volatile operations, then you
are simply wrong. You are not alone in this - it's a mistake many
people have made - but you are wrong. And if you think older compilers
guaranteed something different, then you are /very/ wrong.
How do you make sure your buffer transfers are sequenced correctly with
respect to the volatile transfers? You have three options:
1. Use volatile accesses when doing the buffer transfers. Since you
will be copying the data anyway, you are not going to lose efficiency.
Note that "what constitutes a volatile access is implementation defined"
- but most (probably all) compilers define simple and direct volatile
reads and writes in the obvious way.
2. Use a memory barrier. This has traditionally been
implementation-dependent, such as "asm volatile("" ::: "memory")" for
gcc. With C11, "atomic_thread_fence(memory_order_seq_cst)" should do
the job.
3. Use a more limited compiler, or artificially limit your compiler by
using low optimisation options or other flags.
> There is no standard library version of "memcpy" which uses volatile-
> qualified pointers, and copying data one byte at a time is apt to be
> sufficiently slow as to negate much of the speed benefit from using DMA
> in the first place.
>
memcpy is not volatile - that is certainly true. But often it does not
copy bytes at a time - a good compiler will inline faster copying loops
if it can see the size of the copy and it knows the alignments of the
source and destination. Library versions will also often try to copy in
larger sizes than single bytes.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-25 10:01 -0700 |
| Message-ID | <fef308cd-639f-4906-815d-7803a8045c15@googlegroups.com> |
| In reply to | #92693 |
On Thursday, August 25, 2016 at 3:32:07 AM UTC-5, David Brown wrote:
> Diab Data was one I remember from that age (it's now owned by Wind
> River, which is in turn owned by Intel).
Never heard of it, but I'd be interested to know more. What was the
target platform?
> > Given a construct like:
> >
> > void set_lower_half_to_0x8000(uint32_t *n)
> > {
> > ((uint16_t*)n)[IS_BIG_ENDIAN] = 0x8000;
> > }
>
> I would not write such code - not even 20 years ago - so I can't say for
> sure.
The particular example was contrived to ask what a compiler would do with
it, but the need to process bunches of bits in various size groups comes
up a lot in some kinds of code (e.g. bitmap graphics). If you have e.g.
a bitmap screen upon which it's necessary to draw 16-bit-wide tiles on
16-bit boundaries and 32-bit-wide tiles on 32-bit boundaries, how would
you do that efficiently in a fashion consistent with C's rules?
IMHO, the Standard really needs to add "compiler" memory barriers; any
implementation should be able to uphold the guarantees they would imply,
and almost any implementation would have to be able to in order to uphold
the semantics of something like:
unsigned char barrier_dummy;
unsigned char volatile * volatile barrier_dummy_ptr = &barrier_dummy;
void volatile * volatile barrier_dummy_ptr2;
void memory_barrier(void *x)
{
barrier_dummy_ptr2=x;
*barrier_dummy_ptr += 1;
}
Unless an implementation could know everything about the volatile
variables, it would have to presume that storing any address to
barrier_dummy_ptr2 could cause barrier_dummy to hold any address
which differed by a fixed displacement; if that occurred, the
aliasing rules would require that a compiler recognize the aliasing
between *barrier_dummy_pointer and the object whose address appeared
there. A compiler could in theory generate code to test whether
barrier_dummy_ptr had changed and skip the memory barrier if it hadn't,
but it seems doubtful that such behavior would improve efficiency.
Of course, generating all the code for the above when a memory barrier
is required would be horrendously inefficient, but any implementation
which has any volatile locations outside its control would need to be
able to handle memory barriers at the compiler level (even if they
simply had no effect), so I see nothing to be gained by not having
a standard means by which code could forbid the compiler from moving
accesses to any lvalues associated with a pointer across a certain point
in the code.
> How do you make sure your buffer transfers are sequenced correctly with
> respect to the volatile transfers? You have three options:
>
> 1. Use volatile accesses when doing the buffer transfers. Since you
> will be copying the data anyway, you are not going to lose efficiency.
> Note that "what constitutes a volatile access is implementation defined"
> - but most (probably all) compilers define simple and direct volatile
> reads and writes in the obvious way.
If the buffer may contain data of arbitrary types, do you do the transfers
a byte at a time? If the source pointer will usually be word aligned, that
would seem to imply at least a 4x performance hit.
> 2. Use a memory barrier. This has traditionally been
> implementation-dependent, such as "asm volatile("" ::: "memory")" for
> gcc. With C11, "atomic_thread_fence(memory_order_seq_cst)" should do
> the job.
By my understanding, C11 can only offer that if it includes aspects of
threading which requires a higher level of OS integration than many
freestanding implementations would support.
> 3. Use a more limited compiler, or artificially limit your compiler by
> using low optimisation options or other flags.
What should be the right approach would be to have standardized targeted
ways of preventing breaking "optimizations". Otherwise, disabling such
optimizations with a sledge hammer will have some performance cost, but
depending upon the application that cost may be less than the cost of
foregoing efficient techniques that a platform would support but the
Standard doesn't.
> > There is no standard library version of "memcpy" which uses volatile-
> > qualified pointers, and copying data one byte at a time is apt to be
> > sufficiently slow as to negate much of the speed benefit from using DMA
> > in the first place.
> >
>
> memcpy is not volatile - that is certainly true. But often it does not
> copy bytes at a time - a good compiler will inline faster copying loops
> if it can see the size of the copy and it knows the alignments of the
> source and destination. Library versions will also often try to copy in
> larger sizes than single bytes.
Of course memcpy is optimized. The problem is that unless one wants to use
a compiler-specific extension to do something no compiler should have any
problem supporting, one can't use memcpy on buffers which are going to be
accessed asynchronously, even if a volatile action would separate the memcpy
from any time when external accesses could occur.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-29 16:24 +0200 |
| Message-ID | <nq1gip$7p0$1@dont-email.me> |
| In reply to | #92700 |
On 25/08/16 19:01, supercat@casperkitty.com wrote:
> On Thursday, August 25, 2016 at 3:32:07 AM UTC-5, David Brown wrote:
>> Diab Data was one I remember from that age (it's now owned by Wind
>> River, which is in turn owned by Intel).
>
> Never heard of it, but I'd be interested to know more. What was the
> target platform?
I evaluated it for the 68k, but they supported a range of targets.
>> How do you make sure your buffer transfers are sequenced correctly with
>> respect to the volatile transfers? You have three options:
>>
>> 1. Use volatile accesses when doing the buffer transfers. Since you
>> will be copying the data anyway, you are not going to lose efficiency.
>> Note that "what constitutes a volatile access is implementation defined"
>> - but most (probably all) compilers define simple and direct volatile
>> reads and writes in the obvious way.
>
> If the buffer may contain data of arbitrary types, do you do the transfers
> a byte at a time? If the source pointer will usually be word aligned, that
> would seem to imply at least a 4x performance hit.
Use the transfer sizes you want. With volatile accesses, you don't have
the same concerns about type-based aliasing optimisations that keep you
awake at night. (But remember that any non-volatile stores a variable
are not ordered with respect to volatile accesses of the same variable.)
>
>> 2. Use a memory barrier. This has traditionally been
>> implementation-dependent, such as "asm volatile("" ::: "memory")" for
>> gcc. With C11, "atomic_thread_fence(memory_order_seq_cst)" should do
>> the job.
>
> By my understanding, C11 can only offer that if it includes aspects of
> threading which requires a higher level of OS integration than many
> freestanding implementations would support.
I haven't looked into details of C11 threading implementations as yet.
All the compilers I use have a simple memory barrier implementation.
>
>> 3. Use a more limited compiler, or artificially limit your compiler by
>> using low optimisation options or other flags.
>
> What should be the right approach would be to have standardized targeted
> ways of preventing breaking "optimizations". Otherwise, disabling such
> optimizations with a sledge hammer will have some performance cost, but
> depending upon the application that cost may be less than the cost of
> foregoing efficient techniques that a platform would support but the
> Standard doesn't.
The standard /does/ have an appropriate way to do this - use "volatile"
and the C11 atomics appropriately. Just because implementations have
not all caught up with C11 atomics yet does not mean it would be a good
idea to invent new "standardised" methods.
>
>>> There is no standard library version of "memcpy" which uses volatile-
>>> qualified pointers, and copying data one byte at a time is apt to be
>>> sufficiently slow as to negate much of the speed benefit from using DMA
>>> in the first place.
>>>
>>
>> memcpy is not volatile - that is certainly true. But often it does not
>> copy bytes at a time - a good compiler will inline faster copying loops
>> if it can see the size of the copy and it knows the alignments of the
>> source and destination. Library versions will also often try to copy in
>> larger sizes than single bytes.
>
> Of course memcpy is optimized. The problem is that unless one wants to use
> a compiler-specific extension to do something no compiler should have any
> problem supporting, one can't use memcpy on buffers which are going to be
> accessed asynchronously, even if a volatile action would separate the memcpy
> from any time when external accesses could occur.
>
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-29 10:43 -0700 |
| Message-ID | <3913d87e-6204-437d-b9ac-7db30be5d60d@googlegroups.com> |
| In reply to | #92868 |
On Monday, August 29, 2016 at 9:24:39 AM UTC-5, David Brown wrote:
> Use the transfer sizes you want. With volatile accesses, you don't have
> the same concerns about type-based aliasing optimisations that keep you
> awake at night. (But remember that any non-volatile stores a variable
> are not ordered with respect to volatile accesses of the same variable.)
The goal is a function with an API:
void begin_write(OUTPUT_DEVICE *device, void *data, int size);
which can accept source data of any type and does not require that the
buffer be volatile-qualified, provided that code refrains from using
the buffer until a call to device_busy(OUTPUT_DEVICE *device) returns
0.
If the source data is sometimes of type "float[]", sometimes "uint32_t*",
sometimes uin64_t*', etc. I see no reason to believe that an access of type
"volatile uint64_t*" would be guaranteed to see it if a compiler is willing
to reorder operations on non-qualified objects across operations on volatile-
qualified ones.
I think the fastest approach without using compiler-specific directives
or extensions would probably be to use "memcpy" to copy the data to a
"uint64_t[]", and then from there use a loop to copy it to a "volatile
uint64_t[]". Of course, that would require asking for two copy operations
in code, at most one of which a compiler would be able to optimize out,
and would also require having two extra buffers, one of which would need
to remain allocated for the duration of the operation.
That doesn't seem like a recipe for optimization to me. Is there any
reason why it shouldn't be possible to such a function efficiently without
relying upon any *compiler*-specific features (obviously it would depend
upon DMA hardware, but that's to be expected). What is the advantage of
having compilers require the use of compiler-specific directives to get
reliable operation from code that uses hardware efficiently, versus having
a default behavior which favors correctness and possibly using compiler-
specific means of enabling extra optimizations in cases where they are
known to be "safe"?
> >> 2. Use a memory barrier. This has traditionally been
> >> implementation-dependent, such as "asm volatile("" ::: "memory")" for
> >> gcc. With C11, "atomic_thread_fence(memory_order_seq_cst)" should do
> >> the job.
> >
> > By my understanding, C11 can only offer that if it includes aspects of
> > threading which requires a higher level of OS integration than many
> > freestanding implementations would support.
>
> I haven't looked into details of C11 threading implementations as yet.
> All the compilers I use have a simple memory barrier implementation.
> The standard /does/ have an appropriate way to do this - use "volatile"
> and the C11 atomics appropriately. Just because implementations have
> not all caught up with C11 atomics yet does not mean it would be a good
> idea to invent new "standardised" methods.
There are a number of libraries that implement functions like the above
"begin_write". Do you believe that anything close to all of them include
all the necessary memory barriers? A lot of such code was written at a
time where the likelihood of a compiler finding a breaking optimization
would have been just about nil, and when compiler writers didn't feel any
need to define directives to prevent them from doing things they wouldn't
even think of doing anyway. Treating "volatile" accesses as barriers
against compiler memory reordering would ensure that such code--that may
have functioned reliably for years--would continue to function reliably.
Such a change may mean that code which doesn't use "restrict" or other
optimization directives won't run as fast, but the solution to that is to
add such directives where applicable in cases where they're known to be
"safe".
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-08-29 23:29 +0200 |
| Message-ID | <nq29ff$cbb$1@dont-email.me> |
| In reply to | #92887 |
On 29/08/16 19:43, supercat@casperkitty.com wrote:
> On Monday, August 29, 2016 at 9:24:39 AM UTC-5, David Brown wrote:
>> Use the transfer sizes you want. With volatile accesses, you don't have
>> the same concerns about type-based aliasing optimisations that keep you
>> awake at night. (But remember that any non-volatile stores a variable
>> are not ordered with respect to volatile accesses of the same variable.)
>
> The goal is a function with an API:
>
> void begin_write(OUTPUT_DEVICE *device, void *data, int size);
>
> which can accept source data of any type and does not require that the
> buffer be volatile-qualified, provided that code refrains from using
> the buffer until a call to device_busy(OUTPUT_DEVICE *device) returns
> 0.
>
> If the source data is sometimes of type "float[]", sometimes "uint32_t*",
> sometimes uin64_t*', etc. I see no reason to believe that an access of type
> "volatile uint64_t*" would be guaranteed to see it if a compiler is willing
> to reorder operations on non-qualified objects across operations on volatile-
> qualified ones.
>
> I think the fastest approach without using compiler-specific directives
> or extensions would probably be to use "memcpy" to copy the data to a
> "uint64_t[]", and then from there use a loop to copy it to a "volatile
> uint64_t[]". Of course, that would require asking for two copy operations
> in code, at most one of which a compiler would be able to optimize out,
> and would also require having two extra buffers, one of which would need
> to remain allocated for the duration of the operation.
>
Just put in the implementation-specific bits that are needed - or accept
that the generic fully portable may not be optimal for all targets.
That's the way other people write code.
This is low-level code. It is going to be target-specific anyway!
> That doesn't seem like a recipe for optimization to me. Is there any
> reason why it shouldn't be possible to such a function efficiently without
> relying upon any *compiler*-specific features (obviously it would depend
> upon DMA hardware, but that's to be expected). What is the advantage of
> having compilers require the use of compiler-specific directives to get
> reliable operation from code that uses hardware efficiently, versus having
> a default behavior which favors correctness and possibly using compiler-
> specific means of enabling extra optimizations in cases where they are
> known to be "safe"?
>
>>>> 2. Use a memory barrier. This has traditionally been
>>>> implementation-dependent, such as "asm volatile("" ::: "memory")" for
>>>> gcc. With C11, "atomic_thread_fence(memory_order_seq_cst)" should do
>>>> the job.
>>>
>>> By my understanding, C11 can only offer that if it includes aspects of
>>> threading which requires a higher level of OS integration than many
>>> freestanding implementations would support.
>>
>> I haven't looked into details of C11 threading implementations as yet.
>> All the compilers I use have a simple memory barrier implementation.
>
>> The standard /does/ have an appropriate way to do this - use "volatile"
>> and the C11 atomics appropriately. Just because implementations have
>> not all caught up with C11 atomics yet does not mean it would be a good
>> idea to invent new "standardised" methods.
>
> There are a number of libraries that implement functions like the above
> "begin_write". Do you believe that anything close to all of them include
> all the necessary memory barriers? A lot of such code was written at a
> time where the likelihood of a compiler finding a breaking optimization
> would have been just about nil, and when compiler writers didn't feel any
> need to define directives to prevent them from doing things they wouldn't
> even think of doing anyway. Treating "volatile" accesses as barriers
> against compiler memory reordering would ensure that such code--that may
> have functioned reliably for years--would continue to function reliably.
> Such a change may mean that code which doesn't use "restrict" or other
> optimization directives won't run as fast, but the solution to that is to
> add such directives where applicable in cases where they're known to be
> "safe".
>
If you want most of the code to be portable and efficient, you do as
other people do - make a "system.h" or "target.h" header file containing
macros for things like compiler/memory barriers. Perhaps the header
will have a bunch of pre-processor conditionals that identify typical
compilers and targets, or perhaps it is left to the code user to fill in
the necessary parts.
[toc] | [prev] | [next] | [standalone]
Page 16 of 18 — ← Prev page 1 … 14 15 [16] 17 18 Next page →
Back to top | Article view | comp.lang.c
csiph-web