Permalink
Browse files

Add a backlog of posts that I just forgot to commit

  • Loading branch information...
rtyler committed Mar 9, 2013
1 parent 7c93544 commit 30ab44c4c4759b5806e3b3ffd9cced29cc7f5108
@@ -0,0 +1,18 @@
+---
+layout: post
+title: "FOSDEM: Testing and Automation Dev Room CFP"
+tags:
+- fosdem
+- fosdem2013
+---
+
+For this next year's FOSDEM, I'm organizing the "Testing and Automation"
+developer room. And wouldn't you know it, we've just opened up our [Call for
+Participation](https://gist.github.com/4107243).
+
+I'm quite excited about the dev room, and look forward to reviewing and
+selecting the talks.
+
+Hope to see you there :)
+
+
@@ -0,0 +1,38 @@
+---
+layout: post
+title: Tyler goes to Yurp
+tags:
+- fosdem
+- fosdem2013
+- roadtrip
+- europe
+---
+
+As I mentioned in my [previous
+post](/2012/11/18/testing-automation-devroom-fosdem.html) I'll be going to
+[FOSDEM](http://fosdem.org) this year. Unlike last year, I will be spending a
+*lot* more time in Europe this time around.
+
+I will be arriving in Frankfurt on the 29th of January and spending a few days
+in Köln (Cologne). Naturally I will be in Brussels for FOSDEM for a couple
+days, but after that, I will be heading to
+[Berlin](https://en.wikipedia.org/wiki/Berlin) for a few weeks.
+
+I've already spent a good amount of time in Germany, so I won't be on the
+"tourist track", having seen most of the sights in Berlin already.
+
+So I will be working from Berlin, and my weekends and evenings will be open to
+as many meetups/hackathons as I can find. Even if you don't want to hang out
+(it's okay, I understand), but know of some good events in Berlin that are
+worth checking out, please send me an email (tyler@linux.com) and let me know!
+
+
+
+---
+
+
+*What the hell is Yurp?*
+
+Having spent a large amount of my time in the southern US, "Yurp" is how *far*
+too many southern people pronounce "Europe", including those in my own family.
+That's why I'm going to Yurp.
@@ -0,0 +1,227 @@
+---
+layout: post
+title: Safe, Dynamic Task Creation in Ada
+tags:
+- ada
+- programming
+---
+
+
+A few years ago,
+[Ada](https://secure.wikimedia.org/wikipedia/en/wiki/Ada_(programming_language)
+become my hobby/tinker programming language of choice, for a [number of
+reasons](/2010/12/06/ada-surely-you-jest-mr-pythonman.html), concurrency being
+one of them. In this post I'd like to walk you through an example of dynamic
+task creation in Ada, which uses `Ada.Task_Termination` handlers, a new feature
+in Ada 2005.
+
+(If you're familiar with Ada, you can skip this next section)
+
+---
+
+> *Note:* You can find all this code, and more in my
+[ada-playground](https://github.com/rtyler/ada-playground) repository on GitHub
+
+---
+
+Similar to C, Ada supports stack allocated variables as well as heap allocated
+variabels, it also defaults to stack allocation. For example:
+
+{% highlight ada %}
+
+procedure Main is
+ -- A stack allocated `Integer` object
+ Enough_Memory : constant Integer := 655360;
+begin
+ null;
+end Main;
+
+{% endhighlight %}
+
+If you wanted to allocate that `Integer` onto the heap, then you would use the
+`new` keyword:
+
+{% highlight ada %}
+
+procedure Main is
+ -- A heap allocated `Integer` pointer
+ Enough_Memory : access Integer := new Integer'(655360);
+begin
+ null;
+end Main;
+
+{% endhighlight %}
+
+
+I won't dive too much into the minutia of what is going on here, if you're not
+familiar with Ada already you can learn more about [access types on the Ada
+Programming
+Wikibook](http://en.wikibooks.org/wiki/Ada_Programming/Types/access). Basically
+we're heap allocating a new Integer and using an **access type** (aka: typed
+pointer) to keep track of it. Keen readers will notice we didn't do anything
+with that Integer access type, and we're _technically_ leaking the memory. To
+solve this we use the generic unit `Ada.Unchecked_Deallocation`, which gives
+you a facility for properly freeing memory ([more details
+here](http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Deleting_objects_from_a_storage_pool)).
+
+
+---
+
+### Tasking Trickiness
+
+Concurrency is part of the language in Ada, and is handled through
+[tasking](http://en.wikibooks.org/wiki/Ada_Programming/Tasking). A basic
+example of might be:
+
+{% highlight ada %}
+with Ada.Text_IO;
+
+procedure Main is
+ task Counter;
+
+ task body Counter is
+ begin
+ for Count in 1 .. 10 loop
+ Ada.Text_IO.Put_Line (Count'Img);
+ end loop;
+ end Counter;
+begin
+ null;
+end Main;
+
+{% endhighlight %}
+
+The way tasks in Ada work means that the `Counter` task will be created,
+started and then the execution of the `Main` program will block until the
+`Counter` task completes (important detail).
+
+
+The trickiness starts to arrive when you talk about dynamically allocating task
+objects, and combine that with something like an infinite loop, such as one
+might find in a server program, e.g.:
+
+{% highlight ada %}
+
+procedure Main is
+begin
+ -- Socket set up omitted
+ loop
+ declare
+ Client_Socket : Socket_Type;
+ Request_Handler : Handler_Ptr := new Handler;
+ begin
+ -- Block until we receive a new inbound connection
+ Accept_Socket (Server_Socket, Client_Socket, Server_Addr);
+ -- Dereference the Handler_Ptr and call `Process` on the Handler
+ -- task
+ Request_Handler.all.Process (Client_Socket);
+ end;
+ end loop;
+end Main;
+
+{% endhighlight %}
+
+(The code above is an abbreviated version of `echomultitask_main.adb` which [can
+be found
+here](https://github.com/rtyler/ada-playground/blob/master/echomultitask_main.adb)).
+
+The issue with this code is that we're allocating a new `Handler` task for
+every in-bound connection, and we have no means of ever cleaning them up
+properly. If we were to create an Array of `Handler_Ptr`, we still would have
+to find some mechanism (which exists) to check the status of each `Handler` to
+determine if we should clean it up. Problem being, we'd have to loop through
+all the active tasks, checking for a "terminated" status, in order to
+deallocate them. It'd be much better if a task could tell us when it's
+finished, rather than us polling every one.
+
+Fortunately in Ada 2005, a mechanism was added to make it easier to add
+"clean-up" to tasks: **`Ada.Task_Termination`**. The package allows you to set
+up a termination handler for the a specific task, which the runtime will call
+when that task terminates. _Unfortunately_ however, the handler procedure that
+can be invoked when the task terminates will **not** be passed a pointer to
+the task itself, but rather the `Task_Id` (`Ada.Task_Identification.Task_Id`).
+
+**So close** to being able to properly deallocate these dynamic tasks, but we
+need one more component, a protected object with a hash map inside of it:
+
+{% highlight ada %}
+
+package Server.Handlers is
+
+ protected Coordinator is
+ procedure Track (Ptr : in Handler_Ptr);
+ private
+ Active_Tasks : Handler_Containers.Map;
+ end Coordinator;
+
+end Server.Handlers;
+
+{% endhighlight %}
+
+Then back in `main.adb`:
+
+{% highlight ada %}
+
+ Accept_Socket (Server_Socket, Client_Socket, Server_Addr);
+ Request_Handler.all.Process (Client_Socket);
+ -- Make sure the we keep track of the Request_Handler in order to properly
+ -- deallocate it later
+ Server.Handlers.Coordinator.Track (Request_Handler);
+
+{% endhighlight %}
+
+(The code above is an abbreviated version of `echomultitask-worker.ads` which
+[can be found
+here](https://github.com/rtyler/ada-playground/blob/master/echomultitask-worker.ads))
+
+The singleton protected object `Coordinator` not only will give us protected
+(aka thread safe) access to the `Active_Tasks` map, but also gives us a
+protected object to hang our `Ada.Task_Termination.Termination_Handler`
+protected procedure off of:
+
+
+{% highlight ada %}
+
+protected body Server.Handlers is
+
+ protected body Coordinator is
+
+ procedure Last_Wish (C : Ada.Task_Termination.Cause_Of_Termination;
+ T : Ada.Task_Identification.Task_Id;
+ X : Ada.Exceptions.Exception_Occurrence) is
+ begin
+ -- Deallocate our task identified by `T`
+ -- and make sure we remove it from `Active_Tasks`
+ end Last_Wish;
+
+ procedure Track (Ptr : in Handler_Ptr) is
+ -- Dereference our `Handler` task, and fish out its Task_Id
+ Handler_Id : Ada.Task_Idenfitication.Task_Id := Ptr.all'Identity
+ begin
+ -- Add `Handler_Id` to our `Active_Tasks` map
+ Active_Tasks.Insert (Handler_Id, Ptr);
+
+ -- Set up the Last_Wish procedure to be executed after our task has
+ -- terminated
+ Ada.Task_Termination.Set_Specific_Handler (Handler_Id, Last_Wish'Access);
+ end Track;
+
+ end Coordinator;
+
+end Server.Handlers;
+
+{% endhighlight %}
+
+(The code above is an abbreviated version of `echomultitask-worker.adb` which
+[can be found here](https://github.com/rtyler/ada-playground/blob/master/echomultitask-worker.adb))
+
+
+This approach will allow us to safely create new dynamic tasks to handle the
+incoming requests, but will also make sure that the tasks are cleanly
+deallocated when they terminate.
+
+If you're interested in concurrency in Ada, I
+highly recommend purchasing [Concurrent and Real-Time Programming in
+Ada](http://www.amazon.com/gp/product/0521866979?ie=UTF8&tag=unethicalblog-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0521866979)
+by Alan Burns and Andy Wellings, it's been tremendously helpful for my own
+concurrency exploration in Ada.

0 comments on commit 30ab44c

Please sign in to comment.