[squeak-dev] Serial Port(s) from multiple processes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Serial Port(s) from multiple processes

Jon Hylands

Hi everyone,

I've got a couple USB-based serial ports on my robot BrainBot, and I've got
four different processes - two for each port. One process reads from the
serial port, and one writes to it.

For each serial port, I have a mutex semaphore to protect access to the
port, like this:

readData
        ^portAccess critical: [serialPort readByteArray]

writeData: aByteArray
        portAccess critical: [serialPort nextPutAll: aByteArray]

Those two methods are implemented in the same class, and thus the
'portAccess' instance variable (which is a Semaphore) is shared between
read and write, but not between different serial ports..

I have two instances of this class, one for each USB device plugged in (the
USB devices are both FT232-based interfaces, one at port 4, the other at
port 5).

The question is, do I need to protect the two instances of SerialPort with
a single Semaphore? Looking at the serial port code for read/writing, it
looks like the code just jumps directly into the primitives. I was under
the assumption that primitive execution can't be pre-empted, and therefore
the code shouldn't need mutex protection.

Am I missing something?

Thanks,
Jon

--------------------------------------------------------------
   Jon Hylands      [hidden email]      http://www.huv.com/jon

  Project: Micro Raptor (Small Biped Velociraptor Robot)
           http://www.huv.com/blog

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Serial Port(s) from multiple processes

David T. Lewis
On Thu, Jun 11, 2009 at 04:16:06PM -0400, Jon Hylands wrote:

>
> Hi everyone,
>
> I've got a couple USB-based serial ports on my robot BrainBot, and I've got
> four different processes - two for each port. One process reads from the
> serial port, and one writes to it.
>
> For each serial port, I have a mutex semaphore to protect access to the
> port, like this:
>
> readData
> ^portAccess critical: [serialPort readByteArray]
>
> writeData: aByteArray
> portAccess critical: [serialPort nextPutAll: aByteArray]
>
> Those two methods are implemented in the same class, and thus the
> 'portAccess' instance variable (which is a Semaphore) is shared between
> read and write, but not between different serial ports..
>
> I have two instances of this class, one for each USB device plugged in (the
> USB devices are both FT232-based interfaces, one at port 4, the other at
> port 5).
>
> The question is, do I need to protect the two instances of SerialPort with
> a single Semaphore? Looking at the serial port code for read/writing, it
> looks like the code just jumps directly into the primitives. I was under
> the assumption that primitive execution can't be pre-empted, and therefore
> the code shouldn't need mutex protection.
>
> Am I missing something?

It does not sound like you are missing anything. Are you encountering
problems with this, or are you just asking to be sure?

Dave


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Serial Port(s) from multiple processes

Jon Hylands
On Fri, 12 Jun 2009 07:19:40 -0400, "David T. Lewis" <[hidden email]>
wrote:

> It does not sound like you are missing anything. Are you encountering
> problems with this, or are you just asking to be sure?

I'm encountering some weird problems, and right now I'm not sure what is
causing them. Sometimes the image (running on the robot) basically freezes
and becomes non-responsive, and starts consuming an entire core's worth of
CPU.

Later,
Jon

--------------------------------------------------------------
   Jon Hylands      [hidden email]      http://www.huv.com/jon

  Project: Micro Raptor (Small Biped Velociraptor Robot)
           http://www.huv.com/blog

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Socket CPU usage

Jon Hylands
In reply to this post by David T. Lewis
On Fri, 12 Jun 2009 07:19:40 -0400, "David T. Lewis" <[hidden email]>
wrote:

> It does not sound like you are missing anything. Are you encountering
> problems with this, or are you just asking to be sure?

Actually, it appears that the problem is in a different place.

After starting the CPUWatcher in the process browser, the hangup appears to
happen inside the Socket code, on a server socket.

I call Socket >> #receiveDataInto:startingAt: and after a while, CPUWatcher
complains that that process is taking too much CPU. Note that I'm running
on an older system (3.8, Update #6665), with the 3.10.6 (release) VM from
Aug 30, 2007 (on Windows XP).

There's no reason why I can't move forward to 3.10.2, so I will try that,
and hopefully whatever this issue is has been fixed
--------------------------------------------------------------
   Jon Hylands      [hidden email]      http://www.huv.com/jon

  Project: Micro Raptor (Small Biped Velociraptor Robot)
           http://www.huv.com/blog

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Socket CPU usage

Andreas.Raab
Jon Hylands wrote:
> I call Socket >> #receiveDataInto:startingAt: and after a while, CPUWatcher
> complains that that process is taking too much CPU. Note that I'm running
> on an older system (3.8, Update #6665), with the 3.10.6 (release) VM from
> Aug 30, 2007 (on Windows XP).

You might just be hitting a particular issue with that very Socket
method. If you look at receiveDataInto:startingAt: you will notice that
when the connection is closed, it notices it but doesn't do anything.
Because of that, callers need to be aware that *they* must check whether
the underlying socket has been closed which is not the case with other
socket methods. For example, consider a loop like here:

index := 1.
[index <= buffer size] whileTrue:[
        count := socket receiveDataInto: buffer startingAt: index.
        index := index + count.
].

This would loop indefinitely if the socket connection gets closed while
you're in it. To fix this you can either change the caller to test
explicitly or change that method to raise an error when the closed
condition is detected.

Hope this helps,
   - Andreas