A

Adam Dunkels

dunkels.com · Personal blog · on HN since 2013

Adam Dunkels, an embedded systems researcher and creator of Contiki OS, writes about protothreads and tiny TCP/IP stacks in C.

What HN saysCommenters treat Protothreads as an embedded classic and call it simple and beautiful, linking its expansion page to explain the switch/case trick.
43HN people shared it
35linked it in comments
23stories submitted
527story points
5 months agolast shared
2013people per year2026

Most-shared posts

  1. 1
    ProtoThreads: Lightweight, Stackless Threads in C
    20 people · 216 points · first shared 2013 · 44 comments on HN
  2. 2
    Expansion
    10 people · first shared 2014
  3. 3
    Protothreads: Lightweight Stackless Threads in C
    3 people · 163 points · first shared 2013 · 42 comments on HN
  4. 4
  5. 5
    Toothpaste Null-Terminator
    2 people · 96 points · first shared 2022 · 76 comments on HN
  6. 6
    Software
    2 people · first shared 2021
  7. 7
    Twip
    2 people · first shared 2021
  8. 8
  9. 9
    A Simple Way to Pitch Ideas
    1 people · 3 points · first shared 2023 · discussion on HN
  10. 10
    How to Use Git diff with an sqlite3 Database
    1 people · 3 points · first shared 2024 · discussion on HN
  11. 11
  12. 12
  13. 13
    Can We Vibe Code a Smart Home Device with Matter?
    1 people · 2 points · first shared 2026 · discussion on HN
  14. 14
  15. 15

What HN people wrote when they linked it

azubinski · 2023-07-19
It's different and very old story. Protothreads are classic now: https://dunkels.com/adam/pt/index.html Contiki OS is also a piece of embedded development classic: https://en.wikipedia.org/wiki/Contiki In general, it's more about syntax than semantics. Semantics is generally difficult and rarely changes.
j1elo · 2020-05-25
Don't miss out on the brilliant link at the bottom - Adam Dunkels' Protothreads - Lightweight, Stackless Threads in C also uses nested switch/case statements [1]. I learned about the theory with it, and used his library to implement cooperative multitasking on a bare metal embedded AVR C project. I wrote a task manager and dispatcher based on Protothreads, and that effort was what later made it simple for me to understand the JS async/await paradigm that would appear under my radar a couple years later. EDIT to add that I think the concepts might still apply, since these days I've seen things like stackless async coroutines discussed for Rust... didn't study those in detail yet, but I wouldn't be surprised if the basic concepts are the same. [1]: Current website: http://dunkels.com/adam/pt/
snops · 2020-04-07
You can use Protothreads[1] for this which work on anything that runs C, as they are just using setjmp/longjmp. I would recommend FreeRTOS instead, as it has proper prempetive scheduling, context switching and wide debugger support. It's actually only 4 files[2] so not very heavyweight in either memory or stuff to learn, and has decent abstractions for cross thread communication (queues etc). Then you can write continuous code and use preemption, rather than have to code everything as a state machine and co-operatively schedule, which is painful sometimes. [1] http://dunkels.com/adam/pt/ [2] https://www.freertos.org/Creating-a-new-FreeRTOS-project.html
jlundberg · 2019-05-16
The following page describes the implementation details: http://dunkels.com/adam/pt/expansion.html
josephg · 2017-02-03
Whoa, PT is fantastic. A full explanation of how it works is here: http://dunkels.com/adam/pt/expansion.html Its actually a really simple and beautiful. I worry that we give up a lot of this sort of flow expressiveness in more modern languages like Rust.
rdtsc · 2013-10-16
I got to about 500K processes on Erlang's VM on an i7 with lots of memory. These people people got up to 2M concurrent TCP connections http://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/ And on top of it, it is using isolated heaps. That is beautiful I think. Completely concurrent GC is beautiful. I know Erlang syntax is not to for everyone's taste (I do like it though). There is also Elixir (http://elixir-lang.org/). But the underlying BEAM VM is an awesome piece of technology. > The thought was to have a billion threads on a SPARCStation 10 There are some green-thread C libraries I've been playing with, like Protothreads ( http://dunkels.com/adam/pt/index.html ) and libconcurrency ( https://code.google.com/p/libconcurrency/ ) I think they use setjump/longjump trick. Some use setcontext()/getcontext() POSIX call. I still like Erlang VM best.
vanderZwan · 2025-07-14
This is Céu[0] erasure! ... I'm joking, I'm joking, although I do think it deserves a mention. Seriously though, neat library! It took me a moment to realize that everything with a pa_ prefix is a macro, for the dumb reason of being used to only see those in ALL_CAPS. Not saying you can't use lower-case macros but I think a short sentence mentioning it before the demo code, and with a "see the protothread under the hood page[1] for an explanation of how it generally works" would help a lot with demystifying the code for people unfamiliar with the concepts involved. [0] https://ceu-lang.github.io/ [1] https://dunkels.com/adam/pt/expansion.html
jacobmarble · 2024-12-19
I've been using protothreads on the RP2040 (Pico MCU) for task management. https://dunkels.com/adam/pt/ The extensions available from Hunter Adams at Cornell are also very useful. In particular, PT_YIELD_INTERVAL() has been very useful for me. https://people.ece.cornell.edu/land/courses/ece4760/RP2040/C_SDK_proto…
sargstuff · 2024-10-21
?? Duff's Device[0] theme song?? 10b integers get pushed into an array. Does one need an unfold operation to C the union of (&*p) bits get "twidded n by n, ..." and 'ants go marching n x n' [1]. Couldn't find an appropriate utf-32 glyph for the base case. Does the 'BOOM' happen at 0, NULL or NILL? ------ Limited HN ability to Hollerith when there's to much Babbage[2], (aka insufficient HN article space), for Simon/Garfunkel electric glow wall for the perl camel example. ------ [0]: duff's device : https://en.wikipedia.org/wiki/Duff%27s_device proto threads : https://dunkels.com/adam/pt/ coroutines : http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html [1] : file:///home/surf/Downloads/counting-and-math-rhymes-002-the-ants-go-marching.pdf [2] : https://engines.egr.uh.edu/episode/1145
throwawayabcdef · 2024-09-06
see also uip and contiki as well as the other creations from Mr. Dunkles: https://dunkels.com/adam/software.html
crabmusket · 2024-02-26
I was so sure this was about protothreads til I remembered its name. https://dunkels.com/adam/pt/
jamesmunns · 2023-09-11
From a net-effect standpoint, Rust's implementation of async/await is fairly similar to protothreads, which were used even on smaller AVR and MSP430 targets where rtos threads weren't practical. That being said, protothreads were implemented using wildly cursed C macros, and offered none of the safety guardrails that Rust has, nor the ergonomics, and had some insane constraints, like "you can't use local variables at all, only statics" because like rust, they were stackless coroutines that meant you would have no control of the stack across await points. If you were VERY CAREFUL, you could get the same lightweight concurrency with almost the same fundamental model. Woe be on you if you ever had to debug though. edit - here's a look at how protothreads were expanded: https://dunkels.com/adam/pt/expansion.html
riedel · 2023-09-02
The IoT OS contiki made heavy use of protothreads, which are also Duff's device style coroutines [0] [0] https://dunkels.com/adam/pt/examples.html
benhoyt · 2023-07-13
This is a fascinating concept that I've written about before: "C#’s async/await compared to protothreads in C++". [1] Both async/await in C# and protothreads [2] in C unroll control flow to a state machine. In C, this is done using some simple but crazy macros using the fact that you can interleave switch statements with other control flow (ala Duff's Device [3]). Many years ago I ported Adam Dunkel's protothreads library to C++ [4]. You can use C protothreads in C++ directly, of course, but it's a bit nicer to use classes. [1] https://blog.brush.co.nz/2012/11/async-await-protothreads-cpp/ [2] http://dunkels.com/adam/pt/ [3] https://en.wikipedia.org/wiki/Duff%27s_device [4] https://github.com/benhoyt/protothreads-cpp/
samsquire · 2023-03-13
Thanks for this. There is a really good blog post to understand coroutines from an assembly perspective here: https://blog.dziban.net/coroutines/ I ported the intel assembly syntax in that blog post to at&t syntax and assembled it with GNU Assembler https://github.com/samsquire/assembly as coroutines.S there is also protothreads and Tina http://dunkels.com/adam/pt/ https://github.com/slembcke/Tina
zserge · 2023-02-01
The wiki page says it all, but I'll highlight - Contiki has been written by Adam Dunkels, the one who invented Protothreads (coroutines using Duff's Device), uIP, lwIP and a TCP stack that fits into a single tweet - http://dunkels.com/adam/twip.html
butterisgood · 2021-11-19
Duff's device has been used for more than loop unrolling though. https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html which inspired: http://dunkels.com/adam/pt/ And that stuff is just neat!
rramadass · 2021-06-28
Take a look at Adam Dunkels' lwIP and uIP - http://dunkels.com/adam/software.html. Also Jeremy Bentham's TCP/IP Lean: Web Servers for Embedded Systems is pretty good.
felixr · 2020-05-24
Another interesting approach to lightweight cooperative threading is Protothreads [1][2]. Those are however stackless and make use of duff's device for the implementation; rather, than setjmp/longjmp. [1] http://dunkels.com/adam/pt/ [2] https://en.wikipedia.org/wiki/Protothread
kitd · 2019-09-22
As explained here [1], it uses a variation of Duff's device. So the claim that Protothreads were invented by Adam Dunkels with support from Oliver Schmidt is slightly misleading IMHO. But fair play for turning it into a working library. [1] http://dunkels.com/adam/pt/expansion.html
saagarjha · 2019-05-16
These seem to work with some clever (ab)use of switch statements: http://dunkels.com/adam/pt/expansion.html
dpwm · 2019-05-11
You may be in for a treat if you haven't already come across protothreads [0]. They provide a form of stack-less, co-operative multi-threading and are aimed at microcontrollers. I came across them by chance, and have used them on an ESP8266 – it's really made everything feel much more clear and far less confusing. You do need to wrap your head around the trick, but that really shouldn't take long. You also need to put any state that you expect to be preserved between calls of the function into something more persistent – just like with state machines. The examples all use static variables, but I am happier using a struct pointer to maintain state. [0] http://dunkels.com/adam/pt/
VygmraMGVl · 2019-02-07
Protothreads is a library implementation of this trick. In fact, the protothreads creator even references the linked site in their explanation of protothreads (very last paragraph) [1]. [1] http://dunkels.com/adam/pt/expansion.html
mcwoods · 2019-02-07
Isn't this just an application of a protothread[1]? There are implementations that use the GCC goto and label pointer, which then avoid the need for a switch statement. [1] http://dunkels.com/adam/pt/
dimatura · 2018-10-29
Yes, it's basically the idea in Duff's device. Protothreads (http://dunkels.com/adam/pt/) uses a pretty similar trick.
buserror · 2018-01-08
Personally I no longer use pure state machines, as they can become beasts and end up being a royal pain to maintain. Instead, I use 'duff devices' variations of it (in C) which breaks down the machine into code that looks 'linear' enough, but is in fact, a state machine without the drawbacks. I've implemented quite a few protocol stacks using that 'trick' and it's still very nice to read/maintain -- the good thing is that it roughtly looks like a coroutine/thread, without any runtime requirements, so will work just fine on embedded systems as well. Same as coroutine/state machines, don't make your 'states' too 'long' or CPU intensive, you'll have the same consequences. There's an implementation floating around called 'protothreads' [0], but you can really do pretty much the same with a handful of macros. [0]: http://dunkels.com/adam/pt/
arianvanp · 2017-02-02
https://github.com/arianvp/MidiProject/blob/master/MidiProject.ino I use duffs device to concurrently read and debounce multiple inputs in my old dj midi controller http://dunkels.com/adam/pt/expansion.html
huntergoldstein · 2017-02-02
To add onto this: - http://dunkels.com/adam/pt/ Even though it is an abuse, these sorts of libraries are fascinating to me: making use of language features in unexpected (most likely unintended) ways.
nkurz · 2014-06-06
Thank you, that additional information is helpful: http://dunkels.com/adam/dunkels06protothreads.pdf I presume you are the same Muneeb Ali listed as co-author? The website mentioned in your profile seems to be down.
muneeb · 2014-06-06
The SenSys'06 paper has all the details: http://dunkels.com/adam/pt/publications.html The context for a lot of "wireless sensor networks" discussion in the paper is that Adam's research group was primarily focusing on sensor networks at the time.

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close