From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=BAYES_00,DATE_IN_PAST_03_06, FORGED_GMAIL_RCVD,FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,534dd301375921ac,start X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII-7-bit Received: by 10.205.134.138 with SMTP id ic10mr406274bkc.8.1339693979953; Thu, 14 Jun 2012 10:12:59 -0700 (PDT) Path: e27ni48008bkw.0!nntp.google.com!news1.google.com!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail From: awdorrin Newsgroups: comp.lang.ada Subject: Is Text_IO.Put_Line() thread-safe? Date: Thu, 14 Jun 2012 05:53:34 -0700 (PDT) Organization: http://groups.google.com Message-ID: <93201f1a-d668-485e-83b4-492bc283f36e@googlegroups.com> NNTP-Posting-Host: 192.91.173.34 Mime-Version: 1.0 X-Trace: posting.google.com 1339678415 11289 127.0.0.1 (14 Jun 2012 12:53:35 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 14 Jun 2012 12:53:35 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=192.91.173.34; posting-account=YkFdLgoAAADpWnfCBA6ZXMWTz2zHNd0j User-Agent: G2/1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Date: 2012-06-14T05:53:34-07:00 List-Id: I tried posting this yesterday, but my browser glitched out on me, looks li= ke 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. Th= e other modules will call functions in Common to request chunks of memory i= n which to store data structures. As the modules initialize themselves, they call another routine in Common t= o wait until all tasks are ready (basically there is an array defined in co= mmon which has an element for each module, the module's corresponding eleme= nt is set when the module is ready to proceed.) I was having issues with this 'rendezvous' mechanism, because one of the mo= dules 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 informa= tion. 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 comp= rising ~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 mo= dules 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 eac= h module.) So the strange part is, the Put_Line is not always printing the message bei= ng requested. Randomly it will print what appears to be parts of the record= s 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 prop= erly. Originally I thought that something was wrong with the existing legacy Sort= code, and I replaced it with an Ada.Containers.Generic_Array_Sort implemen= tation. While the sort appears to be quicker, the Put_Line() output is stil= l corrupted - and the corruption is different with each subsequent run. Sometimes the entire line of text is replaced, other times it is just a por= tion 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 char= acters 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 w= rites 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 arc= hitecture of this application. While I could ignore the random printing, I am concerned that if the thread= s are not context switching properly, that any and all data structures in t= he 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 w= ithin GNAT. Another is: Am I missing some sort of quick/obvious way to mark the Put_Lin= e 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!