Ticket #1829 (closed bug: fixed)

Opened 4 years ago

Last modified 4 years ago

Recent changes impeded building and testing on smaller boxes

Reported by: jkeenan Owned by:
Priority: normal Milestone:
Component: build Version: 2.8.0
Severity: medium Keywords:
Cc: chromatic, cotto, bacek, GeJ Language:
Patch status: Platform:

Description

This issue has been discussed on parrot-dev, starting  here. But it should be Trac-ked. So I'll start by reposting my original post, plus what I've done to mitigate the problem:

During development of the gc_massacre branch, I tried to build and test 
parrot on both Linux/i386 and Darwin/PPC.  I have used each of these 
machines for testing since I joined the Parrot project in late 2006. 
While I have never explicitly tracked how fast 'make' and 'make test' 
run on those boxes, I do have a general sense of how long those 
processes take.

I noticed that when I was building and testing the gc_massacre branch on 
the Darwin/PPC box (a 6-year-old iBook G4 running Mac OS X 4.11), all 
other operations on that machine would slow to a crawl.  For example, 
using Alt-Tab to toggle among programs would work only with 30-60 
seconds of latency.  Switching from terminal to a browser (SeaMonkey or 
Camino) sometimes took 5 minutes.  This slowdown was most noticeable in 
the parts of 'make' where './ops2c' was being run.  'make test' ground 
to a halt in 't/compilers/opsc/*.t'.

Trunk was continuing to build and test satisfactorily at this time, but 
once the gc_massacre branch was merged into trunk at r49269, trunk began 
to suffer all the same problems that the branch had.  My unscientific 
impression is that 'make' now takes 10% longer to complete (e.g., 12 
minutes version 10-1/2 minutes), though it has taken as long as 19 
minutes.  But what is most striking is that 'make test' won't complete 
at all unless I manually delete the tests in 't/compilers/opsc/*.t' from 
the roster of tests.  The '01' test in that directory will complete ... 
and then I will get no output whatsoever from the '02' test.  If I 
Ctrl-C to kill the '02' test, the '03' test will run -- but other tests 
in this directory will hang indefinitely as well.

Last night bacek was able to devote some attention to this problem.  He 
pointed to a particular line of code recently merged in from the 
gc_massacre branch and asked me to make a manual change:

$ svn diff
Index: src/gc/gc_ms2.c
===================================================================
--- src/gc/gc_ms2.c     (revision 49323)
+++ src/gc/gc_ms2.c     (working copy)
@@ -623,7 +623,8 @@

          /* Collect every 256M allocated. */
          /* Hardcode for now. Will be configured via CLI */
-        self->gc_threshold = 256 * 1024 * 1024;
+/*        self->gc_threshold = 256 * 1024 * 1024; */
+        self->gc_threshold = 64 * 1024 * 1024;
      }
      interp->gc_sys->gc_private = self;

256M happens to be amount of Physical Memory reported by 'top' for this 
machine.  Changing the gc_threshold from 256M to 64M did enable 'make 
test' to run completely (including t/compilers/opsc/*.t) and PASS in 
about 19 minutes.  So the value of the gc_threshold does have a 
significant impact on whether parrot will run (in any meaningful sense) 
on a particular machine.

Now, I know that there are some who will snigger at the thought of 
trying to test Parrot on a machine that is more than 6 years old.  "Just 
go out and buy a new laptop, kid51.  It'll be sure to have at least 10 
times as much memory as that ancient, battered box."

Needless to say, I don't accept that logic -- and not only because 
"ancient, battered box" describes the box's owner as well as the box. 
As I pointed out when voicing a similar problem with Rakudo Star, if 
we've been able to build and run a particular program (Parrot, Rakudo 
Perl, whatever) on a particular machine for years on end, and if we can 
no longer do so, then our scientific rigor ought to require us to 
determine *why* we can no longer do so, rather than sweeping the problem 
under the rug.  AFAICT, we have never specified minimum memory or other 
requirements for building or running Parrot on any particular box. 
Hence, it seems to me to be reasonable to assume that if Parrot build on 
a particular box in 2006, it will continue to do so indefinitely unless 
building on that box is explicitly deprecated by the project.  After 
all, it's quite possible that when Parrot runs on embedded devices in 
the future, it will have to run in an environment with even less memory 
than this ancient, battered box has.

Here is the way I currently hack src/gc/gc_ms2.c to get Parrot to build on this box with 256K physical memory. I do this in trunk -- and I have to do it in any branch forked from trunk subsequent to r49269.

Index: src/gc/gc_ms2.c
===================================================================
--- src/gc/gc_ms2.c     (revision 49555)
+++ src/gc/gc_ms2.c     (working copy)
@@ -623,7 +623,9 @@
 
         /* Collect every 256M allocated. */
         /* Hardcode for now. Will be configured via CLI */
-        self->gc_threshold = 256 * 1024 * 1024;
+/*        self->gc_threshold = 256 * 1024 * 1024; */
+/*        self->gc_threshold = 64 * 1024 * 1024; */
+        self->gc_threshold = 16 * 1024 * 1024;
     }
     interp->gc_sys->gc_private = self;
 

Change History

  Changed 4 years ago by chromatic

  • status changed from new to closed
  • resolution set to fixed

Fixed as of r49557. We still need the CLI configuration system, but we'll be in better shape for 2.9 with this change in place.

  Changed 4 years ago by pmichaud

  • status changed from closed to reopened
  • resolution fixed deleted

r49557 was reverted in r49583; r49557 was causing Rakudo build times to take 6x longer. See thread at  http://lists.parrot.org/pipermail/parrot-dev/2010-October/004929.html.

Reopening ticket.

Pm

follow-up: ↓ 4   Changed 4 years ago by jkeenan

To recapitulate where we stand on this ticket ...

On Saturday, October 16, in r49557, chromatic committed to trunk the one-line hack that had been enabling me to build -- albeit slowly -- the Parrot executable on a small-physical-memory-by-today's-standards (256MM) machine since the gc_massacre merge in r49269. This passed smoke tests on all platforms reported to Smolder between that time and the moment on Tuesday, October 19, when Gerd tagged trunk and released Parrot 2.9.0.

Almost as soon as that release was made, Rakudo Perl 6 developers -- who were planning to do a monthly release targeted on top of Parrot 2.9.0 three days after the latter's release -- began reporting that Rakudo builds were now "unbearably slow." These reports started to come in just before our weekly #parrotsketch meeting and the issues dominated discussion at that meeting. Ultimately, the consensus was to revert r49269 (performed by Util++ in r49583) and to do a bug fix release, Parrot 2.9.1 (performed by cotto+ in r49584).

As expected, this meant that on my small-resource machine Parrot once again took an inordinately long time to run 'make' and 'make test' -- though both ultimately concluded successfully. The times I recorded were:

'make':          28:54
'make smoke': 2:08::51

If the definition of "unbearably slow" is "so slow as to make developing Parrot (or other application) on this box not feasible", then I think it's safe to say that this is "unbearably slow" -- but not broken.

Since Tuesday, bacek++ and fperrad++ have been making commits to trunk in the hope of probing the build machine for the amount of memory and using an algorithm to determine an appropriate GC threshold. We have successful smolder reports mostly for Linux.

Alas, these more recent commits prevent a successful build on Darwin. Here's the tail end of my build log:

config/gen/platform/generic/sysmem.c: In function 'Parrot_sysmem_amount':
config/gen/platform/generic/sysmem.c:44: error: '_SC_AVPHYS_PAGES' undeclared (first use in this function)
config/gen/platform/generic/sysmem.c:44: error: (Each undeclared identifier is reported only once
config/gen/platform/generic/sysmem.c:44: error: for each function it appears in.)
make: *** [src/platform.o] Error 1

bacek has suggested that this GNU file  physmem.c may have some code we can use for Darwin. I have not yet had time to try this out.

So that's where things stand, at least for me, just before UTC 0000 Thursday Oct 21.

Thank you very much.

kid51

in reply to: ↑ 3 ; follow-up: ↓ 5   Changed 4 years ago by doughera

Replying to jkeenan:

> config/gen/platform/generic/sysmem.c: In function 'Parrot_sysmem_amount':
> config/gen/platform/generic/sysmem.c:44: error: '_SC_AVPHYS_PAGES' undeclared (first use in this function)

I suspect the same error will occur on most BSD derivatives as well.

bacek has suggested that this GNU file  physmem.c may have some code we can use for Darwin. I have not yet had time to try this out.

Please do note carefully that the physmem.c file is licensed under the GPL.

in reply to: ↑ 4 ; follow-ups: ↓ 6 ↓ 8   Changed 4 years ago by jkeenan

Replying to doughera:

Replying to jkeenan: {{{

config/gen/platform/generic/sysmem.c: In function 'Parrot_sysmem_amount': config/gen/platform/generic/sysmem.c:44: error: '_SC_AVPHYS_PAGES' undeclared (first use in this function)

}}} I suspect the same error will occur on most BSD derivatives as well.

Well, I worked up a program based on code found in various Apple mailing lists, and cotto turned it into config/gen/platform/darwin/sysmem.c -- and GeJ turned that into config/gen/platform/freebsd/sysmem.c.

But my build problems on Darwin are still not solved. I'm getting past the previous failure point, but am now failing at:

/usr/bin/gcc -I./include -I./include/pmc -pipe -fno-common -Wno-long-double  
-I/sw/include -I/opt/local/include -DHASATTRIBUTE_CONST  -DHASATTRIBUTE_DEPRECATED  
-DHASATTRIBUTE_MALLOC  -DHASATTRIBUTE_NONNULL  -DHASATTRIBUTE_NORETURN  -DHASATTRIBUTE_PURE  
-DHASATTRIBUTE_UNUSED  -DHASATTRIBUTE_WARN_UNUSED_RESULT  -DHAS_GETTEXT  
-g     -falign-functions=16 -fvisibility=hidden -funit-at-a-time -W -Wall 
-Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment 
-Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wextra -Wformat 
-Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k 
-Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch -Wmissing-braces 
-Wmissing-field-initializers -Wno-missing-format-attribute 
-Wmissing-include-dirs -Wmultichar -Wpacked -Wparentheses -Wpointer-arith -Wpointer-sign -Wreturn-type -Wsequence-point -Wsign-compare 
-Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch -Wswitch-default 
-Wtrigraphs -Wundef -Wno-unused -Wunknown-pragmas -Wvariadic-macros 
-Wwrite-strings -Wbad-function-cast -Wdeclaration-after-statement 
-Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-declarations 
-Wmissing-prototypes -Wnested-externs -Wnonnull -Wold-style-definition 
-Wstrict-prototypes -Isrc -o src/null_config.o -c src/null_config.c
/usr/bin/g++ -o miniparrot src/main.o src/null_config.o \
-L/Users/jimk/work/parrot/blib/lib -L/Users/jimk/work/parrot/blib/lib -lparrot  
  -lm -lgmp -lreadline -lintl -undefined dynamic_lookup -L/sw/lib -L/opt/local/lib  
./miniparrot -Iruntime/parrot/include config_lib.pir > runtime/parrot/include/config.fpmc
src/string/api.c:702: failed assertion 'encoding'
make: *** [runtime/parrot/include/config.fpmc] Error 134

At an earlier point in this build, I got this warning:

config/gen/platform/darwin/sysmem.c:38: warning: no previous prototype 
  for 'Parrot_sysmem_amount'

I don't know whether these are related.

Please do note carefully that the physmem.c file is licensed under the GPL.

Can you spell out the implications for us?

Thanks.

kid51

in reply to: ↑ 5   Changed 4 years ago by doughera

Replying to jkeenan:

Replying to doughera:

Please do note carefully that the physmem.c file is licensed under the GPL.

Can you spell out the implications for us?

No, not easily. Software licenses often confuse me.

The link provided above  http://www.opensource.apple.com/source/gcc/gcc-5646.1/libiberty/physmem.c links to a source file released under the GPL v2. According to the GPL-2.0 FAQ  http://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.html#IfLibraryIsGPL (quoted here for simplicity because it is short)

If a library is released under the GPL (not the LGPL), does that mean that any program which uses it has to be under the GPL?

Yes, because the program as it is actually run includes the library.

It may well be that libiberty is also available under other licesnses, such as LGPL, which might ease the integration process. I haven't checked. It also is the case that, at least for BSD, and probably for darwin, the sysctl man page contains examples suitable for cut & paste, so it is easy to "indepdendently" come up with the essentially same implementation. Still, the aggregation of such things in the physmem.c file is a copyrighted work. It is appropriate to respect the author's wishes.

  Changed 4 years ago by whiteknight

In general we cannot use code directly that is under a different open source license. Think about an essay in a paper in school: You can't just copy work from somebody else. There is some possibility that we could use a short snippet of code under a "fair use" provision, but that's shakey in the world of software and isn't always legal.

Here are the options we have available to us:

  • Rewrite the functions ourselves, from scratch, using available documentation. I don't suspect that the writers of that file will press charges if our re-write isn't perfectly "clean", but there's no sense chancing it.
  • We can request the author grant a special license to use his code to us under the artistic license. A friendly, personal email could do the trick if the author is receptive to that kind of thing. It's my experience that relatively few people are extremely tied to particular licenses, so this might be a good option.
  • We can include his file in our project, unmodified (including all his attribution and licensing information). This turns Parrot into what's called an "aggregate" (in GPL-speak) and puts some additional legal requirements on our project. For instance, we must include a copy of the GPL with our distro, declare that Parrot is an aggregate under the artistic license and the GPL, bar our contributors from making non-GPL modifications to that file, etc. It's a mess, but should be possible (I need to re-read the artistic license text for more details on this).

I suggest somebody send Paul Eggert an email, if possible, and see if we can make this easy on ourselves.

in reply to: ↑ 5 ; follow-up: ↓ 9   Changed 4 years ago by jkeenan

  • cc cotto, bacek added

Replying to jkeenan:

This morning I reported that after upping to get config/gen/platform/darwin/sysmem.c, I was getting thie error:

> src/string/api.c:702: failed assertion 'encoding'
> make: *** [runtime/parrot/include/config.fpmc] Error 134

I also reported that earlier in the build, I got this warning:

> config/gen/platform/darwin/sysmem.c:38: warning: no previous prototype 
>   for 'Parrot_sysmem_amount'

I didn't know whether the latter was related to the former.

I'm now persuaded that there is a connection. First, I am not getting any no previous prototype warning in this part of my build log on Linux/i386.

Second, I've had a closer look at the code cited in the failure message on Darwin. Here is the relevant part of src/string/api.c:

 695 PARROT_EXPORT
 696 PARROT_WARN_UNUSED_RESULT
 697 PARROT_CANNOT_RETURN_NULL
 698 STRING *
 699 Parrot_str_new_init(PARROT_INTERP, ARGIN_NULLOK(const char *buffer), UINTVAL len,
 700         ARGIN(const STR_VTABLE *encoding), UINTVAL flags)
 701 {
 702     ASSERT_ARGS(Parrot_str_new_init)
 703     DECL_CONST_CAST;
 704     STRING * const s = Parrot_gc_new_string_header(interp, flags);
 705     s->encoding      = encoding;
 706         
 707     if (flags & PObj_external_FLAG) {

Note that line 702 is the start of a function block which contains a call to Parrot_gc_new_string_header -- a GC-related function.

Here's the definition of Parrot_gc_new_string_header in src/gc/api.c:

 339 PARROT_CANNOT_RETURN_NULL
 340 PARROT_WARN_UNUSED_RESULT
 341 STRING *
 342 Parrot_gc_new_string_header(PARROT_INTERP, UINTVAL flags)
 343 {       
 344     ASSERT_ARGS(Parrot_gc_new_string_header)
 345         
 346     STRING * const string = interp->gc_sys->allocate_string_header(interp, flags);
 347     if (!string)
 348         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_ALLOCATION_ERROR,
 349             "Parrot VM: STRING allocation failed!\n");
 350 
 351     string->strstart        = NULL;
 352     PObj_get_FLAGS(string) |=
 353         flags | PObj_is_string_FLAG | PObj_is_COWable_FLAG;
 354 
 355     return string;
 356 }

Third, as an experiment, in src/gc/gc_ms2.c on Darwin, I reverted to the same hack which was enabling me to build on this box over the past two weeks -- i.e., to the same code that gave Rakudo such headaches on Tuesday of this week:

Index: src/gc/gc_ms2.c
===================================================================
--- src/gc/gc_ms2.c     (revision 49627)
+++ src/gc/gc_ms2.c     (working copy)
@@ -15,7 +15,7 @@
 #include "parrot/parrot.h"
 #include "parrot/gc_api.h"
 #include "parrot/list.h"
-#include "parrot/sysmem.h"
+/*#include "parrot/sysmem.h" */
 #include "gc_private.h"
 #include "fixed_allocator.h"
 
@@ -633,7 +633,10 @@
 
         /* Collect every 256M allocated. */
         /* Hardcode for now. Will be configured via CLI */
+        /*
         self->gc_threshold = Parrot_sysmem_amount(interp) / 8;
+        */
+        self->gc_threshold = 16 * 1024 * 1024;
     }
 
     interp->gc_sys->gc_private = self;

After this reversion, I called make and Parrot successfully built.

So I infer that while the various config/gen/platform/*/sysmem.c files work on generic, win32, etc., config/gen/platform/darwin/sysmem.c is not yet doing what we need it to do.

Let me add that I don't think this is just my problem. We haven't had any smoke reports on Darwin on our smolder server since the 2.9.1 release.

Suggestions?

Thank you very much.

kid51

in reply to: ↑ 8   Changed 4 years ago by jkeenan

Replying to jkeenan:

+ /* self->gc_threshold = Parrot_sysmem_amount(interp) / 8; + */ + self->gc_threshold = 16 * 1024 * 1024; } interp->gc_sys->gc_private = self; }}} After this reversion, I called make and Parrot successfully built.

And with this hack (and only with this hack), I was able to  test satisfactorily.

kid51

  Changed 4 years ago by jkeenan

  • cc GeJ added

GeJ++ suggested s/HW_MEMSIZE/HW_PHYSMEM/ to avoid the build error on Darwin. This worked on Darwin/PPC (OS X 10.4). This needs to be tested on Darwin/i386 in OS X 10.5 and 10.6.

Will leave ticket open in hope that we get smolders on those platforms.

Thank you very much.

kid51

follow-up: ↓ 12   Changed 4 years ago by bacek

Hello.

We have at least one successful report on Darwin/i386 -  http://smolder.parrot.org/app/projects/report_details/1059

Can we close this ticket?

-- Bacek.

in reply to: ↑ 11   Changed 4 years ago by jkeenan

  • status changed from reopened to closed
  • resolution set to fixed

Replying to bacek:

Hello. We have at least one successful report on Darwin/i386 -  http://smolder.parrot.org/app/projects/report_details/1059 Can we close this ticket?

If we confine the discussion to the issues as reported in this ticket, yes, we can close it and I will do so with this commit.

However, the more fundamental issue is the fact that our memory requirements had dramatically increased (a) without anyone actually realizing it; and (b) without any discussion of what our memory requirements ought to be. (This applies even moreso to Rakudo, but that's a discussion for another list.) We were implicitly saying that we didn't care whether Parrot built or not on what are now considered small-RAM devices.

In closing this ticket, I hope it is clear that the memory requirements for building Parrot continue to be a concern that we all share.

Thank you very much.

kid51

Note: See TracTickets for help on using tickets.