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.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,b59b337045eece60 X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!proxad.net!feeder1-2.proxad.net!newsfeed.straub-nv.de!noris.net!newsfeed.arcor.de!newsspool1.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Structure of the multitasking server Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <8b4d1170-22e6-40d3-8ed1-096dc0163491@m36g2000hse.googlegroups.com> <1w9y1ocmu2cm3$.724p6fohqdvy$.dlg@40tude.net> <259e95c5-92e6-4200-bc6e-5f35d99336a9@l64g2000hse.googlegroups.com> <11dyqk0lqb1je.ap31n7jjew7l.dlg@40tude.net> Date: Mon, 22 Sep 2008 10:12:44 +0200 Message-ID: <1ey0wvc4tun7g$.15u4xyef05055$.dlg@40tude.net> NNTP-Posting-Date: 22 Sep 2008 10:12:44 CEST NNTP-Posting-Host: 34119ba2.newsspool3.arcor-online.net X-Trace: DXC=SnE:MkaF\f;LNKYb?b>076McF=Q^Z^V384Fo<]lROoR18kF7enW;^6ZC`4IXm65S@:3>?ME5E9J5j^k9 X-Complaints-To: usenet-abuse@arcor.de Xref: g2news1.google.com comp.lang.ada:2060 Date: 2008-09-22T10:12:44+02:00 List-Id: On Sun, 21 Sep 2008 14:27:13 -0700 (PDT), Maciej Sobczak wrote: > On 21 Wrz, 21:24, "Dmitry A. Kazakov" > wrote: >> On Sun, 21 Sep 2008 10:30:37 -0700 (PDT), Maciej Sobczak wrote: > >>> No problem with that. With separate protected object (instead of >>> rendezvous) it is enough to do this: >> >> Of course there is a problem because conditional and timed entry calls may >> not contain a "terminate" alternative. > > They don't have to. Again: > > entry Get_Job (J : out Job_Type; Finished : out Boolean); Which is a bad pattern because it propagates task termination requests to an entry point of some object (or another task) which usually have little or nothing to do with the task termination issue. I don't like an extra output parameter, it is error-prone. Therefore I used a special value of Job_Type. There also exists a third variant with an exception propagation. (Note that an exception from an rendezvous propagates on both sides) This all is a matter of taste, because the (poor) pattern is same: the knowledge about caller's termination is moved to the callee. >> you have server, workers, channels and management stuff. > > Because it *is* there anyway. > Trying to hide it? What about the following: in my version the main > task (the one that invents jobs) can give the job to the worker task > when it is still working on the previous one, so that the main task > need not be blocked and can go on inventing more jobs. This is a very different task. You didn't say that you wanted to queue jobs. Anyway there is little sense to queue jobs to busy workers. A better design would be: Server --> Scheduler <-- Worker The jobs are queued to the scheduler. Workers ask it for jobs to do. Scheduler could be a protected object or a task. Depending on the nature of the jobs source, Server and Scheduler can be merged (see below). > This is not so easy in your version with rendezvous, where the main > task has to always *wait* until some of the worker will be willing to > pick up the new job (that's the whole point of rendezvous). You *have* to wait, or else you must drop jobs. Queueing jobs postpones the problem but that by no means solves it. If workers are incapable to process the jobs, the server must wait for them. The only reason why job queueing might become necessary is a need to make the server asynchronously working. (Remember our recent discussion? Buffering = wasting resources, unless decouples.) Anyway it is no problem in my design. Use selective accept (RM 9.7.1): select when not Empty (Queue) => accept Get (Work : out Job) do ... -- A worker is here to get a job from the FIFO end Get; or when not Full (Queue) => accept Put (Work : out Job) do ... -- A new job is to queue into the FIFO end Put; or when Full (Queue) => delay Time_Out; ... -- Go to hell with your jobs! end select; > Obviously, > there are fewer opportunities for concurrency in your version. > What would you have to do to have this increased concurrency in your > version? Would you still claim it to be simpler? Certainly yes. If I wished to collect jobs at the server I would just add a FIFO of jobs there, like above. >> The second problem which adds complexity is server to worker 1-n >> communication. Should be n-1 worker to server, simpler (classic >> client-server) and more efficient too. > > I'd prefer producer + queue + N consumers. Still a protected object in > the middle. What you describe is my design (the queue is held by the producer).Your design was: producer + N queues of size 1 + N consumers It is not a problem to me to split the producer into server and scheduler. I object mainly to moving *parts* of the scheduler (as protected objects) into the consumers. It makes no sense. >>> There is no need to introduce any special type of job ("poison pill"). >> >> Job carries the parameters of a worker. You used it too, under the name >> Job_Type. > > But in my case the Job_Type need not contain the special "poison" > value. See above. You can use either of three variants with my design. This is an independent issue. > Let's say that the Job_Type is a matrix that has to be > reversed. There is no place for the "poison" value in the matrix > itself, so the Job_Type would need to be extended (a record with > additional flag, perhaps?) to cover it, but then the pollution of the > type would be very explicit. If it were large objects, I would not use copying anyway. So it would become a referential object moving around. These would have enough place for "poison". Further, don't forget that Ada has variant records. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de