From: Simon Wright on 31 Jan 2006 16:55 "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> writes: > On 30 Jan 2006 14:12:51 -0800, Rolf wrote: >> - I don't know much about sockets (or better I don't remember much). >> Does a waiting read (in the second task) block a write in the first >> task? > > Usually not. Note that you must wait not for a socket read, but for a > "variable-update" event from the middleware layer. _Something_ has to wait for a socket read! If you're writing your own 'middleware' (lower layers, anyway) that will be you. Windows is not wonderful for this sort of thing but I have not seen problems of the sort you describe with a task blocked on the read (input_t'Input) and other code (either another single task, or some sort of mutex) for output_t'Output. >> - what other hints can you give me? > > Never ever use UPD, avoid TCP_NO_DELAY with TCP/IP. The first is > unreliable for your purpose, the second quickly brings the network > down. Probably best to avoid these (I guess that UPD was a typo for UDP) at the start, but sometimes they are the appropriate solution. Not often, maybe.
From: Rolf on 31 Jan 2006 17:52 Stephen Leake wrote: > "Rolf" <rolf.ebert_nospam_(a)gmx.net> writes: > > > In a stripped down version I can succesfully connect to the server > > (using GNAT.Sockets) and either read the sensor data *or* write actor > > data. The program is currently split in two tasks. One tasks contains > > the application code and the actor communication (using > > type_id'output(channel)). The second tasks gets started during program > > initialisation. It reads the data from the socket via > > type_id'input(channel) and provides the data to the application through > > a protected object. > > > > The problem that I face is that the second task seems to starve the > > first one. As soon as it is active, the application does not generate > > debug output anymore. > > You need to set the priorities correctly, Does that mean e.g. to set the main task to 10 and the second task to 5? > and you need to ensure that > there are no busy waits; the second task should be _suspended_ waiting > on socket completions, not polling for them. How would I do that? I have no explicit busy wait, I use Var := Sensor_Cmd_T'Input (Channel); If possible, I'd like to keep that easy way of data input and avoid explicit conversion and read commands. > > Some background info: gcc-3.4.4 on Windows XP. > > That may be a problem. I find the commercially supported GNAT to be > less broken. This is a hobby project. > > Java for the world simulation. > > Yuck. I assume that's not by choice? The world simulation already exists. I won't recode it in Ada. (and I kind of like Java, too) > > The simulator sends about 20 packages à 11bytes every 100ms. The > > application sends typically 2-3 packages per second. > > That's certainly "reasonable rates" > That is almost nothing! > > I have delay statements in both main loops (varied between 0.0 and > > 0.2 seconds). > > You should _not_ need delay statements. Redesign to be waiting on > socket completions. How? > Or, if you are designing to a cyclic execution, you can poll on the > sockets, but just once per cycle. You can use > GNAT.Sockets.Control_Socket for that. > I shall check that. > > My questions: > > - is that a reasonable tasking approach? > > In general, yes. But the details matter a lot. > > > - I don't know much about sockets (or better I don't remember > > much). Does a waiting read (in the second task) block a write in the > > first task? > > Not in Windows with GNAT 5.03a. gcc-3.4.4 on Cygwin may be different. There is no real Ada compiler on Cygwin. I use the Windows (mingw-based) gcc-3.4.4. I shall see if GNAT GPL 2005 gives different results. > > - how can I interrupt the waiting read task to force activity in the > > main task? > > Depends on how it is waiting. If is in a GNAT.Sockets.Receive_Socket, > you can't (short of shutting down the socket). So periodic polling > might be better. I suppose it waits in the Sensor_Cmd_T'Input (Channel) routine, but I am not sure. > > - what other hints can you give me? > > Get an AdaCore support contract. > In a professional environment certainly, but not here ... Rolf
From: Rolf on 31 Jan 2006 18:03 tmoran(a)acm.org wrote: > But it seems to me that if the object is to use TCP to emulate hardware, > one should design for that hardware and do whatever is needed with UDP or > TCP to make the best emulation. Is the intended hardware going to be > polled or generate interrupts or Windows messages or what? The real sensor hardware will be directly connected to the I/O pins of the mcu. I think that counts as polling. The application code simply reads variables from the h/w abstraction layer.
From: Stephen Leake on 31 Jan 2006 20:23 "Rolf" <rolf.ebert_nospam_(a)gmx.net> writes: > Stephen Leake wrote: >> "Rolf" <rolf.ebert_nospam_(a)gmx.net> writes: >> >> > In a stripped down version I can succesfully connect to the server >> > (using GNAT.Sockets) and either read the sensor data *or* write actor >> > data. The program is currently split in two tasks. One tasks contains >> > the application code and the actor communication (using >> > type_id'output(channel)). The second tasks gets started during program >> > initialisation. It reads the data from the socket via >> > type_id'input(channel) and provides the data to the application through >> > a protected object. >> > >> > The problem that I face is that the second task seems to starve the >> > first one. As soon as it is active, the application does not generate >> > debug output anymore. >> >> You need to set the priorities correctly, > > Does that mean e.g. to set the main task to 10 and the second task to > 5? Well, I don't know, since I don't know the details of your project. But it is likely that one should have a higher priority than the other. The default is for all tasks to have the same priority. >> and you need to ensure that >> there are no busy waits; the second task should be _suspended_ waiting >> on socket completions, not polling for them. > > How would I do that? I have no explicit busy wait, I use > > Var := Sensor_Cmd_T'Input (Channel); > > If possible, I'd like to keep that easy way of data input and avoid > explicit conversion and read commands. Hmm. I don't know how this maps to Read_Socket commands. I would guess that it waits for the number of Stream_Elements in Sensor_Cmd_T to be available. But it might wait longer than that, especially if Sensor_Cmd_T is unconstrained. You could do a Read_Socket into a Stream_Array, and then do 'Input from that. That would make it clearer when the task is suspended. >> > Some background info: gcc-3.4.4 on Windows XP. >> >> That may be a problem. I find the commercially supported GNAT to be >> less broken. > > This is a hobby project. Ok. >> > - how can I interrupt the waiting read task to force activity in the >> > main task? >> >> Depends on how it is waiting. If is in a GNAT.Sockets.Receive_Socket, >> you can't (short of shutting down the socket). So periodic polling >> might be better. > > I suppose it waits in the Sensor_Cmd_T'Input (Channel) routine, but I > am not sure. There is an option that expands tasking constructs into lower-level Ada code, and outputs the source. That may help here, to show what is going on. -- -- Stephe
From: Stephen Leake on 31 Jan 2006 20:26 "Rolf" <rolf.ebert_nospam_(a)gmx.net> writes: > tmoran(a)acm.org wrote: >> But it seems to me that if the object is to use TCP to emulate hardware, >> one should design for that hardware and do whatever is needed with UDP or >> TCP to make the best emulation. Is the intended hardware going to be >> polled or generate interrupts or Windows messages or what? > > The real sensor hardware will be directly connected to the I/O pins of > the mcu. I think that counts as polling. The application code simply > reads variables from the h/w abstraction layer. How do those "variables" get set? Does one of the IO pins generate an interrupt, that triggers the h/w abstraction layer "read all pins" function? Or is the h/w abstraction layer a cyclic executor, driven by a clock? How does the application know when to read the variables? By a clock, or some interrupt/event from the h/w abstraction layer? -- -- Stephe
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: Debugger for GNAT Next: Problem creating bindings - please help |