pt-doc.txt 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /**
  2. \defgroup pt Protothreads
  3. Protothreads are a type of lightweight stackless threads designed for
  4. severly memory constrained systems such as deeply embedded systems or
  5. sensor network nodes. Protothreads provides linear code execution for
  6. event-driven systems implemented in C. Protothreads can be used with
  7. or without an RTOS.
  8. Protothreads are a extremely lightweight, stackless type of threads
  9. that provides a blocking context on top of an event-driven system,
  10. without the overhead of per-thread stacks. The purpose of protothreads
  11. is to implement sequential flow of control without complex state
  12. machines or full multi-threading. Protothreads provides conditional
  13. blocking inside C functions.
  14. The advantage of protothreads over a purely event-driven approach is
  15. that protothreads provides a sequential code structure that allows for
  16. blocking functions. In purely event-driven systems, blocking must be
  17. implemented by manually breaking the function into two pieces - one
  18. for the piece of code before the blocking call and one for the code
  19. after the blocking call. This makes it hard to use control structures
  20. such as if() conditionals and while() loops.
  21. The advantage of protothreads over ordinary threads is that a
  22. protothread do not require a separate stack. In memory constrained
  23. systems, the overhead of allocating multiple stacks can consume large
  24. amounts of the available memory. In contrast, each protothread only
  25. requires between two and twelve bytes of state, depending on the
  26. architecture.
  27. \note Because protothreads do not save the stack context across a
  28. blocking call, <b>local variables are not preserved when the
  29. protothread blocks</b>. This means that local variables should be used
  30. with utmost care - <b>if in doubt, do not use local variables inside a
  31. protothread!</b>
  32. Main features:
  33. - No machine specific code - the protothreads library is pure C
  34. - Does not use error-prone functions such as longjmp()
  35. - Very small RAM overhead - only two bytes per protothread
  36. - Can be used with or without an OS
  37. - Provides blocking wait without full multi-threading or
  38. stack-switching
  39. Examples applications:
  40. - Memory constrained systems
  41. - Event-driven protocol stacks
  42. - Deeply embedded systems
  43. - Sensor network nodes
  44. The protothreads API consists of four basic operations:
  45. initialization: PT_INIT(), execution: PT_BEGIN(), conditional
  46. blocking: PT_WAIT_UNTIL() and exit: PT_END(). On top of these, two
  47. convenience functions are built: reversed condition blocking:
  48. PT_WAIT_WHILE() and protothread blocking: PT_WAIT_THREAD().
  49. \sa \ref pt "Protothreads API documentation"
  50. The protothreads library is released under a BSD-style license that
  51. allows for both non-commercial and commercial usage. The only
  52. requirement is that credit is given.
  53. \section authors Authors
  54. The protothreads library was written by Adam Dunkels <adam@sics.se>
  55. with support from Oliver Schmidt <ol.sc@web.de>.
  56. \section pt-desc Protothreads
  57. Protothreads are a extremely lightweight, stackless threads that
  58. provides a blocking context on top of an event-driven system, without
  59. the overhead of per-thread stacks. The purpose of protothreads is to
  60. implement sequential flow of control without using complex state
  61. machines or full multi-threading. Protothreads provides conditional
  62. blocking inside a C function.
  63. In memory constrained systems, such as deeply embedded systems,
  64. traditional multi-threading may have a too large memory overhead. In
  65. traditional multi-threading, each thread requires its own stack, that
  66. typically is over-provisioned. The stacks may use large parts of the
  67. available memory.
  68. The main advantage of protothreads over ordinary threads is that
  69. protothreads are very lightweight: a protothread does not require its
  70. own stack. Rather, all protothreads run on the same stack and context
  71. switching is done by stack rewinding. This is advantageous in memory
  72. constrained systems, where a stack for a thread might use a large part
  73. of the available memory. A protothread only requires only two bytes of
  74. memory per protothread. Moreover, protothreads are implemented in pure
  75. C and do not require any machine-specific assembler code.
  76. A protothread runs within a single C function and cannot span over
  77. other functions. A protothread may call normal C functions, but cannot
  78. block inside a called function. Blocking inside nested function calls
  79. is instead made by spawning a separate protothread for each
  80. potentially blocking function. The advantage of this approach is that
  81. blocking is explicit: the programmer knows exactly which functions
  82. that block that which functions the never blocks.
  83. Protothreads are similar to asymmetric co-routines. The main
  84. difference is that co-routines uses a separate stack for each
  85. co-routine, whereas protothreads are stackless. The most similar
  86. mechanism to protothreads are Python generators. These are also
  87. stackless constructs, but have a different purpose. Protothreads
  88. provides blocking contexts inside a C function, whereas Python
  89. generators provide multiple exit points from a generator function.
  90. \section pt-autovars Local variables
  91. \note
  92. Because protothreads do not save the stack context across a blocking
  93. call, local variables are not preserved when the protothread
  94. blocks. This means that local variables should be used with utmost
  95. care - if in doubt, do not use local variables inside a protothread!
  96. \section pt-scheduling Scheduling
  97. A protothread is driven by repeated calls to the function in which the
  98. protothread is running. Each time the function is called, the
  99. protothread will run until it blocks or exits. Thus the scheduling of
  100. protothreads is done by the application that uses protothreads.
  101. \section pt-impl Implementation
  102. Protothreads are implemented using \ref lc "local continuations". A
  103. local continuation represents the current state of execution at a
  104. particular place in the program, but does not provide any call history
  105. or local variables. A local continuation can be set in a specific
  106. function to capture the state of the function. After a local
  107. continuation has been set can be resumed in order to restore the state
  108. of the function at the point where the local continuation was set.
  109. Local continuations can be implemented in a variety of ways:
  110. -# by using machine specific assembler code,
  111. -# by using standard C constructs, or
  112. -# by using compiler extensions.
  113. The first way works by saving and restoring the processor state,
  114. except for stack pointers, and requires between 16 and 32 bytes of
  115. memory per protothread. The exact amount of memory required depends on
  116. the architecture.
  117. The standard C implementation requires only two bytes of state per
  118. protothread and utilizes the C switch() statement in a non-obvious way
  119. that is similar to Duff's device. This implementation does, however,
  120. impose a slight restriction to the code that uses protothreads in that
  121. the code cannot use switch() statements itself.
  122. Certain compilers has C extensions that can be used to implement
  123. protothreads. GCC supports label pointers that can be used for this
  124. purpose. With this implementation, protothreads require 4 bytes of RAM
  125. per protothread.
  126. @{
  127. */
  128. /** @} */