patch: fix build problems on Solaris

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

patch: fix build problems on Solaris

Andrew Gaylard
 
Hi,

This patch fixes 4 problems which prevented the VM from building
on Solaris/SPARC.  They shouldn't cause problems for other
platforms (famous last words), so please would someone (Ian?)
confirm this before checking in.

The problems fixed by this patch are:
  1. "sun" is already defined by some header or other in Solaris;
    I've changed it to s_un.
  2. AF_LOCAL isn't defined on Solaris.  W Richard Stevens'
    "Advanced programming in the Unix environment" says that
    AF_UNIX is more standard anyway.
  3. Solaris' feof() call really wants a FILE*.
  4. A missing prototype is added for sound_AvailableSpace(void)
With this patch, the VM builds and runs fine if built with gcc-3.4.3.
I've checked both the stock 3.9a-7024 image as well as the
etoys image. (My motivation for this whole exercise is to fix the
problems with audio under Solaris for my young daughter to use
etoys: the first sound plays, but after that, no sounds ever play.)

With gcc-4.2.1 and -O2, the VM won't even start up (complains
about a missing vm-display-X11, even though it's there).  With
gcc-4.2.1 and no -O2, the VM starts, runs for a short while, and
then cores with a bus error.  gdb shows a corrupt stack.  I'm
about to build gcc-4.1.2 and give it a spin building the VM to
try to track this down.  But I do suspect bad code generation
with gcc-4.2.1.


Thanks,
Andrew

Index: platforms/unix/plugins/SocketPlugin/sqUnixSocket.c
===================================================================
--- platforms/unix/plugins/SocketPlugin/sqUnixSocket.c  (revision 1762)
+++ platforms/unix/plugins/SocketPlugin/sqUnixSocket.c  (working copy)
@@ -149,7 +149,7 @@
 union sockaddr_any
 {
   struct sockaddr      sa;
-  struct sockaddr_un   sun;
+  struct sockaddr_un   s_un;
   struct sockaddr_in   sin;
   struct sockaddr_in6  sin6;
 };
@@ -533,7 +533,7 @@
   switch (domain)
     {
     case 0:    domain= AF_INET;        break;  /* SQ_SOCKET_DOMAIN_UNSPECIFIED */
-    case 1:    domain= AF_LOCAL;       break;  /* SQ_SOCKET_DOMAIN_LOCAL */
+    case 1:    domain= AF_UNIX;        break;  /* SQ_SOCKET_DOMAIN_LOCAL */
     case 2:    domain= AF_INET;        break;  /* SQ_SOCKET_DOMAIN_INET4 */
     case 3:    domain= AF_INET6;       break;  /* SQ_SOCKET_DOMAIN_INET6 */
     }
@@ -1563,16 +1563,16 @@
       struct stat st;
       if ((0 == stat(servName, &st)) && (st.st_mode & S_IFSOCK))
        {
-         struct sockaddr_un *sun= calloc(1, sizeof(struct sockaddr_un));
+         struct sockaddr_un *s_un= calloc(1, sizeof(struct sockaddr_un));
          localInfo= (struct addrinfo *)calloc(1, sizeof(struct addrinfo));
-         localInfo->ai_family= AF_LOCAL;
+         localInfo->ai_family= AF_UNIX;
          localInfo->ai_socktype= SOCK_STREAM;
          localInfo->ai_addrlen= sizeof(struct sockaddr_un);
-         localInfo->ai_addr= (struct sockaddr *)sun;
-         /*sun->sun_len= sizeof(struct sockaddr_un);*/
-         sun->sun_family= AF_LOCAL;
-         memcpy(sun->sun_path, servName, servSize);
-         sun->sun_path[servSize]= '\0';
+         localInfo->ai_addr= (struct sockaddr *)s_un;
+         /*s_un->sun_len= sizeof(struct sockaddr_un);*/
+         s_un->sun_family= AF_UNIX;
+         memcpy(s_un->sun_path, servName, servSize);
+         s_un->sun_path[servSize]= '\0';
          addrInfo= localInfo;
          interpreterProxy->signalSemaphoreWithIndex(resolverSema);
          return;
@@ -1586,7 +1586,7 @@
 
   switch (family)
     {
-    case SQ_SOCKET_FAMILY_LOCAL:       request.ai_family= AF_LOCAL;            break;
+    case SQ_SOCKET_FAMILY_LOCAL:       request.ai_family= AF_UNIX;             break;
     case SQ_SOCKET_FAMILY_INET4:       request.ai_family= AF_INET;             break;
     case SQ_SOCKET_FAMILY_INET6:       request.ai_family= AF_INET6;            break;
     }
@@ -1657,7 +1657,7 @@
   fprintf(stderr, " ");
   switch (addr->sa_family)
     {
-    case AF_LOCAL:     fprintf(stderr, "local\n"); break;
+    case AF_UNIX:      fprintf(stderr, "local\n"); break;
     case AF_INET:      fprintf(stderr, "inet\n"); break;
     case AF_INET6:     fprintf(stderr, "inet6\n"); break;
     default:           fprintf(stderr, "?\n"); break;
@@ -1698,7 +1698,7 @@
 
   switch (addrInfo->ai_family)
     {
-    case AF_LOCAL:     return SQ_SOCKET_FAMILY_LOCAL;
+    case AF_UNIX:      return SQ_SOCKET_FAMILY_LOCAL;
     case AF_INET:      return SQ_SOCKET_FAMILY_INET4;
     case AF_INET6:     return SQ_SOCKET_FAMILY_INET6;
     }
Index: platforms/unix/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c
===================================================================
--- platforms/unix/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c        (revision 1762)
+++ platforms/unix/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c        (working copy)
@@ -1818,7 +1818,7 @@
                return interpreterProxy->primitiveFail();
        }
        sqFile = interpreterProxy->arrayValueOf(sqFileOop);
-       if ((feof(sqFile->file)) == 0) {
+       if ((feof((FILE*)(sqFile->file))) == 0) {
                result = interpreterProxy->falseObject();
        } else {
                result = interpreterProxy->trueObject();
Index: platforms/unix/vm-sound-Sun/sqUnixSoundSun.c
===================================================================
--- platforms/unix/vm-sound-Sun/sqUnixSoundSun.c        (revision 1762)
+++ platforms/unix/vm-sound-Sun/sqUnixSoundSun.c        (working copy)
@@ -55,6 +55,7 @@
 #endif
 
 static int sound_Stop(void);
+static int sound_AvailableSpace(void);
 
 static int auFd=              -1;   /* open on /dev/dsp */
 static int fmtStereo=          0;   /* whether we are playing in stereo or not */

Reply | Threaded
Open this post in threaded view
|

Re: patch: fix build problems on Solaris

Andreas Wacknitz
 
Andrew Gaylard wrote:
 



Hi,
Hi Andrew,


This patch fixes 4 problems which prevented the VM from building
on Solaris/SPARC.  They shouldn't cause problems for other
Interesting that there is another guy running Squeak under Solaris.

platforms (famous last words), so please would someone (Ian?)
confirm this before checking in.

The problems fixed by this patch are:
  1. "sun" is already defined by some header or other in Solaris;
    I've changed it to s_un.
  2. AF_LOCAL isn't defined on Solaris.  W Richard Stevens'
    "Advanced programming in the Unix environment" says that
    AF_UNIX is more standard anyway.
  3. Solaris' feof() call really wants a FILE*.
  4. A missing prototype is added for sound_AvailableSpace(void)
Which version of the VM sources you are talking about?
I have 3.9-8 running for quite some time on my Blade 2000.
Although I haven't used sound yet.
I have good experiences with Sun's CoolTools gcc for SPARC systems.
This is a gcc-4.0.4 frontend with a SunStudio 12 code generator.
The code runs at least twice as fast as with a plain gcc-3.4.3.


With this patch, the VM builds and runs fine if built with gcc-3.4.3.
I've checked both the stock 3.9a-7024 image as well as the
etoys image. (My motivation for this whole exercise is to fix the
problems with audio under Solaris for my young daughter to use
etoys: the first sound plays, but after that, no sounds ever play.)

With gcc-4.2.1 and -O2, the VM won't even start up (complains
about a missing vm-display-X11, even though it's there).  With
gcc-4.2.1 and no -O2, the VM starts, runs for a short while, and
then cores with a bus error.  gdb shows a corrupt stack.  I'm
about to build gcc-4.1.2 and give it a spin building the VM to
try to track this down.  But I do suspect bad code generation
with gcc-4.2.1.
Did you manage to build libffi-2.0? This library is part of gcc-4.2.1.
AFAIK it is necessary for Squeak's FFI. I have only an old libffi-1.2.0 that
has some Solaris bugs. So I don't have FFI which is needed for some interesting
packages (e.g. ODBC).

Regards
Andreas

Reply | Threaded
Open this post in threaded view
|

Re: patch: fix build problems on Solaris

Andrew Gaylard
 
Hi VM people,

I apologise in advance for the length of this post.

On 9/27/07, Andreas Wacknitz <[hidden email]> wrote:
This patch fixes 4 problems which prevented the VM from building
on Solaris/SPARC.  They shouldn't cause problems for other
Interesting that there is another guy running Squeak under Solaris.

Yeah.  I have an Intel Linux PC at  work and a Sun SPARC at home.
How times have changed!

Which version of the VM sources you are talking about?
I have 3.9-8 running for quite some time on my Blade 2000.
Although I haven't used sound yet.

This is the Subversion sources that I'm building, rev 1762.

I have good experiences with Sun's CoolTools gcc for SPARC systems.
This is a gcc-4.0.4 frontend with a SunStudio 12 code generator.
The code runs at least twice as fast as with a plain gcc-3.4.3.

Cool. That's good to know.
 
With this patch, the VM builds and runs fine if built with gcc-3.4.3.
I've checked both the stock 3.9a-7024 image as well as the
etoys image. (My motivation for this whole exercise is to fix the
problems with audio under Solaris for my young daughter to use
etoys: the first sound plays, but after that, no sounds ever play.)

With gcc-4.2.1 and -O2, the VM won't even start up (complains
about a missing vm-display-X11, even though it's there).  With
gcc-4.2.1 and no -O2, the VM starts, runs for a short while, and
then cores with a bus error.  gdb shows a corrupt stack.  I'm
about to build gcc-4.1.2 and give it a spin building the VM to
try to track this down.  But I do suspect bad code generation
with gcc-4.2.1.

I take back what I said about gcc-4.2.1.  I'm pretty sure that this was
due to user-stupidity (mine).

Did you manage to build libffi-2.0? This library is part of gcc-4.2.1.
AFAIK it is necessary for Squeak's FFI. I have only an old libffi-1.2.0 that
has some Solaris bugs. So I don't have FFI which is needed for some interesting
packages (e.g. ODBC).

Hmm. I haven't tried building libffi.  That might be my next project,
once this is sorted out. Anyway, on to the sound problems.

1/
Thanks to the patch by Wolfgang Helbig at
http://lists.squeakfoundation.org/pipermail/vm-dev/2006-January/000450.html
the problem was quite simple to fix.  I made a few small changes,
and sound is working on Solaris/SPARC hardware natively (no NAS
needed).  Note that it looks like vm-sound-sun never implemented
recording; this is playback only (which is fine for my purposes).

2/
According to the squeak porting guide, to make sounds, the snd_Start
C function is called.  This is passed a (Squeak/smalltalk) semaphore
"that should be signalled when input/output completes".  I take it this
means that the sound driver should signal the semaphore when the
sound device has space for writing.

(An old copy of the Squeak porting guide is here:
<a href="http://coweb.cc.gatech.edu/squeakbook/uploads/porting.1.pdf" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"> http://coweb.cc.gatech.edu/squeakbook/uploads/porting.1.pdf
I have a much newer version on paper, but I can't remember where
I got it.)

When I send a sound, it plays fine, but when I signal the semaphore
that output has completed, the VM keeps writing more and more stuff to
the sound device.  I assume that it's writing "silence", since I hear
nothing after the initial sound.  But it does keep the CPU quite busy
as you might imagine.

3/
I have instrumented the C code where the VM checks for I/O (aioPoll),
and under ordinary usage (keyboard, mouse, etc.) I get under 20
polls/second.  As soon as a sound has started playing, this jumps
to 2300+ polls/second, and stays there, even when the sound is
played and silence reigns.

I can't figure out why it would do this.

Clearly, since the buffer is large enough to contain only a fraction
of a second of audio data, the semaphore is needed to tell the VM
to send some more data. And clearly the select() call in aioPoll will
notice the file-descriptor for /dev/audio is writable as soon as the
first sample is played, and continuously thereafter, so I can
understand that during playback the poll-rate should be high.  This
problem should be fix-able by using the STREAMS SIGPOLL to
trigger the auHandle() function, rather than using select().

However, once the whole sound is played, why would the VM
continue playing nothing at full speed?  Even with the SIGPOLL
handler in place -- I'm about to try it now -- the VM is still issuing
write() calls to /dev/audio several time per second, indefinitely.

I'm sure I'm missing something here...

Andrew
Reply | Threaded
Open this post in threaded view
|

Re: patch: fix build problems on Solaris

Andrew Gaylard
 
On 9/27/07, Andrew Gaylard <[hidden email]> wrote:

When I send a sound, it plays fine, but when I signal the semaphore
that output has completed, the VM keeps writing more and more stuff to
the sound device.  I assume that it's writing "silence", since I hear
nothing after the initial sound.  But it does keep the CPU quite busy
as you might imagine.

I have instrumented the C code where the VM checks for I/O (aioPoll),
and under ordinary usage (keyboard, mouse, etc.) I get under 20
polls/second.  As soon as a sound has started playing, this jumps
to 2300+ polls/second, and stays there, even when the sound is
played and silence reigns.

I can't figure out why it would do this.

Clearly, since the buffer is large enough to contain only a fraction
of a second of audio data, the semaphore is needed to tell the VM
to send some more data. And clearly the select() call in aioPoll will
notice the file-descriptor for /dev/audio is writable as soon as the
first sample is played, and continuously thereafter, so I can
understand that during playback the poll-rate should be high.  This
problem should be fix-able by using the STREAMS SIGPOLL to
trigger the auHandle() function, rather than using select().

However, once the whole sound is played, why would the VM
continue playing nothing at full speed?  Even with the SIGPOLL
handler in place -- I'm about to try it now -- the VM is still issuing
write() calls to /dev/audio several time per second, indefinitely.

I'm sure I'm missing something here...

OK, I've done some more digging  into this problem, and have
implemented the SIGPOLL-based scheme.  This works as well
as the select()-based scheme of Wolfgang Helbig; i.e. there's no
discernible difference in the sound quality.

The problem with the VM playing silence at full speed once the
first sound has played, remains.  I'm not sure what to do about
this, as I am fairly sure it is not a driver issue.

Here are some figures showing the performance:

(a) Newly-started VM, idle for 60s
  1-minute load-average: 0.22
  '23633677 bytecodes/sec; 990806 sends/sec'

(b) select driver, 60s after playing a 1-second-long sound
  1-minute load-average: 1.14
  '21932830 bytecodes/sec; 899000 sends/sec'

(c) sigpoll driver, 60s after playing a 1-second-long sound
  1-minute load-average: 0.62
  '21592442 bytecodes/sec; 911752 sends/sec'

Clearly, the writes to /dev/audio keep the squeak
process busy in both cases (b) and (c).  Case (b)
has the added disadvantage of spending a great
deal of time in select calls.

For reference, my system details are:
- Sun SPARC Ultra-60, 2x400MHz CPUs
- Squeak SVN tree r1749
- unchanged etoys image, files dated September 7, 2005
- gcc-3.4.3

The new driver files are attached.  Since the changes are
widespread, I have not made patches (but will on request).
Can someone please check the sqUnixSoundSun.c file
into SVN (assuming it's OK)?  I have included the other file,
sqUnixSoundSun-select.c, for comparison only.

Thanks,
Andrew

sqUnixSoundSun.c (11K) Download Attachment
sqUnixSoundSun-select.c (9K) Download Attachment