Recently I have mostly been doing architecture, management, marketing and sales tasks, with the occasional programming interlude, mostly fixing bugs. However, for the last three days I have worked on a new mbeddr feature: support for concurrency. In particular, I have added the following features to mbeddr C:
* Tasks that contain executable code that is to be scheduled concurrently
* Cyclic tasks that are executed with some specified period and offset
* Blocking tasks that are allowed to block their execution and reschedule themselves
* An event mechanism that can be used to signal between tasks (waiting up blocked tasks)
* Shared variables, plus an 'atomic' statement that provides locks to the shared variables (using global lock ordering to prevent races)
* Data queues for communication between tasks, with nice APIs that provide locks (non-blocking and blocking variants).
I have built the language extensions, the type system, IDE support, generation to a pthreads-based implementation plus tests for the type system and the semantics in 25 hours! There are still a few open language design questions that may need revisiting, but that low number is nonetheless a clear testament to the productivity of MPS.
Let me explain where this productivity comes from. mbeddr already has a language extension for queues. I reused this queue extension when building the concurrent queues used in the concurrency extension. In particular, I designed an 'enqueue' and 'dequeue' statement that takes care of locking the queue itself. To do this, I relied on the 'atomic' statement I built earlier to coordinate access to shared variables. So in building the extension for queue-based communication between tasks, I reused other extensions I built earlier: the queue extension itself plus the atomic statement for coordinating access to shared variables. And of course the stuff runs inside of tasks, reusing the scheduling. Later I built blocking read access to queues: when grabbing an element from the queue, the task blocks until an element is available. To build this, I reused the event mechanism I built earlier.
Here is the kicker: in both cases, the tests worked correctly on the first try! The generators ran through, the code compiled successfully and the tests ran through.
So why is this interesting? I think it is interesting for two reasons. First, I did "test-driven language development". I started with the language syntax (if you will, the API of the to-be-built system). Then I wrote type system tests that asserted the error messages I wanted to get from the IDE. I then implemented the type checks to satisfy these tests. Next I wrote tests for the execution semantics. They failed, because I had no generators yet. I then filled in the generators to generate low-level C code from the new concurrency extensions. So test-driven language development is a reality with MPS.
Second, I stacked higher level extensions on lower-level extensions. This allowed me to reuse the generators for the lower-level extensions, making the generators for my high-level concurrency extensions much simpler (this is the reason that they worked on first try). Stacking abstractions is not a new idea, of course. Computer science is all about that. However, it is remarkable that MPS lets you do this with languages (syntax, type systems, IDE support, and, importantly, generators). And all while keeping the language definitions modular! This is a major ingredient to the productivity afforded by MPS.
There is a third important aspect of this exercise: I finally got to program a new mbeddr feature in one go. This was a lot of fun. Seems I am still a programmer after all :-)
If you want to check out the code, go to the mbeddr repository, check out the 'concurrency' branch, open the 'com.mbeddr.ext' project and look at the concurrency folder. It's still a prototype, but you can certainly inspect the stuff I wrote about here. Stay tuned for more news on concurrency support in mbeddr.
"My car was tracking the car in front of me to successfully steer, but I was going slower and that car eventually drifted far ahead of me. Shortly after that, another car was coming in my car's direction from the opposite side of the road. I can only guess at what happened next. My car apparently thought the oncoming car was supposed to be followed, and suddenly veered to the left, crossing the double-yellow road divider line right into its path. Had I not reacted quickly to jerk the steering wheel in the opposite direction, a devastating head-on collision would have occurred." Forget Tesla's driver - he made his choice to trust his life to Musk's AI. Think about the other car. Did its driver have a choice?
- Saint Petersburg State UniversityComputer Science, 2001 - 2006
- 239School, 1997 - 2001
- JetBrainsProject Manager/Lead Developer/Senior Developer/Developer/Intern, 2003 - present
NEWSru.co.il :: Новости Израиля и мира. События на Ближнем Востоке.
Новости Израиля на NEWSru.co.il. Лучшие фото и видео дня. Политика, Экономика, Криминал, Культура, Религия, Спорт.
VMware Virtualization Software for Desktops, Servers & Virtual Machi...
Deliver IT as a Service and reduce costs with a self-managed virtual infrastructure. Gain greater efficiency and agility while retaining con
Google Launches QR Code-Based Login Security Measure
Google has released a new way to securely log into Google accounts on public computers. Using a smartphone, scan the QR code generated at ac