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-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6f69b1cf0f02b9ac X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-01-21 09:11:06 PST Path: supernews.google.com!sn-xit-02!sn-xit-01!supernews.com!feeder.qis.net!fu-berlin.de!uni-berlin.de!ppp-3-29.5800-9.access.uk.worldonline.COM!not-for-mail From: "Nick Roberts" Newsgroups: comp.lang.ada Subject: Re: How can I avoid Using a Semaphore? Date: Sun, 21 Jan 2001 16:53:21 -0000 Message-ID: <94f577$d9s66$1@ID-25716.news.dfncis.de> References: <93ti8b$bjpps$1@ID-25716.news.dfncis.de> <9BP86.270637$U46.8654942@news1.sttls1.wa.home.com> <94563n$cb6kp$1@ID-25716.news.dfncis.de> <0Cka6.290338$U46.9207275@news1.sttls1.wa.home.com> <94co6t$v27$1@nnrp1.deja.com> NNTP-Posting-Host: ppp-3-29.5800-9.access.uk.worldonline.com (62.64.170.29) X-Trace: fu-berlin.de 980097064 13955270 62.64.170.29 (16 [25716]) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Xref: supernews.google.com comp.lang.ada:4268 Date: 2001-01-21T16:53:21+00:00 List-Id: I concur with Robert's comments on Ada's stream facilities. I would have thought some companies which sell Ada compilers might (depending on their clientele etc.) consider it a good idea to provide a facility like GNAT's for changing all the default representations to the network format, as well as (or by means of) providing something like System.Stream_Attributes. To solve your buffer synchronisation problem, Steve, please see the generic package spec attached. The idea here is that the packet picking task(s) does/do something like this: loop read the packet's length call Create to create a buffer of the correct length read the packet's data into the buffer call Dispatch to cause the buffer to be serviced (further calls to Dispatch on the buffer possible) end loop Each servicing task does something like this: loop call Obtain to get a buffer that needs a specific service perform the service (calls to Dispatch possible, to cause further servicing of the buffer) call Release to signal that the service has been completed end loop; A buffer is deleted automatically whenever a call to Release makes its Disp_Count go down to zero. This scheme has a lot of flexibility. It enables service tasks to dispatch a buffer for further processing. It enables several tasks to perform the same service, and it could enable one task to perform many services under some circumstances. It makes it possible to have several packet picking tasks, provided you ensure they actually pick the packets atomically. I have left the package body, and the details of implementation, to you. However, I've suggested that you would need two arrays, one for the allocation of buffers, and one for the allocation of 'dispatches'. Incidentally, I think you will need: type Array_Access is access all Data_Array; if you are going to use an internal array for the buffer data, instead of allocation with 'new'. The internal array will have to be aliased. Hope this is helpful, -- Nick Roberts http://www.AdaOS.org ===== generic type Datum_Type is private; type Service_Type is (<>); package Buffer_Distribution_Management is type Data_Array is array (Positive range <>) of Datum_Type; type Array_Access is access Data_Array; type Buffer_Token is private; type Dispatch_Token is private; -- Utility declarations (effectively private): type Buffer_Index is new Positive; type Dispatch_Index is new Positive; type Buffer_Descriptor is record Allocated: Boolean := False; Data: Array_Access; Disp_Count: Natural := 0; end record; type Dispatch_Descriptor is record Allocated: Boolean := False; Buffer: Buffer_Index; Service: Service_Type; end record; type Buffer_Array is (Buffer_Index range <>) of Buffer_Descriptor; type Dispatch_Array is (Dispatch_Index range <>) of Dispatch_Descriptor; -- The most important declaration for this package: protected type Buffer_Distributor (Buffer_Cap, Dispatch_Cap: Natural) is entry Create (Length: in Natural; Buffer: out Array_Access; Token: out Buffer_Token); procedure Delete (Token: in Buffer_Token); entry Dispatch (Token: in Buffer_Token; Service: in Service_Type); entry Obtain (Service: in Service_Type; Buffer: out Array_Access; Token: out Dispatch_Token); procedure Release (Token: in Dispatch_Token); procedure Reset; private Buffers: Buffer_Array (1..Buffer_Cap); Dispatches: Dispatch_Array (1..Dispatch_Cap); ... end Buffer_Distributor; private type Buffer_Token is new Buffer_Index; type Dispatch_Token is new Dispatch_Index; end Buffer_Distribution_Management;