* FIFO
@ 2017-09-16 15:24 Frank Buss
2017-09-16 16:19 ` FIFO Jacob Sparre Andersen
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Frank Buss @ 2017-09-16 15:24 UTC (permalink / raw)
I need a FIFO with a fixed size, for buffering serial data on an
embedded system. The FIFO will be filled in an interrupt and read from
the main function.
I guess I could implement this myself, using a simple array of e.g. 256
bytes, and then a read index and a write index. If I specify it with
"pragma Volatile", nothing bad should happen.
But I read about bounded vectors. Could I use this as well and save a
few lines of code and testing work? I'm a bit worried about if the
behavior is standardized, such that e.g. Delete_First doesn't physically
move all elements, because this would be bad when writing it at the same
time from the interrupt. Because it is bounded, it could be implemented
as the simple ringbuffer as I would implement it.
--
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 15:24 FIFO Frank Buss
@ 2017-09-16 16:19 ` Jacob Sparre Andersen
2017-09-16 17:07 ` FIFO Dmitry A. Kazakov
2017-09-16 17:12 ` FIFO Frank Buss
2017-09-16 17:52 ` FIFO Robert A Duff
2017-09-16 22:04 ` FIFO Jeffrey R. Carter
2 siblings, 2 replies; 15+ messages in thread
From: Jacob Sparre Andersen @ 2017-09-16 16:19 UTC (permalink / raw)
Frank Buss <fb@frank-buss.de> writes:
> I need a FIFO with a fixed size, for buffering serial data on an
> embedded system. The FIFO will be filled in an interrupt and read from
> the main function.
Maybe something like a bounded, synchronised queue
(http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-18-29.html)?
Greetings,
Jacob
--
"How may I be honest with you today?"
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 16:19 ` FIFO Jacob Sparre Andersen
@ 2017-09-16 17:07 ` Dmitry A. Kazakov
2017-09-16 17:12 ` FIFO Frank Buss
1 sibling, 0 replies; 15+ messages in thread
From: Dmitry A. Kazakov @ 2017-09-16 17:07 UTC (permalink / raw)
On 2017-09-16 18:19, Jacob Sparre Andersen wrote:
> Frank Buss <fb@frank-buss.de> writes:
>
>> I need a FIFO with a fixed size, for buffering serial data on an
>> embedded system. The FIFO will be filled in an interrupt and read from
>> the main function.
>
> Maybe something like a bounded, synchronised queue
> (http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-18-29.html)?
Interrupt handler is a protected procedure. So, it is probably a
bounded-error to use the queue from here (ARM 9.5.1/11).
I don't see anything wrong with ring buffer, provided read/write indices
are declared atomic and there is only one reader.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 16:19 ` FIFO Jacob Sparre Andersen
2017-09-16 17:07 ` FIFO Dmitry A. Kazakov
@ 2017-09-16 17:12 ` Frank Buss
2017-09-16 17:22 ` FIFO Dmitry A. Kazakov
1 sibling, 1 reply; 15+ messages in thread
From: Frank Buss @ 2017-09-16 17:12 UTC (permalink / raw)
On 09/16/2017 06:19 PM, Jacob Sparre Andersen wrote:
> Frank Buss <fb@frank-buss.de> writes:
>
>> I need a FIFO with a fixed size, for buffering serial data on an
>> embedded system. The FIFO will be filled in an interrupt and read from
>> the main function.
>
> Maybe something like a bounded, synchronised queue
> (http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-A-18-29.html)?
Bit cumbersome to define the right type, but otherwise looks like what I
was searching for. Unfortunately not supported for my implementation of
ravenscar:
http://www.adacore.com/developers/development-log/NF-74-O619-005-gnat/
Oh well, I'll write my own package for it then. On the plus side it
wouldn't have all these interface stuff overhead and might be smaller
and faster, just a simple generic with the type and the size.
--
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 17:12 ` FIFO Frank Buss
@ 2017-09-16 17:22 ` Dmitry A. Kazakov
2017-09-16 18:32 ` FIFO Frank Buss
0 siblings, 1 reply; 15+ messages in thread
From: Dmitry A. Kazakov @ 2017-09-16 17:22 UTC (permalink / raw)
On 2017-09-16 19:12, Frank Buss wrote:
> Oh well, I'll write my own package for it then. On the plus side it
> wouldn't have all these interface stuff overhead and might be smaller
> and faster, just a simple generic with the type and the size.
You can borrow code from here:
http://www.dmitry-kazakov.de/ada/components.htm#Generic_FIFO
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 15:24 FIFO Frank Buss
2017-09-16 16:19 ` FIFO Jacob Sparre Andersen
@ 2017-09-16 17:52 ` Robert A Duff
2017-09-16 18:11 ` FIFO Frank Buss
2017-09-17 9:46 ` FIFO Simon Wright
2017-09-16 22:04 ` FIFO Jeffrey R. Carter
2 siblings, 2 replies; 15+ messages in thread
From: Robert A Duff @ 2017-09-16 17:52 UTC (permalink / raw)
Frank Buss <fb@frank-buss.de> writes:
> I need a FIFO with a fixed size,...
Does Ada.Containers.Bounded_Synchronized_Queues meet your needs?
- Bob
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 17:52 ` FIFO Robert A Duff
@ 2017-09-16 18:11 ` Frank Buss
2017-09-17 9:46 ` FIFO Simon Wright
1 sibling, 0 replies; 15+ messages in thread
From: Frank Buss @ 2017-09-16 18:11 UTC (permalink / raw)
On 09/16/2017 07:52 PM, Robert A Duff wrote:
> Frank Buss <fb@frank-buss.de> writes:
>
>> I need a FIFO with a fixed size,...
>
> Does Ada.Containers.Bounded_Synchronized_Queues meet your needs?
I guess it would work, but not available in ravenscar full for GNAT.
--
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 17:22 ` FIFO Dmitry A. Kazakov
@ 2017-09-16 18:32 ` Frank Buss
2017-09-17 7:39 ` FIFO Jacob Sparre Andersen
2017-09-17 11:30 ` FIFO AdaMagica
0 siblings, 2 replies; 15+ messages in thread
From: Frank Buss @ 2017-09-16 18:32 UTC (permalink / raw)
On 09/16/2017 07:22 PM, Dmitry A. Kazakov wrote:
> On 2017-09-16 19:12, Frank Buss wrote:
>
>> Oh well, I'll write my own package for it then. On the plus side it
>> wouldn't have all these interface stuff overhead and might be smaller
>> and faster, just a simple generic with the type and the size.
>
> You can borrow code from here:
>
> http://www.dmitry-kazakov.de/ada/components.htm#Generic_FIFO
Thanks, looks similar. I tried my own version, without looking at your
version :-) Would this work for interrupts with the volatile? Good idea
to use the size generic argument inside the package.
And everyone feel free to criticize my code, as I'm very new to Ada. For
example, I saw that when you want to package something neatly, but it
consists mainly of one type, then the package is named plural of the
type, like I did: "Ringbuffers" and "Ringbuffer" for the type. Is this
common practice?
For testing I wrote a small program. How do Ada programmers usually test
their libraries and programs? For Java I often use JUnit.
My version:
ringbuffers.ads:
generic
Size : Positive;
type Item is private;
package Ringbuffers is
type Ringbuffer is tagged private;
procedure Write (Self : in out Ringbuffer; e : Item);
function Read (Self : in out Ringbuffer) return Item;
function Is_Empty (Self : Ringbuffer) return Boolean;
private
type Item_Array is array (1 .. Size) of Item;
pragma Volatile (Item_Array);
type Ringbuffer is tagged record
Read_Index : Positive := 1;
Write_Index : Positive := 1;
Items : Item_Array;
end record;
pragma Volatile (Ringbuffer);
end Ringbuffers;
ringbuffers.adb:
package body Ringbuffers is
procedure Write (Self : in out Ringbuffer; e : Item) is
begin
Self.Items (Self.Write_Index) := e;
Self.Write_Index := Self.Write_Index + 1;
if (Self.Write_Index = Size) then
Self.Write_Index := 1;
end if;
end Write;
function Read (Self : in out Ringbuffer) return Item is
Result : Item;
begin
Result := Self.Items (Self.Read_Index);
Self.Read_Index := Self.Read_Index + 1;
if (Self.Read_Index = Size) then
Self.Read_Index := 1;
end if;
return Result;
end Read;
function Is_Empty (Self : Ringbuffer) return Boolean is
begin
return Self.Write_Index = Self.Read_Index;
end Is_Empty;
end Ringbuffers;
test_ringbuffer.adb:
with Interfaces; use Interfaces;
with Ada.Text_IO; use Ada.Text_IO;
with Ringbuffers;
procedure Test_Ringbuffer is
package FIFO_Package is new Ringbuffers (256, Unsigned_8);
subtype FIFO is FIFO_Package.Ringbuffer;
Test : FIFO;
begin
Test.Write (1);
Test.Write (7);
while not Test.Is_Empty loop
Put_Line (Unsigned_8'Image (Test.Read));
end loop;
end Test_Ringbuffer;
--
Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 15:24 FIFO Frank Buss
2017-09-16 16:19 ` FIFO Jacob Sparre Andersen
2017-09-16 17:52 ` FIFO Robert A Duff
@ 2017-09-16 22:04 ` Jeffrey R. Carter
2 siblings, 0 replies; 15+ messages in thread
From: Jeffrey R. Carter @ 2017-09-16 22:04 UTC (permalink / raw)
On 09/16/2017 05:24 PM, Frank Buss wrote:
> I need a FIFO with a fixed size, for buffering serial data on an embedded
> system. The FIFO will be filled in an interrupt and read from the main function.
You could use an instance of PragmARC.Queue_Bounded_Unprotected:
https://github.com/jrcarter/PragmARC
--
Jeff Carter
"When danger reared its ugly head, he bravely
turned his tail and fled."
Monty Python and the Holy Grail
60
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 18:32 ` FIFO Frank Buss
@ 2017-09-17 7:39 ` Jacob Sparre Andersen
2017-09-17 8:38 ` FIFO Jacob Sparre Andersen
2017-09-17 8:57 ` FIFO Niklas Holsti
2017-09-17 11:30 ` FIFO AdaMagica
1 sibling, 2 replies; 15+ messages in thread
From: Jacob Sparre Andersen @ 2017-09-17 7:39 UTC (permalink / raw)
Frank Buss wrote:
> And everyone feel free to criticize my code, as I'm very new to
> Ada. For example, I saw that when you want to package something
> neatly, but it consists mainly of one type, then the package is named
> plural of the type, like I did: "Ringbuffers" and "Ringbuffer" for the
> type. Is this common practice?
It is one of three common practices:
1)
package Noun is
subtype Parent is ...;
type Instance is new Parent with ...;
subtype Class is Instance'Class;
2)
package Plural_Noun is
type Noun is ...;
3)
package ... is
type Noun_Type is ...;
The last of the three practices is explicitly frowned upon by the "Ada
(95) Quality and Style Guide", while the first two are listed as
suggested practices.
> For testing I wrote a small program. How do Ada programmers usually
> test their libraries and programs? For Java I often use JUnit.
I usually use Ahven.
There is also AUnit, but when I tried to use it, I found that the tool,
which should make it easier to use than Ahven didn't work on my system.
> generic
> Size : Positive;
> type Item is private;
> package Ringbuffers is
Another option is:
generic
type Index is mod <>;
type Element is private;
package Ring_Buffer is
type Instance is tagged private;
subtype Class is Instance'Class;
procedure Write (Buffer : in out Instance;
New_Item : in Element);
function Read (Buffer : in out Instance) return Element;
function Is_Empty (Buffer : Instance) return Boolean;
private
type Element_Array is array (Index) of Element
with Volatile; -- I'm not sure this does what you want.
type Instance is tagged
record
Head, Tail : Index := Index'First;
Elements : Element_Array;
end record
with Volatile; -- I'm not sure this does what you want either.
end Ring_Buffer;
Notice that "Volatile" is a bit tricky. I'm not sure if that is what
you need. Nor if it makes sense to declare both types volatile.
Greetings,
Jacob
--
"In space, no-one can press CTRL-ALT-DEL"
-- An Ada programmer
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-17 7:39 ` FIFO Jacob Sparre Andersen
@ 2017-09-17 8:38 ` Jacob Sparre Andersen
2017-09-17 8:57 ` FIFO Niklas Holsti
1 sibling, 0 replies; 15+ messages in thread
From: Jacob Sparre Andersen @ 2017-09-17 8:38 UTC (permalink / raw)
Jacob Sparre Andersen wrote:
> 1)
> package Noun is
> subtype Parent is ...;
> type Instance is new Parent with ...;
> subtype Class is Instance'Class;
Just to be precise: The "Parent" part of this construct is not included
in the "Ada (95) Quality and Style Guide".
Greetings,
Jacob
--
PNG: Pretty Nice Graphics
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-17 7:39 ` FIFO Jacob Sparre Andersen
2017-09-17 8:38 ` FIFO Jacob Sparre Andersen
@ 2017-09-17 8:57 ` Niklas Holsti
1 sibling, 0 replies; 15+ messages in thread
From: Niklas Holsti @ 2017-09-17 8:57 UTC (permalink / raw)
On 17-09-17 10:39 , Jacob Sparre Andersen wrote:
> Frank Buss wrote:
>
>> And everyone feel free to criticize my code, as I'm very new to
>> Ada.
[snip]
>> generic
>> Size : Positive;
>> type Item is private;
>> package Ringbuffers is
>
> Another option is:
>
> generic
> type Index is mod <>;
> type Element is private;
> package Ring_Buffer is
> type Instance is tagged private;
> subtype Class is Instance'Class;
>
> procedure Write (Buffer : in out Instance;
> New_Item : in Element);
> function Read (Buffer : in out Instance) return Element;
> function Is_Empty (Buffer : Instance) return Boolean;
> private
> type Element_Array is array (Index) of Element
> with Volatile; -- I'm not sure this does what you want.
>
> type Instance is tagged
> record
> Head, Tail : Index := Index'First;
> Elements : Element_Array;
> end record
> with Volatile; -- I'm not sure this does what you want either.
> end Ring_Buffer;
>
> Notice that "Volatile" is a bit tricky. I'm not sure if that is what
> you need. Nor if it makes sense to declare both types volatile.
I would use pragma Atomic on Head and Tail, pragma Volatile_Components
on Element_Array, and no pragma on the (whole) Instance record type.
In May of this year there was a long and profound thread on
comp.lang.ada about the Atomic/Volatile issue, with the subject
"Portable memory barrier?". Worth reading if you intend to use those
pragmas.
On the functional level, it seems to me that the ring-buffer package
examples given so far are missing a check for overflow (full queue) in
the "write" (enqueue) operation. I would augment the Write procedure to
make this check and return a success/failure result to the caller (the
interrupt handler) and/or increment a "lost elements" counter in the
queue Instance, for use by the queue-reading task,
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 17:52 ` FIFO Robert A Duff
2017-09-16 18:11 ` FIFO Frank Buss
@ 2017-09-17 9:46 ` Simon Wright
1 sibling, 0 replies; 15+ messages in thread
From: Simon Wright @ 2017-09-17 9:46 UTC (permalink / raw)
Robert A Duff <bobduff@TheWorld.com> writes:
> Frank Buss <fb@frank-buss.de> writes:
>
>> I need a FIFO with a fixed size,...
>
> Does Ada.Containers.Bounded_Synchronized_Queues meet your needs?
>
> - Bob
The implementation in GNAT GPL 2017 is not legal under Ravenscar
restrictions (the protected type Queue has two entries).
Also, what's the behaviour when the queue is already full? It blocks on
Enqueue, which would be a Bad Idea if called from an interrupt handler.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
2017-09-16 18:32 ` FIFO Frank Buss
2017-09-17 7:39 ` FIFO Jacob Sparre Andersen
@ 2017-09-17 11:30 ` AdaMagica
[not found] ` <8b99f47a-63bf-4f07-9077-6dab3cf32a7f@googlegroups.com>
1 sibling, 1 reply; 15+ messages in thread
From: AdaMagica @ 2017-09-17 11:30 UTC (permalink / raw)
Am Samstag, 16. September 2017 20:32:36 UTC+2 schrieb Frank Buss:
> generic
> Size : Positive;
> type Item is private;
> package Ringbuffers is
>
> type Ringbuffer is tagged private;
>
> procedure Write (Self : in out Ringbuffer; e : Item);
> function Read (Self : in out Ringbuffer) return Item;
> function Is_Empty (Self : Ringbuffer) return Boolean;
>
> private
>
> type Item_Array is array (1 .. Size) of Item;
> pragma Volatile (Item_Array);
> type Ringbuffer is tagged record
> Read_Index : Positive := 1;
> Write_Index : Positive := 1;
> Items : Item_Array;
> end record;
> pragma Volatile (Ringbuffer);
Please check Volatile in the RM.
>
> end Ringbuffers;
>
>
> ringbuffers.adb:
>
> package body Ringbuffers is
>
> procedure Write (Self : in out Ringbuffer; e : Item) is
Check for overflow is missing.
> begin
> Self.Items (Self.Write_Index) := e;
> Self.Write_Index := Self.Write_Index + 1;
> if (Self.Write_Index = Size) then
Seems the true size is Size -1 , component with index Size will never be written (nor read, see below).
> Self.Write_Index := 1;
> end if;
> end Write;
>
> function Read (Self : in out Ringbuffer) return Item is
Check for emptiness is missing.
> Result : Item;
> begin
> Result := Self.Items (Self.Read_Index);
> Self.Read_Index := Self.Read_Index + 1;
> if (Self.Read_Index = Size) then
> Self.Read_Index := 1;
> end if;
> return Result;
> end Read;
>
> function Is_Empty (Self : Ringbuffer) return Boolean is
> begin
> return Self.Write_Index = Self.Read_Index;
> end Is_Empty;
>
> end Ringbuffers;
>
>
> test_ringbuffer.adb:
>
> with Interfaces; use Interfaces;
> with Ada.Text_IO; use Ada.Text_IO;
> with Ringbuffers;
>
> procedure Test_Ringbuffer is
> package FIFO_Package is new Ringbuffers (256, Unsigned_8);
> subtype FIFO is FIFO_Package.Ringbuffer;
> Test : FIFO;
>
> begin
> Test.Write (1);
> Test.Write (7);
> while not Test.Is_Empty loop
> Put_Line (Unsigned_8'Image (Test.Read));
> end loop;
> end Test_Ringbuffer;
>
>
> --
> Frank Buss, http://www.frank-buss.de
> electronics and more: http://www.youtube.com/user/frankbuss
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: FIFO
[not found] ` <opqq32$3bd$1@newsreader4.netcologne.de>
@ 2017-09-25 20:57 ` Niklas Holsti
0 siblings, 0 replies; 15+ messages in thread
From: Niklas Holsti @ 2017-09-25 20:57 UTC (permalink / raw)
On 17-09-19 13:04 , Frank Buss wrote:
> On 09/19/2017 08:33 AM, Niklas Holsti wrote:
>> If one task or interrupt handler is pushing data into the buffer at some
>> rate, with some burstiness, and another task or interrupt handler is
>> pulling data from the buffer at some rate, with some burstiness, I do
>> not believe that GNATprove can show that the buffer never overflows.
>>
>> I'll be glad to be proven wrong, though.
>
> Right, this is what I meant. A real world example: This package reads
> data into my buffer:
>
> https://github.com/FrankBuss/Ada_Synth/blob/master/ada/discovery/serial_io.adb#L67
>
>
> Another unrelated problem: I think there could be a race condition, if
> the FIFO is not empty, but then the interrupt is called and the FIFO
> gets empty, and then the next byte is added to the FIFO in the else
> branch, which then will never be sent, and even worse, no more bytes at
> all will be sent after this bug. How could I prevent this? I guess I
> should disable interrupts while in the Write procedure, or is this done
> by Ada automatically because I'm in a protected body?
Yes, automatically. RM C.3.1(13): "When a handler is attached to an
interrupt, the interrupt is blocked (subject to the Implementation
Permission in C.3 [that is, if "the underlying system or hardware"
allows blocking interrupts]) during the execution of every protected
action on the protected object containing the handler."
I haven't reviewed your code in detail, but I glanced at it and wonder
about some things:
- Serial_Port_Controller.Write checks if the Output FIFO Is_Empty, but
it does not check if a transmission is going on. How do you intend to
prevent the writer task(s) from calling Write too often, overwriting an
on-going transmission with a new transmission?
- In fact, the code only puts something into the Output FIFO if the
Output FIFO is non-empty. I assume the FIFO is empty initially, so it
seems to me that it will always be empty. That can't be intended.
- If I understand the code correctly,
Serial_Port_Controller.Interrupt_Handler clears the "transmission
completed" status _after_ it has started a new transmission. This
creates a race condition: if the UART is very fast, it might complete
the transmission before the code clears the "transmission completed"
status, in which case the "transmission completed" status would be lost.
I suggest to clear the "tranmission completed" status _before_ starting
the new transmission.
I think the protected object should have a flag variable showing if a
transmission is going on. The flag should be set when a transmission is
started, and be cleared in the Interrupt_Handler when it detects the
completion of the transmission. The Write procedure should start a
transmission if, and only if, no transmission is already going on. If a
transmission is going on when Write is called, Write should put the Data
into the Output FIFO, for Interrupt_Handler to transmit later.
Perhaps you intended that "not Output.Is_Empty" would mean "transmission
going on", but that is not the way the code works. The octet currently
being transmitted is _not_ in the Output FIFO.
(By the way, if the Rinbguffer objects are protected variables, it is
not necessary to have pragma Volatile etc. on them, because the
protected object does whatever is needed for multi-task access. Pragma
Volatile etc. is needed only for _unprotected_ variables that are
nevertheless accessed from multiple tasks.)
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2017-09-25 20:57 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-16 15:24 FIFO Frank Buss
2017-09-16 16:19 ` FIFO Jacob Sparre Andersen
2017-09-16 17:07 ` FIFO Dmitry A. Kazakov
2017-09-16 17:12 ` FIFO Frank Buss
2017-09-16 17:22 ` FIFO Dmitry A. Kazakov
2017-09-16 18:32 ` FIFO Frank Buss
2017-09-17 7:39 ` FIFO Jacob Sparre Andersen
2017-09-17 8:38 ` FIFO Jacob Sparre Andersen
2017-09-17 8:57 ` FIFO Niklas Holsti
2017-09-17 11:30 ` FIFO AdaMagica
[not found] ` <8b99f47a-63bf-4f07-9077-6dab3cf32a7f@googlegroups.com>
[not found] ` <oppbcq$7jj$1@newsreader4.netcologne.de>
[not found] ` <d37417dd-3a94-4a43-bc9c-071f2da6181d@googlegroups.com>
[not found] ` <f2bs2lFq4j3U1@mid.individual.net>
[not found] ` <opqq32$3bd$1@newsreader4.netcologne.de>
2017-09-25 20:57 ` FIFO Niklas Holsti
2017-09-16 17:52 ` FIFO Robert A Duff
2017-09-16 18:11 ` FIFO Frank Buss
2017-09-17 9:46 ` FIFO Simon Wright
2017-09-16 22:04 ` FIFO Jeffrey R. Carter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox