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,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,41967527237c1aa2 X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!postnews.google.com!e65g2000hsc.googlegroups.com!not-for-mail From: mhamel_98@yahoo.com Newsgroups: comp.lang.ada Subject: Re: Fun with Tasking Date: 28 Mar 2007 10:53:16 -0700 Organization: http://groups.google.com Message-ID: <1175104396.231171.125360@e65g2000hsc.googlegroups.com> References: <1175097196.113031.259000@r56g2000hsd.googlegroups.com> <1175100948.580216.145940@r56g2000hsd.googlegroups.com> NNTP-Posting-Host: 155.104.37.17 Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Trace: posting.google.com 1175104397 16061 127.0.0.1 (28 Mar 2007 17:53:17 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Wed, 28 Mar 2007 17:53:17 +0000 (UTC) In-Reply-To: <1175100948.580216.145940@r56g2000hsd.googlegroups.com> User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; MathPlayer 2.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727),gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: e65g2000hsc.googlegroups.com; posting-host=155.104.37.17; posting-account=RO8m9AwAAAB418WhNxD6U0JmFC9jLoK1 Xref: g2news1.google.com comp.lang.ada:14655 Date: 2007-03-28T10:53:16-07:00 List-Id: On Mar 28, 12:55 pm, "Adam Beneschan" wrote: > On Mar 28, 8:53 am, mhamel...@yahoo.com wrote: > > > > > > > Below is sample code I made representing something I wanted to do with > > a program, of course it doesn't work quite the way I would like. > > Hopefully this sample doesn't cause eye (or brain) injury, it is more > > symbolic than useful - the procedure "Exec" is, of course, really a > > package (rather, several similar packages). > > > The problem is, how to "transport" a task? As seen in the sample > > below, I would like to use just a single address in the Control_Block > > type, but it's never that simple, is it? In actuality, how I get this > > program in its full incarnation to work is to define the "test_task"s > > in the acc_add_test part of the program. I really don't like doing > > this, as I mentioned, "exec" is representative of a family of several > > different packages. I would like the task definition to be local to > > the "exec" pacakage(s), not all kludged together in acc_add_test, > > which then requires all sorts of (ideally private) types being moved > > out of the local "exec" packages into acc_add_test and then the > > Control_Block record now has nearly a dozen different task pointers > > stuffed into it, only one of which is going to be used at any given > > time. > > > One last caveat, the Acc_Add_Test program should have *no* visibility > > into the "exec" procedure/package. The "exec" package(s), in fact, > > "push" their procedures into the main program. So is there something > > simple I'm having a brain fart over in missing here, or is a complete > > re-architecture required here? > > > with Text_Io; > > with System; > > with System.Address_To_Access_Conversions; > > > procedure Acc_Add_test is > > > Exec_Count : constant Natural := 10; > > > type Control_Block is > > record > > Task_Addr : System.Address; > > end record; > > > type Mode_Type is (preprocess, process); > > > procedure Exec (Mode : in Mode_Type; > > Cntl : in out Control_Block) is > > > task type Test_Task is > > entry Start (Addr : System.Address); > > entry Complete; > > end Test_Task; > > > package Convert is new System.Address_To_Access_Conversions > > (Test_Task); > > use Convert; > > > task body Test_Task is > > Task_Ptr : Convert.Object_Pointer := null; > > Count : Natural := 0; > > begin > > loop > > begin > > select > > accept Start (Addr : System.Address) do > > Task_Ptr := Convert.To_Pointer (Addr); > > end Start; > > > or > > accept Complete do > > Count := Count + 1; > > end Complete; > > if Count = Exec_Count then > > Text_Io.Put_Line ("Completed All Tasks"); > > abort Task_Ptr.all; > > end if; > > end select; > > end; > > end loop; > > end Test_Task; > > > begin > > case Mode is > > when Preprocess => > > declare > > Task_Ptr : Convert.Object_Pointer; > > Address : System.Address; > > begin > > Task_Ptr := new Test_Task; > > Address := Convert.To_Address (Task_Ptr); > > Task_Ptr.Start (Address); > > Cntl.Task_Addr := Address; > > end; > > > when Process => > > declare > > Task_Ptr : Convert.Object_Pointer; > > begin > > Task_Ptr := Convert.To_Pointer (Cntl.Task_Addr); > > Task_Ptr.Complete; > > end; > > end case; > > end Exec; > > > Controls : Control_Block; > > > begin > > Exec (Preprocess, Controls); > > for I in 1 .. Exec_Count loop > > Exec (Process, Controls); > > end loop; > > end Acc_Add_Test; > > > Thanks for any input! > > Your main problem is that your tasks aren't going to live long > enough. When a task is created by an allocator, it depends on the > "master" that declares the access type (or if the access type is a > derived type, which isn't the case here, on the "ultimate ancestor" of > the access type). See RM section 9.3. In this case, the master that > declares the access type (Convert.Object_Pointer) is the Exec > procedure. This means that any task that you create using this access > type depends on Exec, and Exec will not finish until any such tasks > are completed. It looks to me that you're trying to be able to call > Exec multiple times, and have it start a task the first time and then > use the same task the next time Exec is called. This won't work if > the task type is declared inside Exec, because any such tasks will not > be allowed to keep running if Exec isn't running. You'll need to move > the task types (and the access type that points to the task type) > outside Exec. > > This is the only thing that makes sense, anyway. If your task type is > declared inside Exec, the task body will have access to Exec's > parameters and local variables; how then could it be possible for the > task body to stay running while Exec isn't? > > I'm not real clear on what you're trying to do. Your sample has > "Exec" as a procedure, which makes it a master, but your discussion > talks about "Exec" *packages*---and a package is not a master. If you > wanted an Exec *package* that declares its own task type and its own > procedure to do the processing, but the task type isn't inside the > procedure, then I suspect that you may be able to accomplish what > you're trying to do; and there should be a way to keep certain things > private without having to resort to hokeyness like System.Address or > Address_To_Access_Conversions. But I'm not up to trying to guess what > you're trying to do; I'd recommend that you redo your example a bit to > avoid the task dependence problem and then ask again if you still > aren't sure how to do what you need to do. > > -- Adam- Hide quoted text - > > - Show quoted text - Thank you Adam. While making this sample program a sneaking suspicion started to creep up that I really didn't know what I was doing, and you helped verify that suspicion. What's really going on is I have a number of tasks I'm going to run, and while themselves completely independent of one another, they send updates to a single listening, or collating, task. That is the task at the heart of my initial post. My approach was to start up this collating task and give it's pointer (or address) to the processing tasks. This works fine if the collating task definition is in the acc_add_test procedure and the Control_Block has a pointer to that task within it. However, I would like the collating task definition to reside with the "exec" procedure/ package as the sample has it. How would one declare and start up that task, without any visibility into the package, just a procedure pointer with a mode argument? My (terribly flawed) idea was the PreProcess element of the procedure would set that up, but as you pointed out, the procedure would never exit while the task is running. So how to define the task and put it on "hold" until the processing tasks can utilize it? I don't expect it's possible without incurring as much ugliness as the program has already, but I thought I'd give it a try. Thanks again =)