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=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,3a3dffa82925efee X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Newsgroups: comp.lang.ada Subject: Re: Advantages References: <2k86nbF18idtrU1@uni-berlin.de> From: Brian May X-Home-Page: http://snoopy.apana.org.au/~bam/ Date: Mon, 28 Jun 2004 11:59:20 +1000 Message-ID: User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux) Cancel-Lock: sha1:ivTVsmwUjyVraCMSwNkkuZrd+34= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: dsl-202-173-153-89.vic.westnet.com.au X-Trace: news.melbourne.pipenetworks.com 1088387960 202.173.153.89 (28 Jun 2004 11:59:20 +1000) X-Complaints-To: abuse@pipenetworks.com X-Abuse-Info: Please forward all headers to enable your complaint to be properly processed. Path: g2news1.google.com!news1.google.com!newshub.sdsu.edu!logbridge.uoregon.edu!newsfeeds.ihug.co.nz!ihug.co.nz!news.xtra.co.nz!news.mel.connect.com.au!news.melbourne.pipenetworks.com!not-for-mail Xref: g2news1.google.com comp.lang.ada:1959 Date: 2004-06-28T11:59:20+10:00 List-Id: >>>>> "Robert" == Robert I Eachus writes: Robert> In Ada, if all these semaphores are actually internal to Robert> protected objects, the only way to hold R while acquiring Robert> S is for the protected object for R to have a call which Robert> internally calls the protected object for S. This is not Robert> hard to write in Ada, but the implicit ordering of with Robert> clauses will make it impossible for you to have a call Robert> that gets S while holding R, another call that gets T Robert> while holding S, and a third call that gets R while Robert> holding T. For that matter any matter any calling Robert> sequence that violates the rule will mean that the Robert> compiler will reject the program. So you can design, Robert> build and maintain complex real-time systems with many Robert> threads of control in Ada, and not only will there be no Robert> deadlocks, you won't have to do lots of analysis to show Robert> that the software is deadlock free. (Yes, you can put two Robert> protected objects in the same scope and violate the Robert> implicit ordering. But now the only source of potential Robert> deadlocks is in that one unit--that I hope violates your Robert> software development plan in some way.) I am assuming here that two protected objects in two different packages (units?) don't lie in "the same scope". I hope I haven't misunderstood you. The implication of what you say is you can't have a deadlock in Ada across different packages, that will compile, if you use protected objects in this manner to access variables Not true! -- cut -- package types is type R_Type is record X, Y: Float; end record; end types; -- cut -- -- cut -- with Types; package alpha is protected Prot_R is function Get return Types.R_Type; function Get_Deadlock return Types.R_Type; procedure Set (New_R: in Types.R_Type); private Inner_R: Types.R_Type; end; end alpha; -- cut -- -- cut -- with Ada.Text_IO; with beta; package body alpha is protected body Prot_R is function Get return Types.R_Type is begin Ada.Text_IO.Put_Line("Got Alpha 1"); Ada.Text_IO.Put_Line("Released Alpha 1"); return Inner_R; end; function Get_Deadlock return Types.R_Type is Temp : Types.R_Type; begin Ada.Text_IO.Put_Line("Got Alpha 2"); delay 5.0; Ada.Text_IO.Put_Line("Trying Beta"); Temp := beta.Prot_R.get; Ada.Text_IO.Put_Line("Released Alpha 2"); return Temp; end; procedure Set (New_R: in Types.R_Type) is begin Inner_R := New_R; end; end Prot_R; end alpha; -- cut -- -- cut -- with types; package beta is protected Prot_R is function Get return Types.R_Type; function Get_Deadlock return Types.R_Type; procedure Set (New_R: in Types.R_Type); private Inner_R: Types.R_Type; end; end beta; -- cut -- -- cut -- with Ada.Text_IO; with Alpha; package body beta is protected body Prot_R is function Get return Types.R_Type is begin Ada.Text_IO.Put_Line("Got Beta 1"); Ada.Text_IO.Put_Line("Released Beta 1"); return Inner_R; end; function Get_Deadlock return Types.R_Type is Temp : Types.R_Type; begin Ada.Text_IO.Put_Line("Got Beta 2"); delay 5.0; Ada.Text_IO.Put_Line("Trying Alpha"); Temp := alpha.Prot_R.get; Ada.Text_IO.Put_Line("Released Beta 2"); return Temp; end; procedure Set (New_R: in Types.R_Type) is begin Inner_R := New_R; end; end Prot_R; end beta; -- cut -- -- cut -- with Ada.Text_IO; with Types; with Alpha; with Beta; procedure deadlock is Local_R : Types.R_Type; task X is entry Start; end X; task body X is Task_R : Types.R_Type; begin accept Start; Ada.Text_IO.Put_Line("Task: trying beta"); Task_R := Beta.Prot_R.Get_Deadlock; Ada.Text_IO.Put_Line("Task: stopping"); end X; begin Ada.Text_IO.Put_Line("Main starting"); X.Start; Ada.Text_IO.Put_Line("main: trying alpha"); Local_R := Alpha.Prot_R.Get_Deadlock; Ada.Text_IO.Put_Line("main: stopping"); end; -- cut -- On my system produces: -- cut -- Main starting main: trying alpha Got Alpha 2 Task: trying beta Got Beta 2 Trying Beta Trying Alpha -- cut -- looks like deadlock to me... One task is trying to get beta, but can't because the other task has it, this task is trying to get alpha but can't because the first task has it. Sure, contrived example, but I think it gets the point across. Also, if you removed the delays it might sometimes work (if I got that correct), depending on timing. It is worth mentioning the compiler does warn you, at least for this case: -- cut -- >gnatmake deadlock gnatgcc -c deadlock.adb gnatgcc -c alpha.adb alpha.adb:19:10: warning: potentially blocking operation in protected operation gnatgcc -c beta.adb beta.adb:19:10: warning: potentially blocking operation in protected operation gnatbind -x deadlock.ali gnatlink deadlock.ali -- cut -- I would imagine that there are other cases where the compiler can't warn you. -- Brian May