|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2018-8-9 18:44:03
|
显示全部楼层
我个人没有用过, 但是有人移值到CCS C, 没有后续的跟进, 有没有问题不知道, 根据移植的作者说,CCS C 并不能很好的支持原创的代码, 他是经过一番修改。
- /******************************************************************************
- * NAME: protothreads.h
- * AUTH: Jeremiah (Reworked from Adam Dunkel's code)
- * DESC: Provides a stackless, OS-less, low RAM implementation of cooperative
- * multithreading for the CCS compiler environment. Based off of the
- * protothreads library provided by Adam Dunkel, but with modifications
- * for the CCS compiler environment. Specifically:
- * 1. CCS doesn't support local continuations, so compiler extensions
- * are used instead. label_address() and goto_address()
- * 2. Removal of do{}while() loops as they generate compiler warnings
- * and are not needed for CCS.
- * 3. Changed PT_END() and PT_EXIT() to not reset the local
- * continuation but instead remember the thread finished.
- * 4. Re-orged a few macros to better optimize with CCS.
- * 5. Changed PT_YIELD_FLAG=0 to PT_YIELD_FLAG=PT_YIELD_FLAG in the
- * PT_END() macro
- * 6. Removed PT_THREAD() and replaced it with pt_ret_t
- * 7. Added (and defaulted to) the use of reference parameters since
- * those provide less code in most general scenarios. A #define
- * can be commented out to go back to pointers.
- * Copyright notice from Adam Dunkels code provided near the end of the
- * file.
- *
- * TYPES:
- * pt_t - Protothread context type
- * pt_ret_t - Protothread return type
- * PT_WAITING - Thread is waiting/blocking
- * PT_YIELDED - Thread yielded
- * PT_EXITED - Thread ended abnormally
- * PT_ENDED - Thread ended normally
- * pt_sem_t - Protothread semiphore type
- *
- * MACROS:
- * PT_INIT() - Must be called prior to scheduling a thread
- * PT_BEGIN() - Must be called at the beginning of a protothread.
- * PT_END() - Must be called at the end of a protothread (once)
- * PT_WAIT_WHILE() - Used to block a thread while a condition is TRUE
- * PT_WAIT_UNTIL() - Used to block a thread until a condition is TRUE
- * PT_YIELD() - Yields the current thread
- * PT_YIELD_WHILE() - Yields current thread while a condition is TRUE
- * PT_YIELD_UNTIL() - Yields current thread until a condition is TRUE
- * PT_RESTART() - Restarts the current thread
- * PT_EXIT() - Exits the current thread
- * PT_SCHEDULE() - Schedules a thread from a non-thread method
- * PT_WAIT_THREAD() - Spawns a child thread and waits on it to end
- * PT_SPAWN() - Same as PT_WAIT_THREAD() but with PT_INIT()
- * PT_SEM_INIT() - Initializes a semiphore
- * PT_SEM_WAIT() - Waits on a semiphore signal (decrements count)
- * PT_SEM_SIGNAL() - Sends a semiphore signal (increments count)
- *
- * COMPILED WITH: CCS PCWHD Revision 5.025
- *
- * HISTORY:
- * 02/20/2014 - JHB - Creation
- ******************************************************************************/
- #ifndef PROTOTHREADS_H
- #define PROTOTHREADS_H
- #nolist
- ///////////////////////////////////////////////////////////////////////////////
- //***************** File Option Settings ************************************//
- ///////////////////////////////////////////////////////////////////////////////
- //CCS specific - for use with reference parameters vs pointer parameters
- #define PT_USE_REFERENCES //comment this line out to use pointers
- #if defined(PT_USE_REFERENCES)
- #define PT_STRUCT_ELEM(st, e) ((st).e)
- #else
- #define PT_STRUCT_ELEM(st, e) ((st)->e)
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- //***************** Local Continuations (Compiler Specific) *****************//
- ///////////////////////////////////////////////////////////////////////////////
- //This section sets up some macros used by the protothreads interface. These
- //macros should not be used directly. They are merely tools for the
- //protothreads interface.
- //Variable typedef
- #if defined(__PCH__) || defined(__PCD__)
- typedef unsigned int32 lc_t;
- #else
- typedef unsigned int16 lc_t;
- #endif
- //Used to reset the local continuation
- #define LC_INIT(lc) lc = 0
- //Place in PT_BEGIN()
- #define LC_RESUME(lc) if(0 != lc){goto_address(lc);}
- //Used to create continuations
- #define LC_CONCAT_INNER(s1,s2) s1##s2
- #define LC_CONCAT(s1,s2) LC_CONCAT_INNER(s1,s2)
- #define LC_SET(lc) \
- LC_CONCAT(LC_LABEL, __LINE__): \
- (lc) = label_address(LC_CONCAT(LC_LABEL,__LINE__))
- //Place in PT_END()
- #define LC_END(lc)
- ///////////////////////////////////////////////////////////////////////////////
- //***************** Protothreads Interface **********************************//
- ///////////////////////////////////////////////////////////////////////////////
- //This is the meat of the file. Macros from here will be used to create and
- //manage protothreads.
- //Variable Typedefs
- typedef struct{
- lc_t lc;
- } pt_t;
- typedef enum{
- PT_WAITING = 0,
- PT_YIELDED = 1,
- PT_EXITED = 2,
- PT_ENDED = 3
- } pt_ret_t;
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_INIT
- // DESC: Initializes the control structure for a protothread. Must be called
- // prior to calling the thread.
- // IN: pt - protothread control structure
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt);
- // void main(){
- // pt_t pt;
- // PT_INIT(pt);
- // while(TRUE){PT_SCHEDULE(thread(pt));}
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_INIT(pt) LC_INIT(PT_STRUCT_ELEM(pt,lc))
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_BEGIN
- // DESC: Starts the control code for a thread. Must be called after variable
- // declarations and before function program code
- // IN: pt - protothread control structure
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt){
- // static int variable;
- // PT_BEGIN(pt);
- // variable = 10;
- // //do stuff here
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_BEGIN(pt) int1 PT_YIELD_FLAG = 1; LC_RESUME(PT_STRUCT_ELEM(pt,lc))
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_END
- // DESC: Ends the control code for a thread. Must be called at the end of
- // of a protothread. Leaves the tread with the PT_ENDED status.
- // IN: pt - protothread control structure
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // //do stuff here
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_END(pt) LC_SET(PT_STRUCT_ELEM(pt,lc)); \
- LC_END(PT_STRUCT_ELEM(pt,lc)); PT_YIELD_FLAG = PT_YIELD_FLAG;\
- return PT_ENDED
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_WAIT_WHILE
- // DESC: Blocks the current thread while a supplied condition is true
- // IN: pt - protothread control structure
- // condition - condition that causes blocking
- // OUT: NONE
- // NOTE: Example:
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // PT_WAIT_WHILE(0 == g_variable);
- // //do stuff here
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_WAIT_WHILE(pt, condition) \
- LC_SET(PT_STRUCT_ELEM(pt,lc)); if(condition) { return PT_WAITING;}
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_WAIT_UNTIL
- // DESC: Blocks the current thread until a supplied condition becomes true
- // IN: pt - protothread control structure
- // condition - condition that ends blocking
- // OUT: NONE
- // NOTE: Example:
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // PT_WAIT_UNTIL(0 != g_variable);
- // //do stuff here
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_WAIT_UNTIL(pt, condition) PT_WAIT_WHILE(pt, !(condition))
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_YIELD
- // DESC: Yields the current thread
- // IN: pt - protothread control structure
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt){
- // static int16 i;
- // PT_BEGIN(pt);
- // for(i=0; i<10000; i++){
- // //do something
- // PT_YIELD(pt);
- // }
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_YIELD(pt) \
- PT_YIELD_FLAG = 0; \
- LC_SET(PT_STRUCT_ELEM(pt,lc)); \
- if(0 == PT_YIELD_FLAG){ return PT_YIELDED; }
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_YIELD_WHILE
- // DESC: Yields the current thread while a supplied condition is true. Always
- // yeilds at least once.
- // IN: pt - protothread control structure
- // condition - condition that causes yielding
- // OUT: NONE
- // NOTE: Example:
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // PT_YIELD_UNTIL(0 != g_variable);
- // //do stuff here
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_YIELD_WHILE(pt, condition) \
- PT_YIELD_FLAG = 0; \
- LC_SET(PT_STRUCT_ELEM(pt,lc)); \
- if((0 == PT_YIELD_FLAG) || (condition)){ return PT_YIELDED; }
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_YIELD_UNTIL
- // DESC: Yields the current thread until a supplied condition becomes true.
- // Always yeilds at least once.
- // IN: pt - protothread control structure
- // condition - condition that ends yielding
- // OUT: NONE
- // NOTE: Example:
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // PT_YIELD_WHILE(0 != g_variable);
- // //do stuff here
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_YIELD_UNTIL(pt, condition) PT_YIELD_WHILE(pt, !(condition))
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_RESTART
- // DESC: Restarts the current thread back to the beginning
- // IN: pt - protothread control structure
- // OUT: NONE
- // NOTE: Example:
- // BOOLEAN function();
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // if(!function()){
- // PT_RESTART(pt);
- // }
- // //do stuff
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_RESTART(pt) PT_INIT(pt); return PT_WAITING
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_EXIT
- // DESC: Leaves the current thread with the PT_EXITED status
- // IN: pt - protothread control structure
- // OUT: NONE
- // NOTE: Example:
- // BOOLEAN function();
- // pt_ret_t thread(pt_t &pt){
- // PT_BEGIN(pt);
- // if(!function()){
- // PT_EXIT(pt);
- // }
- // //do stuff
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_EXIT(pt) LC_SET(PT_STRUCT_ELEM(pt,lc)); return PT_EXITED
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_SCHEDULE
- // DESC: Calls a thread from a non-thread function and compares it to
- // the current status.
- // IN: thread - protothread to call
- // OUT: BOOLEAN - True if not PT_EXIT or PT_END
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt);
- // void main(){
- // pt_t pt;
- // PT_INIT(pt);
- // while(PT_SCHEDULE(thread(pt)));
- // while(TRUE);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_SCHEDULE(thread) ((thread) < PT_EXITED)
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_WAIT_THREAD
- // DESC: Calls a child thread from a protothread function and waits until
- // the child thread ends. Must call PT_INIT() on child prior to calling
- // thread.
- // IN: pt - parent protothread control structure
- // thread - protothread to call
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t childThread(pt_t &pt);
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt){
- // pt_t child;
- // PT_BEGIN(pt);
- // PT_WAIT_UNTIL(0 != g_variable);
- // //do stuff here
- // PT_INIT(child);
- // PT_WAIT_THREAD(pt,childThread(child));
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE(pt,PT_SCHEDULE(thread))
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_SPAWN
- // DESC: Initializes a child thread context structure, calls the child
- // thread from a protothread function, and waits until the child thread
- // ends.
- // IN: pt - parent protothread control structure
- // child - child protothread control structure
- // thread - protothread to call
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t childThread(pt_t &pt);
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt){
- // pt_t child;
- // PT_BEGIN(pt);
- // PT_WAIT_UNTIL(0 != g_variable);
- // //do stuff here
- // PT_SPAWN(pt,child,childThread(child));
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_SPAWN(pt, child, thread) PT_INIT(child); PT_WAIT_THREAD(pt,thread)
- ///////////////////////////////////////////////////////////////////////////////
- //***************** Semiphore Interface *************************************//
- ///////////////////////////////////////////////////////////////////////////////
- //Variable typedefs
- typedef struct{
- unsigned int16 count;
- } pt_sem_t;
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_SEM_INIT
- // DESC: Initializes the a semiphore for a protothread.
- // IN: s - protothread semiphore structure
- // c - initial count
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt, pt_sem_t &sem);
- // void main(){
- // pt_t pt;
- // pt_sem_t sem;
- // PT_INIT(pt);
- // PT_SEM_INIT(sem,0);
- // while(TRUE){PT_SCHEDULE(thread(pt,sem));}
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_SEM_INIT(s, c) PT_STRUCT_ELEM(s,count) = c
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_SEM_WAIT
- // DESC: Forces the current thread to block until the semiphore has a non
- // zero count. Decrements the count afterwards.
- // IN: pt - protothread control structure
- // s - protothread semiphore structure
- // OUT: NONE
- // NOTE: Example:
- // pt_ret_t thread(pt_t &pt, pt_sem_t &sem){
- // PT_BEGIN(pt);
- // PT_SEM_WAIT(pt,sem);
- // //consume something
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_SEM_WAIT(pt, s) \
- PT_WAIT_UNTIL(pt, PT_STRUCT_ELEM(s,count) > 0); \
- --(PT_STRUCT_ELEM(s,count))
- ///////////////////////////////////////////////////////////////////////////////
- // NAME: PT_SEM_SIGNAL
- // DESC: Increments the semiphore count.
- // IN: pt - protothread control structure
- // s - protothread semiphore structure
- // OUT: NONE
- // NOTE: Example:
- // int g_variable = 0;
- // pt_ret_t thread(pt_t &pt, pt_sem_t &sem){
- // PT_BEGIN(pt);
- // while(0 == g_variable){
- // //produce some stuff
- // }
- // PT_SEM_SIGNAL(pt,sem);
- // PT_END(pt);
- // }
- ///////////////////////////////////////////////////////////////////////////////
- #define PT_SEM_SIGNAL(pt, s) ++(PT_STRUCT_ELEM(s,count))
- /*
- Copyright (c) 2004-2005, Swedish Institute of Computer Science.
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the Institute nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `AS IS' AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
- Author: Adam Dunkels
- */
- #list
- #endif
复制代码 |
|