Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #24329 > unrolled thread

Common name for a "Task Loop"

Started byTim Wescott <seemywebsite@myfooter.really>
First post2016-06-24 13:37 -0500
Last post2016-07-14 20:44 +0000
Articles 20 on this page of 196 — 27 participants

Back to article view | Back to comp.arch.embedded


Contents

  Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-24 13:37 -0500
    Re: Common name for a "Task Loop" Lanarcam <lanarcam1@yahoo.fr> - 2016-06-24 21:04 +0200
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-24 15:21 -0500
    Re: Common name for a "Task Loop" Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2016-06-24 22:46 +0300
    Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-24 14:51 -0500
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-24 15:10 -0500
    Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-24 20:11 +0000
      Re: Common name for a "Task Loop" gtwrek@sonic.net (Mark Curry) - 2016-06-24 20:31 +0000
    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-24 13:21 -0700
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-24 18:31 -0500
        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-24 17:03 -0700
          Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-25 10:52 +0300
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 01:07 -0700
              Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-25 14:00 +0300
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 08:27 -0700
                  Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-25 15:50 -0500
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 14:45 -0700
                      Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-25 17:28 -0500
                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 00:40 -0700
                      Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 12:41 +0300
              Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-25 15:46 -0500
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 14:42 -0700
          Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-25 15:43 -0500
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 14:36 -0700
              Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-25 17:25 -0500
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 00:14 -0700
    Re: Common name for a "Task Loop" Paul Rubin <no.email@nospam.invalid> - 2016-06-24 14:00 -0700
      Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-25 15:27 +0000
        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 09:41 -0700
          Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-25 17:59 +0000
            Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-25 16:24 -0500
              Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-26 23:36 +0000
                Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-26 19:00 -0500
                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-27 05:53 +0300
                  Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-27 09:43 -0500
                    Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-28 02:39 +0000
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 15:08 -0700
              Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-26 23:54 +0000
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 18:12 -0700
                  Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-28 02:54 +0000
                    Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-28 06:20 +0300
                      Re: Common name for a "Task Loop" raimond.dragomir@gmail.com - 2016-06-27 22:57 -0700
                      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-28 09:40 -0500
                        Re: Common name for a "Task Loop" Mel Wilson <mwilson@the-wire.com> - 2016-06-28 15:38 +0000
                          Re: Common name for a "Task Loop" raimond.dragomir@gmail.com - 2016-06-28 08:57 -0700
                        Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 16:49 +0000
                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-28 15:35 -0500
                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 13:54 -0700
                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 14:04 -0700
                              Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 21:09 +0000
                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 15:14 -0700
                                  Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 22:30 +0000
                                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 16:06 -0700
                                      Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 16:18 -0700
                                    Re: Common name for a "Task Loop" Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2016-06-29 01:32 +0200
                        Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 01:00 +0300
                          Re: Common name for a "Task Loop" Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2016-06-29 00:20 +0200
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:07 +0300
                          Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 22:21 +0000
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:20 +0300
                          Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-28 17:39 -0500
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:29 +0300
                              Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-29 09:50 -0500
                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 15:43 -0700
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:40 +0300
                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 16:56 -0700
                            Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-29 08:04 +0300
                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 23:22 -0700
                                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-30 09:02 +0300
                                  Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-30 02:33 -0700
                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-02 14:27 +0300
                                      Re: Common name for a "Task Loop" Wouter van Ooijen <wouter@voti.nl> - 2016-07-02 14:50 +0200
                                        Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-02 20:18 +0300
                                      Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-02 07:36 -0700
                                        Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-02 21:44 +0300
                                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-02 14:36 -0700
                                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-03 06:23 +0300
                                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-03 00:43 -0700
                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-29 11:36 -0500
                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-29 09:55 -0700
                              Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-29 12:53 -0500
                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-29 11:29 -0700
                                  Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-29 13:41 -0500
                                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-29 11:49 -0700
                                Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-02 20:48 -0700
                                  Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-03 03:07 -0500
                                    Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-03 08:06 -0700
                                      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-03 12:39 -0500
                                        Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-03 21:44 +0300
                                        Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-03 16:39 -0700
                                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-03 23:57 -0500
                                            Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-04 14:39 -0500
                                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-05 06:04 +0300
                                              Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-07-05 11:58 -0500
                                                Re: Common name for a "Task Loop" Reinhardt Behm <rbehm@hushmail.com> - 2016-07-06 10:39 +0800
                                                  Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-07-06 10:11 -0500
                                              Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-05 21:57 +0300
                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-05 12:20 -0700
                                            Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-04 10:08 -0700
                                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-05 11:59 -0700
                                            Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-05 22:51 +0300
                                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-05 13:16 -0700
                                                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-06 11:31 +0300
                                                  Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-06 03:06 -0700
                                                    Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-06 21:37 +0300
                                                      Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-07 00:50 -0400
                                                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-06 23:16 -0700
                                                          Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-07 21:36 +0300
                                                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-07 12:06 -0700
                                                              Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-07 23:09 +0300
                                                                Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-07-08 11:06 -0500
                                                                  Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 12:50 -0500
                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-08 23:33 +0300
                                                                      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 16:40 -0500
                                                                    Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-08 23:47 +0300
                                                                      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 16:48 -0500
                                                                        Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 21:37 +0300
                                                                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-09 14:26 -0500
                                                                            Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-10 00:48 +0300
                                                                              Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-10 03:29 -0500
                                                                                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-11 06:51 +0300
                                                                                  Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-11 16:11 +0300
                                                                                    Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-11 12:04 -0500
                                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-12 11:31 +0300
                                                                                      Re: Common name for a "Task Loop" mac <acolvin@efunct.com> - 2016-07-12 15:08 +0000
                                                                                        Re: Common name for a "Task Loop" Robert Wessel <robertwessel2@yahoo.com> - 2016-07-12 21:24 -0500
                                                                                      Memory scrubbing [Was Re: Common name for a "Task Loop"] Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-12 21:11 +0300
                                                                                    Re: Common name for a "Task Loop" Robert Wessel <robertwessel2@yahoo.com> - 2016-07-12 21:11 -0500
                                                                  Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-08 23:35 +0300
                                                                    Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-08 23:54 +0300
                                                                      Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-09 09:34 +0300
                                                                        Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-09 10:28 +0300
                                                                        Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-09 14:39 -0500
                                                                    Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 16:56 -0500
                                                                      Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 15:46 +0300
                                                                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-10 02:41 -0700
                                                                          Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-10 17:55 +0300
                                                                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-16 16:34 -0700
                                                                            Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-17 09:56 +0300
                                                                              Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-18 00:08 -0400
                                                                                Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-18 21:16 +0300
                                                                                  Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-18 23:54 -0400
                                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-19 10:02 +0300
                                                                                  Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-25 02:56 -0700
                                                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-25 02:40 -0700
                                                                                  Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-25 17:32 -0400
                                                                                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-25 16:56 -0700
                                                                                      Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-26 06:27 -0400
                                                                                        Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-26 15:59 +0300
                                                                                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-26 06:55 -0700
                                                                                          Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-26 17:14 +0300
                                                                                          Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-26 12:50 -0400
                                                                                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-26 22:07 -0700
                                                                                              Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-27 14:22 -0400
                                                                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-08-03 04:58 -0700
                                                                                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-26 06:38 -0700
                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-09 01:28 +0300
                                                                      Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-09 09:25 +0300
                                                                        Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 21:47 +0300
                                                                      Re: Common name for a "Task Loop" Mike Perkins <spam@spam.com> - 2016-07-09 11:18 +0100
                                                                      Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 21:41 +0300
                                                                    Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-07-09 20:52 -0500
                                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-10 02:01 -0700
                                                                  Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-10 17:34 +0300
                                                                    Re: Common name for a "Task Loop" [long] Don Y <blockedofcourse@foo.invalid> - 2016-07-17 01:17 -0700
                                                            Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-07-07 16:02 -0500
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-30 04:14 +0300
                              Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-30 17:07 -0500
                                Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-01 02:28 +0300
                      Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 12:02 -0700
                        Re: Common name for a "Task Loop" Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2016-06-28 23:19 +0200
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 11:51 -0700
                      Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-07-01 06:54 +0000
          Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-25 21:08 +0300
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 15:24 -0700
          Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-25 21:52 +0300
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 01:04 -0700
              Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 13:46 +0300
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 05:11 -0700
                  Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 15:35 +0300
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 06:57 -0700
                  Re: Common name for a "Task Loop" Reinhardt Behm <rbehm@hushmail.com> - 2016-06-26 21:18 +0800
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 07:07 -0700
                      Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 17:35 +0300
                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 07:50 -0700
                      Re: Common name for a "Task Loop" Reinhardt Behm <rbehm@hushmail.com> - 2016-06-26 22:37 +0800
                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 08:18 -0700
    Re: Common name for a "Task Loop" Dave Nadler <drn@nadler.com> - 2016-06-25 22:00 -0700
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-26 11:01 -0500
      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-26 19:28 -0500
    Re: Common name for a "Task Loop" FreeRTOS info <noemail@given.com> - 2016-06-27 08:33 +0100
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-28 09:48 -0500
        Re: Common name for a "Task Loop" raimond.dragomir@gmail.com - 2016-06-28 08:25 -0700
    Re: Common name for a "Task Loop" Chris <xxx.syseng.yyy@gfsys.co.uk> - 2016-07-03 17:39 +0000
    Re: Common name for a "Task Loop" WangoTango <Asgard24@mindspring.com> - 2016-07-14 16:27 -0400
      Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-07-14 20:44 +0000

Page 4 of 10 — ← Prev page 1 2 3 [4] 5 6 … 10  Next page →


#24426

FromTim Wescott <seemywebsite@myfooter.really>
Date2016-06-28 17:39 -0500
Message-ID<WKqdnRfbXJY_Ye_KnZ2dnUU7-L-dnZ2d@giganews.com>
In reply to#24421
On Wed, 29 Jun 2016 01:00:02 +0300, Dimiter_Popoff wrote:

> On 28.6.2016 г. 17:40, Tim Wescott wrote:
>> On Tue, 28 Jun 2016 06:20:43 +0300, Dimiter_Popoff wrote:
>>
>>> On 28.6.2016 г. 05:54, Simon Clubley wrote:
>>>>
>>>   > .....
>>>> I still think that's a polling loop because you are reaching out to
>>>> the sensor and asking it for it's current value.
>>>
>>> "Polling" in programming means "as opposed to interrupt handling".
>>> How is this opposed to "interrupt handling".
>>>
>>> What you suggest to be polling is simply a loop of calls to
>>> subroutines.
>>> A "call loop" is what describes it - although it does not matter a lot
>>> what word is used as long as it is not an already widely accepted one
>>> like "polling" which you want to redefine. Nothing wrong with that of
>>> course - as long as you don't have to communicate with other people
>>> using your redefined term.
>>>
>>> So much talk about so little :-). Although Tim's topic idea worked,
>>> produced quite a discussion.
>>
>> Well, I was hoping for a name of a design pattern, and I'm still not
>> happy about my choices.  So from that perspective it's a wash.
>>
>> "Super loop" seems closest, but it seems to more capture the notion of
>> _always_ executing A, B, C, rather than executing only those bits that
>> are ready.
>>
>>
> I encounter the "super loop" term for the first time here, but why not.
> Although I see nothing "super" about it, to me this is still an endless
> loop of calls to subroutines either of which may opt to do something or
> to just return if it has nothing to do.
> But like I said earlier I have almost never used this approach, it
> smells of oversimplifying - thus costing more than a decent scheduler
> does. Implement loops, state machines etc. as you like within tasks but
> having a true - preemptive allowing cooperative operation- scheduler
> costs very little in both machine resources and effort to put together
> so I see no point in trying to avoid it.

The "scheduler" overhead is about 10x lower with this style of 
switching.  If you've got a bunch of similar-run-length tasks this method 
works dandy.

Of course, if you've got a bunch of fast tasks and even one slow one 
(reciting the Gettysburg address to a human, for instance) then a 
preemptive scheduler gets very attractive.

-- 

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!

[toc] | [prev] | [next] | [standalone]


#24433

FromDimiter_Popoff <dp@tgi-sci.com>
Date2016-06-29 02:29 +0300
Message-ID<nkv19h$jjq$1@dont-email.me>
In reply to#24426
On 29.6.2016 г. 01:39, Tim Wescott wrote:
> On Wed, 29 Jun 2016 01:00:02 +0300, Dimiter_Popoff wrote:
>
>> On 28.6.2016 г. 17:40, Tim Wescott wrote:
>>> On Tue, 28 Jun 2016 06:20:43 +0300, Dimiter_Popoff wrote:
>>>
>>>> On 28.6.2016 г. 05:54, Simon Clubley wrote:
>>>>>
>>>>    > .....
>>>>> I still think that's a polling loop because you are reaching out to
>>>>> the sensor and asking it for it's current value.
>>>>
>>>> "Polling" in programming means "as opposed to interrupt handling".
>>>> How is this opposed to "interrupt handling".
>>>>
>>>> What you suggest to be polling is simply a loop of calls to
>>>> subroutines.
>>>> A "call loop" is what describes it - although it does not matter a lot
>>>> what word is used as long as it is not an already widely accepted one
>>>> like "polling" which you want to redefine. Nothing wrong with that of
>>>> course - as long as you don't have to communicate with other people
>>>> using your redefined term.
>>>>
>>>> So much talk about so little :-). Although Tim's topic idea worked,
>>>> produced quite a discussion.
>>>
>>> Well, I was hoping for a name of a design pattern, and I'm still not
>>> happy about my choices.  So from that perspective it's a wash.
>>>
>>> "Super loop" seems closest, but it seems to more capture the notion of
>>> _always_ executing A, B, C, rather than executing only those bits that
>>> are ready.
>>>
>>>
>> I encounter the "super loop" term for the first time here, but why not.
>> Although I see nothing "super" about it, to me this is still an endless
>> loop of calls to subroutines either of which may opt to do something or
>> to just return if it has nothing to do.
>> But like I said earlier I have almost never used this approach, it
>> smells of oversimplifying - thus costing more than a decent scheduler
>> does. Implement loops, state machines etc. as you like within tasks but
>> having a true - preemptive allowing cooperative operation- scheduler
>> costs very little in both machine resources and effort to put together
>> so I see no point in trying to avoid it.
>
> The "scheduler" overhead is about 10x lower with this style of
> switching.  If you've got a bunch of similar-run-length tasks this method
> works dandy.

Well it is perhaps 10x in terms of processing time but that makes it
within 1% of the time instead of within 0.1%. I mentioned earlier I
once (some 10years ago) I did a thing using the "loop" approach and
in hindsight I can say it cost me more time (I had plenty of
CPU resources to spare so other considerations just do not apply).

>
> Of course, if you've got a bunch of fast tasks and even one slow one
> (reciting the Gettysburg address to a human, for instance) then a
> preemptive scheduler gets very attractive.
>

I see the preemptive feature mostly as a backup plan, basically if the
reciter is say reciting through an UART at 9600 bps the output driver
would be exiting the task cooperatively long before being preempted
(say after filling an output FIFO of some 256 bytes or something).
But if the system is dynamic - e.g. a fullblown OS with a user in
front of it doing this and that - then preemption may well have to
kick in.

Dimiter

------------------------------------------------------
Dimiter Popoff, TGI             http://www.tgi-sci.com
------------------------------------------------------
http://www.flickr.com/photos/didi_tgi/





[toc] | [prev] | [next] | [standalone]


#24443

FromTim Wescott <tim@seemywebsite.com>
Date2016-06-29 09:50 -0500
Message-ID<TIWdnUZZHPmxfe7KnZ2dnUU7-RGdnZ2d@giganews.com>
In reply to#24433
On Wed, 29 Jun 2016 02:29:54 +0300, Dimiter_Popoff wrote:

> On 29.6.2016 г. 01:39, Tim Wescott wrote:
>> On Wed, 29 Jun 2016 01:00:02 +0300, Dimiter_Popoff wrote:
>>
>>> On 28.6.2016 г. 17:40, Tim Wescott wrote:
>>>> On Tue, 28 Jun 2016 06:20:43 +0300, Dimiter_Popoff wrote:
>>>>
>>>>> On 28.6.2016 г. 05:54, Simon Clubley wrote:
>>>>>>
>>>>>    > .....
>>>>>> I still think that's a polling loop because you are reaching out to
>>>>>> the sensor and asking it for it's current value.
>>>>>
>>>>> "Polling" in programming means "as opposed to interrupt handling".
>>>>> How is this opposed to "interrupt handling".
>>>>>
>>>>> What you suggest to be polling is simply a loop of calls to
>>>>> subroutines.
>>>>> A "call loop" is what describes it - although it does not matter a
>>>>> lot what word is used as long as it is not an already widely
>>>>> accepted one like "polling" which you want to redefine. Nothing
>>>>> wrong with that of course - as long as you don't have to communicate
>>>>> with other people using your redefined term.
>>>>>
>>>>> So much talk about so little :-). Although Tim's topic idea worked,
>>>>> produced quite a discussion.
>>>>
>>>> Well, I was hoping for a name of a design pattern, and I'm still not
>>>> happy about my choices.  So from that perspective it's a wash.
>>>>
>>>> "Super loop" seems closest, but it seems to more capture the notion
>>>> of _always_ executing A, B, C, rather than executing only those bits
>>>> that are ready.
>>>>
>>>>
>>> I encounter the "super loop" term for the first time here, but why
>>> not.
>>> Although I see nothing "super" about it, to me this is still an
>>> endless loop of calls to subroutines either of which may opt to do
>>> something or to just return if it has nothing to do.
>>> But like I said earlier I have almost never used this approach, it
>>> smells of oversimplifying - thus costing more than a decent scheduler
>>> does. Implement loops, state machines etc. as you like within tasks
>>> but having a true - preemptive allowing cooperative operation-
>>> scheduler costs very little in both machine resources and effort to
>>> put together so I see no point in trying to avoid it.
>>
>> The "scheduler" overhead is about 10x lower with this style of
>> switching.  If you've got a bunch of similar-run-length tasks this
>> method works dandy.
> 
> Well it is perhaps 10x in terms of processing time but that makes it
> within 1% of the time instead of within 0.1%. I mentioned earlier I once
> (some 10years ago) I did a thing using the "loop" approach and in
> hindsight I can say it cost me more time (I had plenty of CPU resources
> to spare so other considerations just do not apply).

The only times when the "super loop" architecture that I showed is really 
appropriate is when the problem is small or when the processor is being 
pushed too hard.  Otherwise -- yes, use an RTOS.

-- 
Tim Wescott
Control systems, embedded software and circuit design
I'm looking for work!  See my website if you're interested
http://www.wescottdesign.com

[toc] | [prev] | [next] | [standalone]


#24427

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-28 15:43 -0700
Message-ID<nkuuhj$brp$1@dont-email.me>
In reply to#24421
hi Dimiter,

On 6/28/2016 3:00 PM, Dimiter_Popoff wrote:
> I encounter the "super loop" term for the first time here, but why not.
> Although I see nothing "super" about it, to me this is still an endless
> loop of calls to subroutines either of which may opt to do something
> or to just return if it has nothing to do.
> But like I said earlier I have almost never used this approach, it
> smells of oversimplifying - thus costing more than a decent scheduler
> does. Implement loops, state machines etc. as you like within tasks
> but having a true - preemptive allowing cooperative operation- scheduler
> costs very little in both machine resources and effort to put together
> so I see no point in trying to avoid it.

I don't think you're understanding the value for "lean" approaches
when you are operating in resource starved implementations.

Imagine having a few HUNDRED bytes of RAM, *total* in your system.
How much of this do you "divert" to implementing a formal scheduler?
How much do you devote to preserving the state(s) of independant tasks?

One of my earliest products was a LORAN-C position plotter.  It
received LORAN coordinates (time-difference pairs) from an external
LORAN (radio) receiver.  These are ~6 (decimal) digit values that
represent the differences, in time, between radio waves being
received from three geographically-fixed transmitters (a master
and a pair of slaves; the slaves synchronized to the master)

<https://en.wikipedia.org/wiki/LORAN#Operation> not a very
good explanation -- but close enough.
<https://en.wikipedia.org/wiki/Loran-C#Principle>

As they are *differences*, they present a hyperbolic coordinate
system (back to Conic Sections 101  :> ).  Based on knowledge
of where these transmitters are located on the globe (latitude
and longitude!), you project the hyperbolic coordinate system
onto the spherical coordinate system of lat-lon (as used in
navigation).  Then, correct for the fact that the Earth is
an OBLATE sphere (not really *round*).  Finally, map these
onto a mercator map projection (the precisely scaled sheet of
paper -- aka MAP -- in your plotter on which your pen will be
drawing!) and drive the pen to the "current position" from its
previous position.

While the displays, keypad, stepping motor interfaces, etc.
can all use nice little integers, all of this navigational
math has to be done using floats.  Each "coordinate"
(whether in the hyperbolic, spherical/oblate, mercator
coordinate system) is thus a PAIR of floats.

With 256 bytes of RAM to play with (remember the pushdown stack
and EVERY RAM consumer), you really don't have spare *bits*,
let alone *bytes*, to devote to any sort of formal scheduling
framework.

E.g., the only time I bother with something as crude as (my
version of) the "big loop" is when I am operating in these severely
constrained environments.  My implementation costs me EXACTLY *two*
bytes per task.  Yet, allows me to still write code AS IF I had
the services and framework of a "real" scheduler.

I.e., I don't force tasks to watch a hardware counter/timer to
do their *own* timekeeping; I don't force a task to rely on exclusive
access to a physical resource (e.g., N tasks can all "use the UART"
instead of restricting access to just one set aside for that specific
purpose); I don't prevent tasks from blocking WHEREVER IT IS CONVENIENT
FOR THEM; etc.

So, each task can truly focus on its own needs without having to
address the concerns of other tasks (except for any data/events
that it must "source" to those tasks).

I think your current product offerings are REALLY "flush" with
resources, by comparison.  E.g., you (and I) wouldn't think twice
about using an "int" (32b!) as a "bool".  By contrast, the plotter
mentioned above packed *8* bools into a byte -- and, at some
times, might use that very same byte as a *counter*, etc. depending
on what was happening in the product at that time!

[toc] | [prev] | [next] | [standalone]


#24435

FromDimiter_Popoff <dp@tgi-sci.com>
Date2016-06-29 02:40 +0300
Message-ID<nkv1to$l72$1@dont-email.me>
In reply to#24427
On 29.6.2016 г. 01:43, Don Y wrote:
> hi Dimiter,
>
> On 6/28/2016 3:00 PM, Dimiter_Popoff wrote:
>> I encounter the "super loop" term for the first time here, but why not.
>> Although I see nothing "super" about it, to me this is still an endless
>> loop of calls to subroutines either of which may opt to do something
>> or to just return if it has nothing to do.
>> But like I said earlier I have almost never used this approach, it
>> smells of oversimplifying - thus costing more than a decent scheduler
>> does. Implement loops, state machines etc. as you like within tasks
>> but having a true - preemptive allowing cooperative operation- scheduler
>> costs very little in both machine resources and effort to put together
>> so I see no point in trying to avoid it.
>
> I don't think you're understanding the value for "lean" approaches
> when you are operating in resource starved implementations.
>
> Imagine having a few HUNDRED bytes of RAM, *total* in your system.
> How much of this do you "divert" to implementing a formal scheduler?
> How much do you devote to preserving the state(s) of independant tasks?

Hi Don,

I think I addressed this in my reply to Hans a short time ago.
My estimate was that for 5-6 tasks at 512 bytes of RAM you'd spend
about 20% of it on multitasking. If you opt for the superloop
approach you will still need some stack etc., let us say
5%.  Which means you will have spent about 80 bytes on having
a good scheduler - which would likely be a good deal in most
cases (and of course I can see there can be extreme cases where
one just does not have the 80 bytes).

>
> One of my earliest products was a LORAN-C position plotter.  It
> received LORAN coordinates (time-difference pairs) from an external
> LORAN (radio) receiver.  These are ~6 (decimal) digit values that
> represent the differences, in time, between radio waves being
> received from three geographically-fixed transmitters (a master
> and a pair of slaves; the slaves synchronized to the master)
>
> <https://en.wikipedia.org/wiki/LORAN#Operation> not a very
> good explanation -- but close enough.
> <https://en.wikipedia.org/wiki/Loran-C#Principle>
>
> As they are *differences*, they present a hyperbolic coordinate
> system (back to Conic Sections 101  :> ).  Based on knowledge
> of where these transmitters are located on the globe (latitude
> and longitude!), you project the hyperbolic coordinate system
> onto the spherical coordinate system of lat-lon (as used in
> navigation).  Then, correct for the fact that the Earth is
> an OBLATE sphere (not really *round*).  Finally, map these
> onto a mercator map projection (the precisely scaled sheet of
> paper -- aka MAP -- in your plotter on which your pen will be
> drawing!) and drive the pen to the "current position" from its
> previous position.
>
> While the displays, keypad, stepping motor interfaces, etc.
> can all use nice little integers, all of this navigational
> math has to be done using floats.  Each "coordinate"
> (whether in the hyperbolic, spherical/oblate, mercator
> coordinate system) is thus a PAIR of floats.
>
> With 256 bytes of RAM to play with (remember the pushdown stack
> and EVERY RAM consumer), you really don't have spare *bits*,
> let alone *bytes*, to devote to any sort of formal scheduling
> framework.

Well this is a good example of an extreme case where it is worth
going to extra length to save each byte of RAM, of course.

> ....
>
> I think your current product offerings are REALLY "flush" with
> resources, by comparison.  E.g., you (and I) wouldn't think twice
> about using an "int" (32b!) as a "bool".  By contrast, the plotter
> mentioned above packed *8* bools into a byte -- and, at some
> times, might use that very same byte as a *counter*, etc. depending
> on what was happening in the product at that time!
>

We all have plenty of resources nowadays indeed, which is why
I think a scheduler is the normal way to go. But I do not use a longword
as "bool", almost never. Typically I call it "flag" and define
bits into it... then often I (have to) use atomic accesses to it
etc. :-).

Dimiter

------------------------------------------------------
Dimiter Popoff, TGI             http://www.tgi-sci.com
------------------------------------------------------
http://www.flickr.com/photos/didi_tgi/



[toc] | [prev] | [next] | [standalone]


#24436

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-28 16:56 -0700
Message-ID<nkv2rb$nnm$1@dont-email.me>
In reply to#24435
On 6/28/2016 4:40 PM, Dimiter_Popoff wrote:
> We all have plenty of resources nowadays indeed, which is why
> I think a scheduler is the normal way to go. But I do not use a longword

I don't think that is universally the case.  I think there still exist
"penny pinching" applications.

OTOH, I think many of those could, for the same effective cost, move up to
more featureful implementations if not for "design inertia"

I've played at the shallow end of the pool for a long time.  Now I'm
enjoying "the deep end" -- and the VERY deep end!  There are entirely
different issues present that you'd never get exposed to if you
kept playing in the "wading pool"  :-/

> as "bool", almost never. Typically I call it "flag" and define
> bits into it... then often I (have to) use atomic accesses to it
> etc. :-).

[toc] | [prev] | [next] | [standalone]


#24437

Fromupsidedown@downunder.com
Date2016-06-29 08:04 +0300
Message-ID<6cl6nb99aa54apfq3b179m7uoeir9dc3jj@4ax.com>
In reply to#24427
On Tue, 28 Jun 2016 15:43:03 -0700, Don Y
<blockedofcourse@foo.invalid> wrote:


>Imagine having a few HUNDRED bytes of RAM, *total* in your system.
>How much of this do you "divert" to implementing a formal scheduler?
>How much do you devote to preserving the state(s) of independant tasks?

With a stack oriented HLL like Pascal r C, the variables are already
in the (private) stacks,  only the CPU registers needs to be saved,
thus only a few extra bytes needs to be allocated in each local stack
in addition to the application variables.
  

[toc] | [prev] | [next] | [standalone]


#24438

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-28 23:22 -0700
Message-ID<nkvpfn$civ$1@dont-email.me>
In reply to#24437
On 6/28/2016 10:04 PM, upsidedown@downunder.com wrote:
> On Tue, 28 Jun 2016 15:43:03 -0700, Don Y
> <blockedofcourse@foo.invalid> wrote:
>
>> Imagine having a few HUNDRED bytes of RAM, *total* in your system.
>> How much of this do you "divert" to implementing a formal scheduler?
>> How much do you devote to preserving the state(s) of independant tasks?
>
> With a stack oriented HLL like Pascal r C, the variables are already
> in the (private) stacks,  only the CPU registers needs to be saved,
> thus only a few extra bytes needs to be allocated in each local stack
> in addition to the application variables.

Ah, but that's the problem!  You now need stacks for each task
(each large enough to satisfy the task's worst case stack penetration
*plus* any stack required by ISRs -- as they can occur during any
task's "time slot").

You can save JUST the SP for each task and use that to "recover"
the stack and CPU registers (saved on the stack during the context
switch).

But, you will alwyas be tempted to yield() (or equivalent) at some
arbitrary depth on the stack.  I.e., you can have a dozen stack
frames nested FOR THIS TASK and decide to yield() -- now, all of those
stack frames must be preserved as part of the task's state (because
you picked a "less than ideal place" to yield the processor to the
"next" task)

If, instead, you impose a discipline on when you can yield, then
you can eliminate the need to preserve any of this "stacked state".
E.g., only "yield" when the SP is at the level it is at between calls
out from the big loop.

Then, all you need to do is save the processor state (registers plus PC;
the SP will be *known* to be "fixed" in all such invocations with NOTHING
on the stack!)

If you take a step further and allow yield() to be invoked ANY TIME YOU
CARE NOTHING ABOUT THE REGISTER CONTENTS, then you don't even have to
save those!  That's the premise of the MTX I described in my other posts
(and the reason it can function with just 2 bytes per task -- the PC).

If you're working in tiny environments, you probably are willing -- even
EAGER -- to shed the sorts of overhead that you typically draw into the
mix with HLL's; yet, you sacrifice relatively little in terms of
capability (cuz you're not building giant applications with negligible
resources!)

[toc] | [prev] | [next] | [standalone]


#24477

Fromupsidedown@downunder.com
Date2016-06-30 09:02 +0300
Message-ID<smb9nb1rmauevd5murpt9b6vjpjek8e23s@4ax.com>
In reply to#24438
On Tue, 28 Jun 2016 23:22:51 -0700, Don Y
<blockedofcourse@foo.invalid> wrote:

>On 6/28/2016 10:04 PM, upsidedown@downunder.com wrote:
>> On Tue, 28 Jun 2016 15:43:03 -0700, Don Y
>> <blockedofcourse@foo.invalid> wrote:
>>
>>> Imagine having a few HUNDRED bytes of RAM, *total* in your system.
>>> How much of this do you "divert" to implementing a formal scheduler?
>>> How much do you devote to preserving the state(s) of independant tasks?
>>
>> With a stack oriented HLL like Pascal r C, the variables are already
>> in the (private) stacks,  only the CPU registers needs to be saved,
>> thus only a few extra bytes needs to be allocated in each local stack
>> in addition to the application variables.
>
>Ah, but that's the problem!  You now need stacks for each task
>(each large enough to satisfy the task's worst case stack penetration
>*plus* any stack required by ISRs -- as they can occur during any
>task's "time slot").
>
>You can save JUST the SP for each task and use that to "recover"
>the stack and CPU registers (saved on the stack during the context
>switch).
>
>But, you will alwyas be tempted to yield() (or equivalent) at some
>arbitrary depth on the stack.  I.e., you can have a dozen stack
>frames nested FOR THIS TASK and decide to yield() -- now, all of those
>stack frames must be preserved as part of the task's state (because
>you picked a "less than ideal place" to yield the processor to the
>"next" task)

In preemptive systems you usually talk about a task becoming not ready
e.g. waiting for some event. Some systems execute a Software Interrupt
type instruction stacking the registers as a real interrupt would do.
The stack pointer is saved into the kernel data structure.

There are no nested saved register sets, there is just _one_ saved
register set at the top of the stack.

When the task finally becomes ready to run, the scheduler reloads the
task stack pointer and then performs a Return From Interrupt, which
pops the registers and continues with the instruction following the
Software Interrupt instruction.

So there are at most one saved register set in the task specific stack
and it is located at the top of the stack.

[toc] | [prev] | [next] | [standalone]


#24480

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-30 02:33 -0700
Message-ID<nl2p13$oqb$1@dont-email.me>
In reply to#24477
On 6/29/2016 11:02 PM, upsidedown@downunder.com wrote:

>> Ah, but that's the problem!  You now need stacks for each task
>> (each large enough to satisfy the task's worst case stack penetration
>> *plus* any stack required by ISRs -- as they can occur during any
>> task's "time slot").
>>
>> You can save JUST the SP for each task and use that to "recover"
>> the stack and CPU registers (saved on the stack during the context
>> switch).
>>
>> But, you will alwyas be tempted to yield() (or equivalent) at some
>> arbitrary depth on the stack.  I.e., you can have a dozen stack
>> frames nested FOR THIS TASK and decide to yield() -- now, all of those
>> stack frames must be preserved as part of the task's state (because
>> you picked a "less than ideal place" to yield the processor to the
>> "next" task)
>
> In preemptive systems you usually talk about a task becoming not ready
> e.g. waiting for some event. Some systems execute a Software Interrupt
> type instruction stacking the registers as a real interrupt would do.
> The stack pointer is saved into the kernel data structure.
>
> There are no nested saved register sets, there is just _one_ saved
> register set at the top of the stack.
>
> When the task finally becomes ready to run, the scheduler reloads the
> task stack pointer and then performs a Return From Interrupt, which
> pops the registers and continues with the instruction following the
> Software Interrupt instruction.
>
> So there are at most one saved register set in the task specific stack
> and it is located at the top of the stack.

And the other tasks have NO stacks?  And no "processor state" stored?

Note the "stack frames" that I mentioned, above, refer to the nesting of
*function calls* (or subroutine invocations) within each specific task.
I.e., you have no way of knowing how "deep" each task's stack happens to
be when the task is preempted or voluntarily yields control of the
processor.

At that point, ALL of the task's state must be preserved:  its CPU registers
and its "live" stack.

Repeat for all tasks in the system.

If, instead, you ensure all context switches occur when there is NOTHING on
the "task-specific stack", then all tasks can SHARE a stack (because you've
ensured that the stack will be empty BEFORE you allow a reschedule() event).

As such, the memory required for the stack is the maximum stack penetration
of ANY task -- plus the maximum usage for the foreground (ISR) system.

Contrast this with the maximum stack penetration for *each* task, plus the
maximum ISR penetration SUMMED for all tasks in the system.

(Some processors let you specify a separate stack for ISR's.  In which case,
you can eliminate the cost of the ISR stack PER TASK)

[toc] | [prev] | [next] | [standalone]


#24511

Fromupsidedown@downunder.com
Date2016-07-02 14:27 +0300
Message-ID<j58fnbl2giluke621jdgjfsahnak14jcfm@4ax.com>
In reply to#24480
On Thu, 30 Jun 2016 02:33:24 -0700, Don Y
<blockedofcourse@foo.invalid> wrote:

>On 6/29/2016 11:02 PM, upsidedown@downunder.com wrote:
>
>>> Ah, but that's the problem!  You now need stacks for each task
>>> (each large enough to satisfy the task's worst case stack penetration
>>> *plus* any stack required by ISRs -- as they can occur during any
>>> task's "time slot").
>>>
>>> You can save JUST the SP for each task and use that to "recover"
>>> the stack and CPU registers (saved on the stack during the context
>>> switch).
>>>
>>> But, you will alwyas be tempted to yield() (or equivalent) at some
>>> arbitrary depth on the stack.  I.e., you can have a dozen stack
>>> frames nested FOR THIS TASK and decide to yield() -- now, all of those
>>> stack frames must be preserved as part of the task's state (because
>>> you picked a "less than ideal place" to yield the processor to the
>>> "next" task)
>>
>> In preemptive systems you usually talk about a task becoming not ready
>> e.g. waiting for some event. Some systems execute a Software Interrupt
>> type instruction stacking the registers as a real interrupt would do.
>> The stack pointer is saved into the kernel data structure.
>>
>> There are no nested saved register sets, there is just _one_ saved
>> register set at the top of the stack.
>>
>> When the task finally becomes ready to run, the scheduler reloads the
>> task stack pointer and then performs a Return From Interrupt, which
>> pops the registers and continues with the instruction following the
>> Software Interrupt instruction.
>>
>> So there are at most one saved register set in the task specific stack
>> and it is located at the top of the stack.
>
>And the other tasks have NO stacks?  And no "processor state" stored?

After working for several decades with preemptive kernels, I thought
it is self-evident that a preemptive system requires task specific
stacks !!
 
>
>Note the "stack frames" that I mentioned, above, refer to the nesting of
>*function calls* (or subroutine invocations) within each specific task.
>I.e., you have no way of knowing how "deep" each task's stack happens to
>be when the task is preempted or voluntarily yields control of the
>processor.

This is not relevant to the context saving discussion.

You can do a quite good static stack usage analysis based on static
code analysis. In many systems recursive calls are forbidden exactly
for that reason. 

>At that point, ALL of the task's state must be preserved:  its CPU registers
>and its "live" stack.

Self-evident.

[toc] | [prev] | [next] | [standalone]


#24512

FromWouter van Ooijen <wouter@voti.nl>
Date2016-07-02 14:50 +0200
Message-ID<5777b8a0$0$22216$e4fe514c@newszilla.xs4all.nl>
In reply to#24511
Op 02-Jul-16 om 1:27 PM schreef upsidedown@downunder.com:
> On Thu, 30 Jun 2016 02:33:24 -0700, Don Y
> <blockedofcourse@foo.invalid> wrote:
>
>> On 6/29/2016 11:02 PM, upsidedown@downunder.com wrote:
>>
>>>> Ah, but that's the problem!  You now need stacks for each task
>>>> (each large enough to satisfy the task's worst case stack penetration
>>>> *plus* any stack required by ISRs -- as they can occur during any
>>>> task's "time slot").
>>>>
>>>> You can save JUST the SP for each task and use that to "recover"
>>>> the stack and CPU registers (saved on the stack during the context
>>>> switch).
>>>>
>>>> But, you will alwyas be tempted to yield() (or equivalent) at some
>>>> arbitrary depth on the stack.  I.e., you can have a dozen stack
>>>> frames nested FOR THIS TASK and decide to yield() -- now, all of those
>>>> stack frames must be preserved as part of the task's state (because
>>>> you picked a "less than ideal place" to yield the processor to the
>>>> "next" task)
>>>
>>> In preemptive systems you usually talk about a task becoming not ready
>>> e.g. waiting for some event. Some systems execute a Software Interrupt
>>> type instruction stacking the registers as a real interrupt would do.
>>> The stack pointer is saved into the kernel data structure.
>>>
>>> There are no nested saved register sets, there is just _one_ saved
>>> register set at the top of the stack.
>>>
>>> When the task finally becomes ready to run, the scheduler reloads the
>>> task stack pointer and then performs a Return From Interrupt, which
>>> pops the registers and continues with the instruction following the
>>> Software Interrupt instruction.
>>>
>>> So there are at most one saved register set in the task specific stack
>>> and it is located at the top of the stack.
>>
>> And the other tasks have NO stacks?  And no "processor state" stored?
>
> After working for several decades with preemptive kernels, I thought
> it is self-evident that a preemptive system requires task specific
> stacks !!
>
>>
>> Note the "stack frames" that I mentioned, above, refer to the nesting of
>> *function calls* (or subroutine invocations) within each specific task.
>> I.e., you have no way of knowing how "deep" each task's stack happens to
>> be when the task is preempted or voluntarily yields control of the
>> processor.
>
> This is not relevant to the context saving discussion.
>
> You can do a quite good static stack usage analysis based on static
> code analysis. In many systems recursive calls are forbidden exactly
> for that reason.

Do you have experience (or know) any tools that do this?

Wouter "Objects? No Thanks!" van Ooijen

[toc] | [prev] | [next] | [standalone]


#24514

FromNiklas Holsti <niklas.holsti@tidorum.invalid>
Date2016-07-02 20:18 +0300
Message-ID<dtqbbbF846cU1@mid.individual.net>
In reply to#24512
On 16-07-02 15:50 , Wouter van Ooijen wrote:
> Op 02-Jul-16 om 1:27 PM schreef upsidedown@downunder.com:
>> On Thu, 30 Jun 2016 02:33:24 -0700, Don Y
>> <blockedofcourse@foo.invalid> wrote:
>>
>>> On 6/29/2016 11:02 PM, upsidedown@downunder.com wrote:
>>>
>>>>> Ah, but that's the problem!  You now need stacks for each task
>>>>> (each large enough to satisfy the task's worst case stack penetration
>>>>> *plus* any stack required by ISRs -- as they can occur during any
>>>>> task's "time slot").
>>>>>
>>>>> You can save JUST the SP for each task and use that to "recover"
>>>>> the stack and CPU registers (saved on the stack during the context
>>>>> switch).
>>>>>
>>>>> But, you will alwyas be tempted to yield() (or equivalent) at some
>>>>> arbitrary depth on the stack.  I.e., you can have a dozen stack
>>>>> frames nested FOR THIS TASK and decide to yield() -- now, all of those
>>>>> stack frames must be preserved as part of the task's state (because
>>>>> you picked a "less than ideal place" to yield the processor to the
>>>>> "next" task)
>>>>
>>>> In preemptive systems you usually talk about a task becoming not ready
>>>> e.g. waiting for some event. Some systems execute a Software Interrupt
>>>> type instruction stacking the registers as a real interrupt would do.
>>>> The stack pointer is saved into the kernel data structure.
>>>>
>>>> There are no nested saved register sets, there is just _one_ saved
>>>> register set at the top of the stack.
>>>>
>>>> When the task finally becomes ready to run, the scheduler reloads the
>>>> task stack pointer and then performs a Return From Interrupt, which
>>>> pops the registers and continues with the instruction following the
>>>> Software Interrupt instruction.
>>>>
>>>> So there are at most one saved register set in the task specific stack
>>>> and it is located at the top of the stack.
>>>
>>> And the other tasks have NO stacks?  And no "processor state" stored?
>>
>> After working for several decades with preemptive kernels, I thought
>> it is self-evident that a preemptive system requires task specific
>> stacks !!
>>
>>>
>>> Note the "stack frames" that I mentioned, above, refer to the nesting of
>>> *function calls* (or subroutine invocations) within each specific task.
>>> I.e., you have no way of knowing how "deep" each task's stack happens to
>>> be when the task is preempted or voluntarily yields control of the
>>> processor.
>>
>> This is not relevant to the context saving discussion.
>>
>> You can do a quite good static stack usage analysis based on static
>> code analysis. In many systems recursive calls are forbidden exactly
>> for that reason.
>
> Do you have experience (or know) any tools that do this?

Google "static stack usage analysis" for links.

Compilers from IAR Systems can do it, at least for some targets.

AdaCore provide the "gnatstack" tool which can also do it, in 
conjunction with AdaCore's compilers.

StackAnalyzer (www.absint.com) and Bound-T (www.bound-t.com) can do it.

GCC option "-fstack-usage" gives per-function stack usage. For the AVR 
target, a Perl script can be used to add those up along call-paths to 
get per-thread stack usage (http://dlbeer.co.nz/oss/avstack.html).

I have experience with Bound-T (well, I'm the developer) and some with 
IAR compilers. As long as all calls and stack-space allocations are 
static the tools work well; when either calls or stack allocations 
become dynamic (e.g. virtual function calls) you run into problems, but 
at least the commercial tools have means to work around those problems.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

[toc] | [prev] | [next] | [standalone]


#24513

FromDon Y <blockedofcourse@foo.invalid>
Date2016-07-02 07:36 -0700
Message-ID<nl8jh6$acj$1@dont-email.me>
In reply to#24511
On 7/2/2016 4:27 AM, upsidedown@downunder.com wrote:
> On Thu, 30 Jun 2016 02:33:24 -0700, Don Y

>>>> But, you will alwyas be tempted to yield() (or equivalent) at some
>>>> arbitrary depth on the stack.  I.e., you can have a dozen stack
>>>> frames nested FOR THIS TASK and decide to yield() -- now, all of those
>>>> stack frames must be preserved as part of the task's state (because
>>>> you picked a "less than ideal place" to yield the processor to the
>>>> "next" task)
>>>
>>> In preemptive systems you usually talk about a task becoming not ready
>>> e.g. waiting for some event. Some systems execute a Software Interrupt
>>> type instruction stacking the registers as a real interrupt would do.
>>> The stack pointer is saved into the kernel data structure.
>>>
>>> There are no nested saved register sets, there is just _one_ saved
>>> register set at the top of the stack.
>>>
>>> When the task finally becomes ready to run, the scheduler reloads the
>>> task stack pointer and then performs a Return From Interrupt, which
>>> pops the registers and continues with the instruction following the
>>> Software Interrupt instruction.
>>>
>>> So there are at most one saved register set in the task specific stack
>>> and it is located at the top of the stack.
>>
>> And the other tasks have NO stacks?  And no "processor state" stored?
>
> After working for several decades with preemptive kernels, I thought
> it is self-evident that a preemptive system requires task specific
> stacks !!

Now, walk back up-thread to my comment to Dimiter:

    Imagine having a few HUNDRED bytes of RAM, *total* in your system.
    How much of this do you "divert" to implementing a formal scheduler?
    How much do you devote to preserving the state(s) of independant tasks?

>> Note the "stack frames" that I mentioned, above, refer to the nesting of
>> *function calls* (or subroutine invocations) within each specific task.
>> I.e., you have no way of knowing how "deep" each task's stack happens to
>> be when the task is preempted or voluntarily yields control of the
>> processor.
>
> This is not relevant to the context saving discussion.

Again, walk back up-thread and please find try to see *if* I claimed it to
be part of the context switch.

You're missing the appeal of NOT including any "stacked task state" in
the PRESERVED TASK STATE; namely, that the amount of RAM that you dedicate
to stack usage -- ALL stacks -- in the design is the maximum of all
tasks' stack penetration plus the ISR penetration.  You never have more
than one stack "live" in the system!

    "If, instead, you ensure all context switches occur when there is NOTHING on
    the 'task-specific stack', then all tasks can SHARE a stack (because you've
    ensured that the stack will be empty BEFORE you allow a reschedule() event).

> You can do a quite good static stack usage analysis based on static
> code analysis. In many systems recursive calls are forbidden exactly
> for that reason.
>
>> At that point, ALL of the task's state must be preserved:  its CPU registers
>> and its "live" stack.
>
> Self-evident.

But not necessary to work in a multitasking environment!  Even with a HLL
(though operating with NOTHING preserved on the stack in a HLL environment
imposes lots of constraints -- with which the compiler WON'T help!):

task()  {
     some_variable_declarations;     <---- disallowed
     ...
     some_function();
     ...
     taskX();     <---- disallowed
     ...
     yield();    <---- allowed
     ...
}

some_function() {
     ...
     yield();       <------ disallowed
     ...
}

OTOH, there's nothing wrong with:

task()  {
     ...
     global = value;       <---- allowed
     ...
     another_function();   <---- allowed
     ...
     yield();              <---- allowed
     ...
}

another_function() {
     some_variable_declarations;
     ...
     some_other_function();
     ...
     another_function();       // recursive
     ...
}

This latter form is quite "comfortable", after some experience.

(Replace C with your language of choice)

[toc] | [prev] | [next] | [standalone]


#24515

Fromupsidedown@downunder.com
Date2016-07-02 21:44 +0300
Message-ID<bt1gnbtdb83lcbavogvndi9s5ke5bqu9ad@4ax.com>
In reply to#24513
On Sat, 02 Jul 2016 07:36:34 -0700, Don Y
<blockedofcourse@foo.invalid> wrote:

>On 7/2/2016 4:27 AM, upsidedown@downunder.com wrote:
>> On Thu, 30 Jun 2016 02:33:24 -0700, Don Y
>
>>>>> But, you will alwyas be tempted to yield() (or equivalent) at some
>>>>> arbitrary depth on the stack.  I.e., you can have a dozen stack
>>>>> frames nested FOR THIS TASK and decide to yield() -- now, all of those
>>>>> stack frames must be preserved as part of the task's state (because
>>>>> you picked a "less than ideal place" to yield the processor to the
>>>>> "next" task)
>>>>
>>>> In preemptive systems you usually talk about a task becoming not ready
>>>> e.g. waiting for some event. Some systems execute a Software Interrupt
>>>> type instruction stacking the registers as a real interrupt would do.
>>>> The stack pointer is saved into the kernel data structure.
>>>>
>>>> There are no nested saved register sets, there is just _one_ saved
>>>> register set at the top of the stack.
>>>>
>>>> When the task finally becomes ready to run, the scheduler reloads the
>>>> task stack pointer and then performs a Return From Interrupt, which
>>>> pops the registers and continues with the instruction following the
>>>> Software Interrupt instruction.
>>>>
>>>> So there are at most one saved register set in the task specific stack
>>>> and it is located at the top of the stack.
>>>
>>> And the other tasks have NO stacks?  And no "processor state" stored?
>>
>> After working for several decades with preemptive kernels, I thought
>> it is self-evident that a preemptive system requires task specific
>> stacks !!
>
>Now, walk back up-thread to my comment to Dimiter:
>
>    Imagine having a few HUNDRED bytes of RAM, *total* in your system.
>    How much of this do you "divert" to implementing a formal scheduler?
>    How much do you devote to preserving the state(s) of independant tasks?

On some small systems I have worked with, I have initially allocated
64 bytes stack space for each task or something more, if the manual
static analysis would demand. 

Also filling each task with a known pattern and checking after a week
how much has actually been used and reduced the stack allocation
accordingly.

In one case the kernel data structure was just 3 bytes for each task,
two bytes to store the stack pointer for each task and one byte to
contain the task state, such as not ready, ready and running.Slightly
more RAM efficient would be to use 8 or 16 task states (runnable or
not) into 1 or 2 bytes.

With 64 bytes/task, you could fit 3 tasks into 200 bytes and six into
400 bytes of RAM.

[toc] | [prev] | [next] | [standalone]


#24516

FromDon Y <blockedofcourse@foo.invalid>
Date2016-07-02 14:36 -0700
Message-ID<nl9c3t$t0$1@dont-email.me>
In reply to#24515
On 7/2/2016 11:44 AM, upsidedown@downunder.com wrote:
> With 64 bytes/task, you could fit 3 tasks into 200 bytes and six into
> 400 bytes of RAM.

With 3 tasks, you probably couldn't implement a municipal traffic light
controller!  (don't forget the globals and ISR's)

(Yes, you could *do* it -- as one big spaghetti loop)

- Run the normal light cycle (go/caution/stop)
- Sense vehicles waiting in the turn lanes to conditionally qualify those
    by injecting the "turn arrow" controls
- Sense traffic proceeding through the intersection and waiting at cross
    streets (to adjust the timing of the cycles)
- Communicate with the other processes (so if oncoming is allowing left
    turns, YOU should probably do so as well -- or not!)
- Sense a demand for a "walk" signal
- Control the walk/countdown/don't walk signals
- Monitor for on-coming emergency vehicles
- Indicate recognition of said vehicles and adjust traffic cycles accordingly.
- Communicate with municipal controlling algorithms/time-of-day scheduling.
- Allow on-site overrides.
- Support run-time diagnostics (fallback modes)

And, we're not even worrying about red-light cameras or general surveillance
cameras!

1980's era (arcade) video games would treat each object on the screen
as a task.  So, 50 - 100 objects all acting independantly without
concern for their "neighbors" (unless their neighbor was something
that they could kill or be killed by).

I run 5 tasks to decode a barcode (without "consuming" it)

My "fallback" speech synthesizers each require more than a dozen tasks.

Etc.

I.e., I *like* decomposing projects into more manageable pieces -- get it
right the first time!

[toc] | [prev] | [next] | [standalone]


#24518

FromDimiter_Popoff <dp@tgi-sci.com>
Date2016-07-03 06:23 +0300
Message-ID<nla0fn$r3v$1@dont-email.me>
In reply to#24516
On 03.7.2016 г. 00:36, Don Y wrote:
> On 7/2/2016 11:44 AM, upsidedown@downunder.com wrote:
>> With 64 bytes/task, you could fit 3 tasks into 200 bytes and six into
>> 400 bytes of RAM.
>
> With 3 tasks, you probably couldn't implement a municipal traffic light
> controller!  (don't forget the globals and ISR's)

Don, even splitting things in two tasks can be quite helpful. Say one
handling the I/O and the other the rest.
Having a multitask scheduler does not mean you don't use loops. You do
of course - practically always. You just don't have to care about what
the scheduler gives you in every subroutine you write - just call the
"task exit for rescheduling" call when your code has to wait. If you
don't have the scheduler you will have to care about this every step of
the way, make sure you know where your current stack pointer is
(subroutine calls; then a subroutine which exits cannot be just
called from any nesting level etc. etc.).

If we really have to count the bytes of RAM - let us say we turn the
clock 25 years back - we can statically assign as much stack as needed
to each task. We may find out that splitting in 3 tasks can at
times _save_ memory above a certain complexity...

I thought we'd be done with counting for days every byte by now,
last "small" MCU I used was a coldfire in tqfp100 with 16k RAM and
a sort of 68000 running at 80 MHz.... I just copied and slightly
adapted the initial (68340 from 1994) DPS scheduler and trap handler,
cost me virtually nothing.

http://tgi-sci.com/dsv/swgboard.gif
http://tgi-sci.com/dsv/swg800.gif
http://tgi-sci.com/misc/PICT6999.avi
http://tgi-sci.com/tgi/auxhv.htm
No picture of the last, this MCU replaced a huge computer board
in an 8 channel Ortec alpha counting system so they could use
two netmca-s to simultaneously select any two vacuum chhambers
to count, measure the vacuum and plenty of other internals, the
analog part was intact).

And such an MCU costs well below $10 at Mouser or the likes for
a single piece....

Dimiter

------------------------------------------------------
Dimiter Popoff, TGI             http://www.tgi-sci.com
------------------------------------------------------
http://www.flickr.com/photos/didi_tgi/


[toc] | [prev] | [next] | [standalone]


#24522

FromDon Y <blockedofcourse@foo.invalid>
Date2016-07-03 00:43 -0700
Message-ID<nlafmi$ukt$1@dont-email.me>
In reply to#24518
Hi Dimiter,

On 7/2/2016 8:23 PM, Dimiter_Popoff wrote:
> On 03.7.2016 г. 00:36, Don Y wrote:
>> On 7/2/2016 11:44 AM, upsidedown@downunder.com wrote:
>>> With 64 bytes/task, you could fit 3 tasks into 200 bytes and six into
>>> 400 bytes of RAM.
>>
>> With 3 tasks, you probably couldn't implement a municipal traffic light
>> controller!  (don't forget the globals and ISR's)
>
> Don, even splitting things in two tasks can be quite helpful. Say one
> handling the I/O and the other the rest.

Yes, but you ideally want to come up with a "natural decomposition";
how do things *want* to split themselves up instead of how *can* I
split them up.

I like doing lots of little things and getting them 100.0% correct
instead of trying to walk and chew gum -- and risking a latent bug.

E.g., the barcode decoder in the example I previously posted runs in 6 layers:
- an ISR grabs the contents of a freerunning two byte counter-timer using 3
   byte-wide reads (H-L-H / L-H-L); it also reads another counter-timer (the
   one that generated the IRQ from the rising/falling edge of the "video"
   signal) to determine "how long ago" the actual edge occured (this allows
   interrupt latency to be removed from the 3 byte read!); then, programs
   the counter-timer to look for the "opposite" edge (black-to-white vs.
   white-to-black)
- the first "background" task simply watches the FIFO maintained by the
   ISR and extracts data as it becomes available; it notices special
   encodings in the FIFO that indicate the ISR overran the FIFO (so,
   data has been lost *at* that point -- but the data preceding it may
   still represent a valid code); as it extracts each 4-byte entry, it
   converts the 3-byte timer read into a 2-byte read (by noticing if the
   low byte "wrapped" while the read was happening); then, uses the
   "latency time" to adjust the 2-byte value to account for any delay
   that might have been present when the IRQ was actually *serviced*;
   it also passes flags that indicate if the 2-byte timer wrapped more
   than once (cuz the ISR can be idle for long periods of time between
   uses; 0x65535 and 0x0002 may have far more than 3 counts between them!).
   So, this task's primary purpose is to keep the ISR FIFO empty cuz each
   entry there consumes 4 bytes
- the second background task looks at these 2-byte counts (and any interspersed
   flag encodings) and computes time *differences* between them.  It knows
   that the 2 byte counter might not be counting [0..65535] -- or even something
   like [0..MAX_COUNT] -- rather, it can be counting ([0..MAX_LSB],[0..MAX_MSB])
   so has to play games with modular arithmetic but can do the math /in situ/
   without consuming any additional memory (recall the first background task
   will be trying to fill *this* buffer as well!)
- the third grabs groups of 8 (?) "bars" (a "space" is essentially a bar)
   and tries to see if the widths fit the ratios of the barcode that is
   being decoded -- assuming the label has been scanned at a relatively
   constant speed over the course of those bars/spaces; it reduces the
   bars/spaces to a "character" in the format supported by the label.
   If the widths defy the rules for the legal characters, it discards the
   oldest bar/space and tries again
- the fourth looks at groups of characters to decide if they fit the
   form of a label -- correct start character, number of characters,
   check digit, stop character, etc.  If not, then the oldest character
   must be rejected (which means the oldest bar/space must be rejected
   in the *third* task that feeds this.  It also applies more "global"
   tests in an attempt to discard dubious data (goal is to achieve a very
   high "first pass read rate" but an even HIGHER *accuracy* level!).  So,
   it looks at things like how "fast" the label passed the point scanner
   for each of the characters and argues as to whether it is possible
   for that set of scanning speeds to be encountered "in such rapid
   succession".  E.g., if the first character appears to have been scanned
   at a rate of 10 inches per second (based on the time-widths of the
   bars and spaces that it is composed of) but the second character (one
   tenth of an inch from the start of the first!) indicates a scanning speed
   of 80 ips, we know something just isn't right and can discard the
   oldest character, etc.
- Finally, the fifth level takes "whole labels" and tries to concatenate
   them into "super labels" by recognizing certain start-stop character
   combinations AND the time (physical distance between the end of one
   and the start of the next) to see if they conform to a grammar that
   allows them to be combined into a single, continuous label (with the
   EMBEDDED start-stop characters elided)

On top of all this, you're also looking at the data in the context of it
being representative of a label scanned *backwards* -- so, the oldest
bar/space may, in fact, be the LAST one in the label, part of the LAST
character 9stop character), etc.

You can write this as one giant piece of spaghetti code.  And, spend
a boatload of time trying to get it to work RELIABLY (note that you
have to allow a label to be scanned at ANY time, not just when the
user tells you "I'm going to scan a label, now!").  So, testing
is an abysmal way of assuring yourself that the code REALLY works!

Prove it on paper; verify it in the lab!

> Having a multitask scheduler does not mean you don't use loops. You do
> of course - practically always. You just don't have to care about what
> the scheduler gives you in every subroutine you write - just call the
> "task exit for rescheduling" call when your code has to wait. If you
> don't have the scheduler you will have to care about this every step of
> the way, make sure you know where your current stack pointer is
> (subroutine calls; then a subroutine which exits cannot be just
> called from any nesting level etc. etc.).

When you can *afford* a more "flush" environment, I agree that it
makes life a *lot* easier; you don't have to think about how many CPU
cycles you've burned since you last yield()-ed ("Am I starving some
task -- that I don't want to be aware of! -- that really NEEDS the
CPU more than me?").  You don't have to refactor the design as you add
tasks/complexity, etc.

You just concentrate on the individual "jobs" that need to be done.

But, what I'm attempting to show with my example is that you don't
have to make it an all-or-nothing decision; you can still avail
yourself of a multitasking environment (including other "services"
that a real OS would provide) even without all the resources that
you would otherwise ASSUME were needed!

Spaghetti code is never justified, IMO.  Even tiny PICs can benefit
from more structured execution environments.

> If we really have to count the bytes of RAM - let us say we turn the
> clock 25 years back - we can statically assign as much stack as needed
> to each task. We may find out that splitting in 3 tasks can at
> times _save_ memory above a certain complexity...
>
> I thought we'd be done with counting for days every byte by now,

There are still a lot of designs that pinch pennies.  The LORAN
plotter I mentioned ran in 12K of CODE and 256 bytes of RAM.
Back when 2716's were $50/each.  We actually went through the
code to pull out a few hundred bytes by mapping the most frequent
subroutine CALL's (a 3 byte operation) to ReSTart instructions
(one byte SWI's, of a sort).  Silly to put an extra $50 into the
device if it wasn't needed!

Nowadays, there's a lot of cruft added to many products that eats
up a lot of resources before you write your first byte of code.
E.g., communication stacks (ethernet, bluetooth, USB, etc.)
are now common whereas ages ago it was a hundred bytes to handle
a UART!

> last "small" MCU I used was a coldfire in tqfp100 with 16k RAM and
> a sort of 68000 running at 80 MHz.... I just copied and slightly
> adapted the initial (68340 from 1994) DPS scheduler and trap handler,
> cost me virtually nothing.
>
> http://tgi-sci.com/dsv/swgboard.gif
> http://tgi-sci.com/dsv/swg800.gif

Sheesh!  Couldn't you have used a RULER to line up the mounting screws??
<grin>

> http://tgi-sci.com/misc/PICT6999.avi
> http://tgi-sci.com/tgi/auxhv.htm
> No picture of the last, this MCU replaced a huge computer board
> in an 8 channel Ortec alpha counting system so they could use
> two netmca-s to simultaneously select any two vacuum chhambers
> to count, measure the vacuum and plenty of other internals, the
> analog part was intact).
>
> And such an MCU costs well below $10 at Mouser or the likes for
> a single piece....

Yes, but there are complete products that *sell* for less than that!
E.g., I can buy a BT stereo headphone for $5 -- and a FEW people
in the distribution chain are making money on that!  :-/  If
you are looking to create a "consumable" (disposable) product,
then you still *do* need to pinch pennies!

(My speech synthesizer has to fit *inside* something like that ALONGSIDE
its existing functionality and at a comparable price point)

OTOH, there are far too many fun/interesting things that are just not
practical to undertake when hobbled with a resource-starved environment.
And, once you get beyond a certain cost/complexity, the *added* costs
of moving to even richer execution environments is insignificant!

E.g., I recently doubled my clock speed (500M to 1G) and quadrupled
the number of cores in the design.  And, its still laughably "cheap"!

[toc] | [prev] | [next] | [standalone]


#24446

FromLes Cargill <lcargill99@comcast.com>
Date2016-06-29 11:36 -0500
Message-ID<nl0t75$3t5$1@dont-email.me>
In reply to#24421
Dimiter_Popoff wrote:
> On 28.6.2016 г. 17:40, Tim Wescott wrote:
>> On Tue, 28 Jun 2016 06:20:43 +0300, Dimiter_Popoff wrote:
>>
>>> On 28.6.2016 г. 05:54, Simon Clubley wrote:
>>>>
>>>   > .....
>>>> I still think that's a polling loop because you are reaching out to the
>>>> sensor and asking it for it's current value.
>>>
>>> "Polling" in programming means "as opposed to interrupt handling".
>>> How is this opposed to "interrupt handling".
>>>
>>> What you suggest to be polling is simply a loop of calls to subroutines.
>>> A "call loop" is what describes it - although it does not matter a lot
>>> what word is used as long as it is not an already widely accepted one
>>> like "polling" which you want to redefine. Nothing wrong with that of
>>> course - as long as you don't have to communicate with other people
>>> using your redefined term.
>>>
>>> So much talk about so little :-). Although Tim's topic idea worked,
>>> produced quite a discussion.
>>
>> Well, I was hoping for a name of a design pattern, and I'm still not
>> happy about my choices.  So from that perspective it's a wash.
>>
>> "Super loop" seems closest, but it seems to more capture the notion of
>> _always_ executing A, B, C, rather than executing only those bits that
>> are ready.
>>
>
> I encounter the "super loop" term for the first time here, but why not.
> Although I see nothing "super" about it, to me this is still an endless
> loop of calls to subroutines either of which may opt to do something
> or to just return if it has nothing to do.
> But like I said earlier I have almost never used this approach, it
> smells of oversimplifying - thus costing more than a decent scheduler
> does. Implement loops, state machines etc. as you like within tasks
> but having a true - preemptive allowing cooperative operation- scheduler
> costs very little in both machine resources and effort to put together
> so I see no point in trying to avoid it.
>

Other than for ISRs, you really don't *need* preemption. I once built
a proto-RTOS on top of DOS whilst waiting for the hardware, back
in the stone age.

This allowed getting most of the work done.

It was initially configured as cooperative multitasking. I put a task 
switch in the timer ISR and got that working. It made nothing
particularly better nor worse. But of course, I had the thing working
as a fully cooperative multitasker first.

But the experience of doing that made me rather queasy about the very 
concept of preemption. Randomly yoinking the current task based on
timer events seems a curious thing when you've A/B compared them.

> Dimiter
>
> ------------------------------------------------------
> Dimiter Popoff, TGI             http://www.tgi-sci.com
> ------------------------------------------------------
> http://www.flickr.com/photos/didi_tgi/
>

-- 
Les Cargill

[toc] | [prev] | [next] | [standalone]


#24449

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-29 09:55 -0700
Message-ID<nl0ui8$8qv$1@dont-email.me>
In reply to#24446
On 6/29/2016 9:36 AM, Les Cargill wrote:
> Dimiter_Popoff wrote:
>> On 28.6.2016 г. 17:40, Tim Wescott wrote:
>>> On Tue, 28 Jun 2016 06:20:43 +0300, Dimiter_Popoff wrote:
>>>
>>>> On 28.6.2016 г. 05:54, Simon Clubley wrote:
>>>>>
>>>>   > .....
>>>>> I still think that's a polling loop because you are reaching out to the
>>>>> sensor and asking it for it's current value.
>>>>
>>>> "Polling" in programming means "as opposed to interrupt handling".
>>>> How is this opposed to "interrupt handling".
>>>>
>>>> What you suggest to be polling is simply a loop of calls to subroutines.
>>>> A "call loop" is what describes it - although it does not matter a lot
>>>> what word is used as long as it is not an already widely accepted one
>>>> like "polling" which you want to redefine. Nothing wrong with that of
>>>> course - as long as you don't have to communicate with other people
>>>> using your redefined term.
>>>>
>>>> So much talk about so little :-). Although Tim's topic idea worked,
>>>> produced quite a discussion.
>>>
>>> Well, I was hoping for a name of a design pattern, and I'm still not
>>> happy about my choices.  So from that perspective it's a wash.
>>>
>>> "Super loop" seems closest, but it seems to more capture the notion of
>>> _always_ executing A, B, C, rather than executing only those bits that
>>> are ready.
>>>
>>
>> I encounter the "super loop" term for the first time here, but why not.
>> Although I see nothing "super" about it, to me this is still an endless
>> loop of calls to subroutines either of which may opt to do something
>> or to just return if it has nothing to do.
>> But like I said earlier I have almost never used this approach, it
>> smells of oversimplifying - thus costing more than a decent scheduler
>> does. Implement loops, state machines etc. as you like within tasks
>> but having a true - preemptive allowing cooperative operation- scheduler
>> costs very little in both machine resources and effort to put together
>> so I see no point in trying to avoid it.
>>
>
> Other than for ISRs, you really don't *need* preemption. I once built
> a proto-RTOS on top of DOS whilst waiting for the hardware, back
> in the stone age.
>
> This allowed getting most of the work done.
>
> It was initially configured as cooperative multitasking. I put a task switch in
> the timer ISR and got that working. It made nothing
> particularly better nor worse. But of course, I had the thing working
> as a fully cooperative multitasker first.
>
> But the experience of doing that made me rather queasy about the very concept
> of preemption. Randomly yoinking the current task based on
> timer events seems a curious thing when you've A/B compared them.

Preemption isn't just "a timer interrupt" but, rather, anything that
causes "something more important" to be invoked (scheduled) instead
of the currently executing task.

I.e., an ISR is a preemptive task.

An ISR can signal an event (or other OS-involved mechanism) that, in
turn, causes something that might be blocking, currently, to begin
execution -- without waiting for the currently executing task to
decide when an appropriate time to yield the processor might be.

[Should the executing task *poll* the event flag mentioned above to
decide when some other task is probably ready and waiting for THAT event?
Should each task know the needs of other concurrent tasks??]

The advantage of preemption is that tasks *don't* have to be considerate
of the needs of other tasks -- unlike the MTX I illustrated, here, which
must be *obsessed* with the needs of other tasks!

A fully preemptive MTOS typically also exploits EVERY possibility of
rerunning the scheduler, not just at jiffy's.  E.g., if a task adjusts
its priority downward, a reschedule() should occur (because some other
higher priority task may be waiting to run and prohibited from doing
so solely by the previously higher priority of the currently
executing task.

Note that preemption can also extend *into* the kernel -- whereby the
kernel itself can be preempted (by other aspects of itself).

Developing under a preemptive MTOS requires a different discipline;
as does developing under a cooperative MTOS.  For projects of substance,
it is usually too difficult to obtain maximum performance from a system
if you are charged with manually yielding control -- the system's
complexity makes it impractical for you to keep track of everything that
*might* be happening ("where *might* task32 be in its execution, now?")

[Again, that's why the MTX I've illustrated keeps the context switch
costs so lightweight; so you aren't concerned about yielding *often*
and gratuitously]

[toc] | [prev] | [next] | [standalone]


Page 4 of 10 — ← Prev page 1 2 3 [4] 5 6 … 10  Next page →

Back to top | Article view | comp.arch.embedded


csiph-web