test

Dependencies:   mbed MMA8451Q

Committer:
hodgins
Date:
Thu Jan 24 06:35:38 2019 +0000
Revision:
0:e541909ea6b0
test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hodgins 0:e541909ea6b0 1 // Protothread class and macros for lightweight, stackless threads in C++.
hodgins 0:e541909ea6b0 2 //
hodgins 0:e541909ea6b0 3 // This was "ported" to C++ from Adam Dunkels' protothreads C library at:
hodgins 0:e541909ea6b0 4 // http://www.sics.se/~adam/pt/
hodgins 0:e541909ea6b0 5 //
hodgins 0:e541909ea6b0 6 // Originally ported for use by Hamilton Jet (www.hamiltonjet.co.nz) by
hodgins 0:e541909ea6b0 7 // Ben Hoyt, but stripped down for public release. See his blog entry about
hodgins 0:e541909ea6b0 8 // it for more information:
hodgins 0:e541909ea6b0 9 // http://blog.brush.co.nz/2008/07/protothreads/
hodgins 0:e541909ea6b0 10 //
hodgins 0:e541909ea6b0 11 // Visual Studio users: There's a quirk with VS where it defines __LINE__
hodgins 0:e541909ea6b0 12 // as a non-constant when you've got a project's Debug Information Format
hodgins 0:e541909ea6b0 13 // set to "Program Database for Edit and Continue (/ZI)" -- the default.
hodgins 0:e541909ea6b0 14 // To fix, just go to the project's Properties, Configuration Properties,
hodgins 0:e541909ea6b0 15 // C/C++, General, Debug Information Format, and change it to "Program
hodgins 0:e541909ea6b0 16 // Database (/Zi)".
hodgins 0:e541909ea6b0 17 //
hodgins 0:e541909ea6b0 18 // --------------------------
hodgins 0:e541909ea6b0 19 // Original BSD-style license
hodgins 0:e541909ea6b0 20 // --------------------------
hodgins 0:e541909ea6b0 21 // Copyright (c) 2004-2005, Swedish Institute of Computer Science.
hodgins 0:e541909ea6b0 22 // All rights reserved.
hodgins 0:e541909ea6b0 23 //
hodgins 0:e541909ea6b0 24 // Redistribution and use in source and binary forms, with or without
hodgins 0:e541909ea6b0 25 // modification, are permitted provided that the following conditions
hodgins 0:e541909ea6b0 26 // are met:
hodgins 0:e541909ea6b0 27 //
hodgins 0:e541909ea6b0 28 // 1. Redistributions of source code must retain the above copyright
hodgins 0:e541909ea6b0 29 // notice, this list of conditions and the following disclaimer.
hodgins 0:e541909ea6b0 30 // 2. Redistributions in binary form must reproduce the above copyright
hodgins 0:e541909ea6b0 31 // notice, this list of conditions and the following disclaimer in the
hodgins 0:e541909ea6b0 32 // documentation and/or other materials provided with the distribution.
hodgins 0:e541909ea6b0 33 // 3. Neither the name of the Institute nor the names of its contributors
hodgins 0:e541909ea6b0 34 // may be used to endorse or promote products derived from this software
hodgins 0:e541909ea6b0 35 // without specific prior written permission.
hodgins 0:e541909ea6b0 36 //
hodgins 0:e541909ea6b0 37 // This software is provided by the Institute and contributors "as is" and
hodgins 0:e541909ea6b0 38 // any express or implied warranties, including, but not limited to, the
hodgins 0:e541909ea6b0 39 // implied warranties of merchantability and fitness for a particular purpose
hodgins 0:e541909ea6b0 40 // are disclaimed. In no event shall the Institute or contributors be liable
hodgins 0:e541909ea6b0 41 // for any direct, indirect, incidental, special, exemplary, or consequential
hodgins 0:e541909ea6b0 42 // damages (including, but not limited to, procurement of substitute goods
hodgins 0:e541909ea6b0 43 // or services; loss of use, data, or profits; or business interruption)
hodgins 0:e541909ea6b0 44 // however caused and on any theory of liability, whether in contract, strict
hodgins 0:e541909ea6b0 45 // liability, or tort (including negligence or otherwise) arising in any way
hodgins 0:e541909ea6b0 46 // out of the use of this software, even if advised of the possibility of
hodgins 0:e541909ea6b0 47 // such damage.
hodgins 0:e541909ea6b0 48 //
hodgins 0:e541909ea6b0 49
hodgins 0:e541909ea6b0 50 #ifndef __PROTOTHREAD_H__
hodgins 0:e541909ea6b0 51 #define __PROTOTHREAD_H__
hodgins 0:e541909ea6b0 52
hodgins 0:e541909ea6b0 53 // A lightweight, stackless thread. Override the Run() method and use
hodgins 0:e541909ea6b0 54 // the PT_* macros to do work of the thread.
hodgins 0:e541909ea6b0 55 //
hodgins 0:e541909ea6b0 56 // A simple example
hodgins 0:e541909ea6b0 57 // ----------------
hodgins 0:e541909ea6b0 58 // class LEDFlasher : public Protothread
hodgins 0:e541909ea6b0 59 // {
hodgins 0:e541909ea6b0 60 // public:
hodgins 0:e541909ea6b0 61 // virtual bool Run();
hodgins 0:e541909ea6b0 62 //
hodgins 0:e541909ea6b0 63 // private:
hodgins 0:e541909ea6b0 64 // ExpiryTimer _timer;
hodgins 0:e541909ea6b0 65 // uintf _i;
hodgins 0:e541909ea6b0 66 // };
hodgins 0:e541909ea6b0 67 //
hodgins 0:e541909ea6b0 68 // bool LEDFlasher::Run()
hodgins 0:e541909ea6b0 69 // {
hodgins 0:e541909ea6b0 70 // PT_BEGIN();
hodgins 0:e541909ea6b0 71 //
hodgins 0:e541909ea6b0 72 // for (_i = 0; _i < 10; _i++)
hodgins 0:e541909ea6b0 73 // {
hodgins 0:e541909ea6b0 74 // SetLED(true);
hodgins 0:e541909ea6b0 75 // _timer.Start(250);
hodgins 0:e541909ea6b0 76 // PT_WAIT_UNTIL(_timer.Expired());
hodgins 0:e541909ea6b0 77 //
hodgins 0:e541909ea6b0 78 // SetLED(false);
hodgins 0:e541909ea6b0 79 // _timer.Start(750);
hodgins 0:e541909ea6b0 80 // PT_WAIT_UNTIL(_timer.Expired());
hodgins 0:e541909ea6b0 81 // }
hodgins 0:e541909ea6b0 82 //
hodgins 0:e541909ea6b0 83 // PT_END();
hodgins 0:e541909ea6b0 84 // }
hodgins 0:e541909ea6b0 85 //
hodgins 0:e541909ea6b0 86 class Protothread
hodgins 0:e541909ea6b0 87 {
hodgins 0:e541909ea6b0 88 public:
hodgins 0:e541909ea6b0 89 // Construct a new protothread that will start from the beginning
hodgins 0:e541909ea6b0 90 // of its Run() function.
hodgins 0:e541909ea6b0 91 Protothread() : _ptLine(0) { }
hodgins 0:e541909ea6b0 92
hodgins 0:e541909ea6b0 93 // Restart protothread.
hodgins 0:e541909ea6b0 94 void Restart() { _ptLine = 0; }
hodgins 0:e541909ea6b0 95
hodgins 0:e541909ea6b0 96 // Stop the protothread from running. Happens automatically at PT_END.
hodgins 0:e541909ea6b0 97 // Note: this differs from the Dunkels' original protothread behaviour
hodgins 0:e541909ea6b0 98 // (his restart automatically, which is usually not what you want).
hodgins 0:e541909ea6b0 99 void Stop() { _ptLine = LineNumberInvalid; }
hodgins 0:e541909ea6b0 100
hodgins 0:e541909ea6b0 101 // Return true if the protothread is running or waiting, false if it has
hodgins 0:e541909ea6b0 102 // ended or exited.
hodgins 0:e541909ea6b0 103 bool IsRunning() { return _ptLine != LineNumberInvalid; }
hodgins 0:e541909ea6b0 104
hodgins 0:e541909ea6b0 105 // Run next part of protothread or return immediately if it's still
hodgins 0:e541909ea6b0 106 // waiting. Return true if protothread is still running, false if it
hodgins 0:e541909ea6b0 107 // has finished. Implement this method in your Protothread subclass.
hodgins 0:e541909ea6b0 108 virtual bool Run() = 0;
hodgins 0:e541909ea6b0 109
hodgins 0:e541909ea6b0 110 protected:
hodgins 0:e541909ea6b0 111 // Used to store a protothread's position (what Dunkels calls a
hodgins 0:e541909ea6b0 112 // "local continuation").
hodgins 0:e541909ea6b0 113 typedef unsigned short LineNumber;
hodgins 0:e541909ea6b0 114
hodgins 0:e541909ea6b0 115 // An invalid line number, used to mark the protothread has ended.
hodgins 0:e541909ea6b0 116 static const LineNumber LineNumberInvalid = (LineNumber)(-1);
hodgins 0:e541909ea6b0 117
hodgins 0:e541909ea6b0 118 // Stores the protothread's position (by storing the line number of
hodgins 0:e541909ea6b0 119 // the last PT_WAIT, which is then switched on at the next Run).
hodgins 0:e541909ea6b0 120 LineNumber _ptLine;
hodgins 0:e541909ea6b0 121 };
hodgins 0:e541909ea6b0 122
hodgins 0:e541909ea6b0 123 // Declare start of protothread (use at start of Run() implementation).
hodgins 0:e541909ea6b0 124 #define PT_BEGIN() bool ptYielded = true; (void) ptYielded; switch (_ptLine) { case 0:
hodgins 0:e541909ea6b0 125
hodgins 0:e541909ea6b0 126 // Stop protothread and end it (use at end of Run() implementation).
hodgins 0:e541909ea6b0 127 #define PT_END() default: ; } Stop(); return false;
hodgins 0:e541909ea6b0 128
hodgins 0:e541909ea6b0 129 // Cause protothread to wait until given condition is true.
hodgins 0:e541909ea6b0 130 #define PT_WAIT_UNTIL(condition) \
hodgins 0:e541909ea6b0 131 do { _ptLine = __LINE__; case __LINE__: \
hodgins 0:e541909ea6b0 132 if (!(condition)) return true; } while (0)
hodgins 0:e541909ea6b0 133
hodgins 0:e541909ea6b0 134 // Cause protothread to wait while given condition is true.
hodgins 0:e541909ea6b0 135 #define PT_WAIT_WHILE(condition) PT_WAIT_UNTIL(!(condition))
hodgins 0:e541909ea6b0 136
hodgins 0:e541909ea6b0 137 // Cause protothread to wait until given child protothread completes.
hodgins 0:e541909ea6b0 138 #define PT_WAIT_THREAD(child) PT_WAIT_WHILE((child).Run())
hodgins 0:e541909ea6b0 139
hodgins 0:e541909ea6b0 140 // Restart and spawn given child protothread and wait until it completes.
hodgins 0:e541909ea6b0 141 #define PT_SPAWN(child) \
hodgins 0:e541909ea6b0 142 do { (child).Restart(); PT_WAIT_THREAD(child); } while (0)
hodgins 0:e541909ea6b0 143
hodgins 0:e541909ea6b0 144 // Restart protothread's execution at its PT_BEGIN.
hodgins 0:e541909ea6b0 145 #define PT_RESTART() do { Restart(); return true; } while (0)
hodgins 0:e541909ea6b0 146
hodgins 0:e541909ea6b0 147 // Stop and exit from protothread.
hodgins 0:e541909ea6b0 148 #define PT_EXIT() do { Stop(); return false; } while (0)
hodgins 0:e541909ea6b0 149
hodgins 0:e541909ea6b0 150 // Yield protothread till next call to its Run().
hodgins 0:e541909ea6b0 151 #define PT_YIELD() \
hodgins 0:e541909ea6b0 152 do { ptYielded = false; _ptLine = __LINE__; case __LINE__: \
hodgins 0:e541909ea6b0 153 if (!ptYielded) return true; } while (0)
hodgins 0:e541909ea6b0 154
hodgins 0:e541909ea6b0 155 // Yield protothread until given condition is true.
hodgins 0:e541909ea6b0 156 #define PT_YIELD_UNTIL(condition) \
hodgins 0:e541909ea6b0 157 do { ptYielded = false; _ptLine = __LINE__; case __LINE__: \
hodgins 0:e541909ea6b0 158 if (!ptYielded || !(condition)) return true; } while (0)
hodgins 0:e541909ea6b0 159
hodgins 0:e541909ea6b0 160 #endif // __PROTOTHREAD_H__