comp.lang.ada
 help / color / mirror / Atom feed
From: awdorrin <awdorrin@gmail.com>
Subject: Is Text_IO.Put_Line() thread-safe?
Date: Thu, 14 Jun 2012 05:53:34 -0700 (PDT)
Date: 2012-06-14T05:53:34-07:00	[thread overview]
Message-ID: <93201f1a-d668-485e-83b4-492bc283f36e@googlegroups.com> (raw)

I tried posting this yesterday, but my browser glitched out on me, looks like it posted a partial message (which I have tried to delete.)

First some background:

I'm migrating legacy code to Linux, using GCC/GNAT 4.4.5-8. The legacy code is a mix of C and Ada. The C code kicks off multiple POSIX threads (around 20), some of which are Ada code and others which are C. (Complicating that, some Ada calls imported C and some C calls imported Ada.)

One module is called 'Common' and is a central 'shared memory' location. The other modules will call functions in Common to request chunks of memory in which to store data structures.

As the modules initialize themselves, they call another routine in Common to wait until all tasks are ready (basically there is an array defined in common which has an element for each module, the module's corresponding element is set when the module is ready to proceed.)

I was having issues with this 'rendezvous' mechanism, because one of the modules was dying and all the other tasks were waiting on it, without giving any indication, so I added a Text_IO.Put_Line() to print some debug information.

Text_IO.Put_Line( Proc_Enum'Image(thisPID)&" waiting for "& Proc_Enum'Image(waitPID));

Here is where the strange part happens:

One of the other modules has a large array of records (~85,000 records comprising ~5MB of data) that needs to be sorted. While the sort of the record array is happening, the other modules are waiting on this one. The other modules loop, checking for all of the rendezvous array entries to be set true, and keep printing the 'waiting for' message (once every 2 seconds for each module.)

So the strange part is, the Put_Line is not always printing the message being requested. Randomly it will print what appears to be parts of the records that are being sorted.

I believe that there is something wrong with the context switching between the threads. That the Put_Line() isn't thread safe, and that somehow, when the threads switch back to a module that is in the middle of printing the 'waiting for' text to the screen, that context memory isn't being reset properly.

Originally I thought that something was wrong with the existing legacy Sort code, and I replaced it with an Ada.Containers.Generic_Array_Sort implementation. While the sort appears to be quicker, the Put_Line() output is still corrupted - and the corruption is different with each subsequent run.

Sometimes the entire line of text is replaced, other times it is just a portion of the text.

For instance, the output should print something like:

PROCESS1 waiting for PROCESS9

I will see lines such as the following:

PRlanSS1 waiting for PROC9
element1

sometimes, since the Linux 'Terminal' program will display unprintable characters as boxes with the hex codes, I'll see some of those in the middle of the text string, ending a text string.

I figure random data from the records is occasionally being pulled into the buffer that Text_IO.Put_Line() is using to assemble the string before it writes it to the screen.

Unfortunately, I can not think of any way to track this down further.

I'm not sure if this is an Ada bug, a threading bug or a bug due to the architecture of this application.

While I could ignore the random printing, I am concerned that if the threads are not context switching properly, that any and all data structures in the application could be corrupted at any time during a thread switch...

So, one question I had was: Is Text_IO.Put_Line() known to be thread safe within GNAT.
Another is: Am I missing some sort of quick/obvious way to mark the Put_Line as a 'critical code' section that cannot be preempted?

I have been using Ada off and on for a few years, but I'm much more of a C guy than an Ada guy.

Thanks in advance for any suggestions you might be able to provide!





             reply	other threads:[~2012-06-14 17:12 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-14 12:53 awdorrin [this message]
2012-06-14 13:49 ` Is Text_IO.Put_Line() thread-safe? Robert A Duff
2012-06-14 14:35   ` Adam Beneschan
2012-06-14 14:38   ` Dmitry A. Kazakov
2012-06-14 14:56     ` J-P. Rosen
2012-06-14 16:01       ` Dmitry A. Kazakov
2012-06-14 18:34       ` Robert A Duff
2012-06-21 19:01         ` Randy Brukardt
2012-06-14 18:29     ` Robert A Duff
2012-06-21 19:04       ` Randy Brukardt
2012-06-14 21:14     ` tmoran
2012-06-14 14:42   ` awdorrin
2012-06-14 18:24     ` Robert A Duff
2012-06-14 20:37       ` awdorrin
2012-06-14 21:37         ` Robert A Duff
2012-06-15  5:32           ` Georg Bauhaus
2012-06-15  7:22             ` Dmitry A. Kazakov
2012-06-15 21:32               ` Robert A Duff
2012-06-16  7:41                 ` Dmitry A. Kazakov
2012-06-15 21:27             ` Robert A Duff
2012-06-14 18:56 ` Jeffrey Carter
2012-06-14 20:50   ` awdorrin
2012-06-14 21:41     ` Robert A Duff
2012-06-15 12:39       ` awdorrin
2012-06-14 22:17     ` Jeffrey Carter
2012-06-14 22:40       ` Simon Wright
2012-06-14 23:35         ` Jeffrey Carter
2012-06-15  5:04           ` Simon Wright
2012-06-15  5:41             ` Jeffrey Carter
2012-06-21 19:20             ` Randy Brukardt
2012-06-16  2:00       ` BrianG
2012-06-16  6:04         ` J-P. Rosen
2012-06-16  6:49           ` Simon Wright
2012-06-16  7:58             ` Dmitry A. Kazakov
2012-06-16  8:03               ` Simon Wright
2012-06-16  8:14                 ` Dmitry A. Kazakov
2012-06-21 19:27               ` Randy Brukardt
2012-06-16  7:51           ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox