Re[11]: [Gc] boehm port to Native Client

Ivan Maidanski ivmai at mail.ru
Sun Feb 20 05:21:24 PST 2011


Hi Elijah,

I've finally finished with NaCl port. I've committed the patch (with some minor modifications). Please test it.

I found a number of bugs in the recent NaCl SDK (native_client_sdk_0_1_721_0 for Win32) - for most of them workaround is possible via -D option:
1. -m64 should be always specified with nacl64-gcc (and should not be specified with nacl-gcc) - typically -m32/m64 selects the compilation target but in NaCl SDK it only influences some predefined macros;
2. pthread.h: pthread_create lacks const for attr argument (to workaround use -DGC_PTHREAD_CONST= );
3. pthread.h: pthread_exit lacks __noreturn__ attribute (to workaround use -DGC_PTHREAD_EXIT_ATTRIBUTE= );
4. sys/features.h: _POSIX_TIMERS is not defined for NaCl (to workaround use -D_POSIX_TIMERS);
5. 64-bit GCC (nacl64-gcc (GCC) 4.4.3 20110124 (Native Client r4216)) produces incorrect code for "xaddq %0, %1" in AO_fetch_and_add_full in gcc/x86_64.h - it substitutes %0 with %eax instead of %rax (AO_fetch_and_add is used eg. in mallocx.c if PARALLEL_MARK).

Thu, 17 Feb 2011 10:28:14 +0300 Ivan Maidanski <ivmai at mail.ru>:

> Hi Elijah,
> 
> configure.ac should be modified to define AO_USE_NO_SIGNALS and
> AO_USE_NANOSLEEP for NaCl.
> 
> But, in fact, atomic_ops.c is not used by BDWGC since all is handled in *.h of
> libatomic_ops.
> 
> Regards.
> 
> Tue, 15 Feb 2011 15:17:04 -0800 Elijah Taylor <elijahtaylor at google.com>:
> 
> > Hi Ivan,
> > 
> > This patch has one problem, AO_USE_NANOSLEEP isn't defined for Native
> > Client.  When I conditionally define it based on __native_client__ in
> > atomic_ops.c it works.  Where is the best place to define something like
> > that, is atomic_ops.c ok?
> > 
> > -Elijah
> > 
> > On Tue, Feb 15, 2011 at 1:50 PM, Ivan Maidanski <ivmai at mail.ru> wrote:
> > 
> > > Hi Elijah,
> > >
> > > Please test the attached patch (against the latest CVS [Feb 13]).
> > > Note: the patch has been created with -b option for easier reading.
> > > I have no time to check it today.
> > >
> > > Regards.
> > >
> > > Wed, 9 Feb 2011 13:26:48 -0800 Elijah Taylor <elijahtaylor at google.com>:
> > >
> > > > Ok, I'll work on getting my config changes to the checked in configure
> > > > scripts and I'll post a patch then.  In the meantime, at least you have
> > > the
> > > > patch I sent (not sure if anyone else on the list cares right now) so I
> > > > won't bother re-sending.
> > > >
> > > >
> > > >
> > > > On Wed, Feb 9, 2011 at 1:23 PM, Ivan Maidanski <ivmai at mail.ru> wrote:
> > > >
> > > > > Hi,
> > > > >
> > > > > Yes, config.sub is auto-generated (by autoreconf -vif), so please
> > > modify
> > > > > configure.ac, etc.
> > > > >
> > > > > It is ok if you're going to produce a patch against that "floating"
> > > bdwgc
> > > > > snapshot (2011-01-07).
> > > > > You don't need to hold off - just post a patch for the audience when
> > > ready.
> > > > >
> > > > > I'll produce another snapshot in several days (collecting this and
> some
> > > > > other patches in).
> > > > >
> > > > > PS If you hit the limit of this mailing list (around 30 KiB) - please
> > > cut
> > > > > it into 2 (or more) parts (don't wait for the moderator - even I have
> > > this
> > > > > limit).
> > > > >
> > > > > Regards.
> > > > >
> > > > > Wed, 9 Feb 2011 13:14:56 -0800 Elijah Taylor <elijahtaylor at google.com
> > > >:
> > > > >
> > > > > > Hi Ivan,
> > > > > >
> > > > > > Great, that looks very similar to my porting effort.
> > > > > >
> > > > > > I also have a patch against the tarball that's been floating around
> > > on
> > > > > this
> > > > > > list (attached).  I've been holding off on it until now waiting for
> > > > > > sourceforge access to come back online.  I'm modifying some
> > > config.sub
> > > > > and
> > > > > > other config files which are distributed with a snapshot but I
> > > suspect
> > > > > when
> > > > > > they're built from source in the tree they're system files that
> can't
> > > be
> > > > > > modified, so we may have to change configure.in to compensate.
> > > > > >
> > > > > > I've tested this patched libgc in Native Client and it seems to work
> > > > > well.
> > > > > >
> > > > > > -Elijah
> > > > > >
> > > > > >
> > > > > > On Wed, Feb 9, 2011 at 1:04 PM, Ivan Maidanski <ivmai at mail.ru>
> > > wrote:
> > > > > >
> > > > > > > Hi Elijah,
> > > > > > >
> > > > > > > I've ported libatomic_ops to NaCl.
> > > > > > > The patch attached.
> > > > > > >
> > > > > > > NaCl target requires -DAO_USE_NO_SIGNALS -DAO_USE_NANOSLEEP
> > > > > > >
> > > > > > > ChangeLog entries:
> > > > > > > 2011-02-09  Ivan Maidanski  <ivmai at mail.ru>
> > > > > > >
> > > > > > >        * src/atomic_ops.c (AO_USE_NO_SIGNALS, AO_USE_NANOSLEEP):
> > > New
> > > > > > >        macros.
> > > > > > >        * src/atomic_ops.c (AO_USE_WIN32_PTHREADS): Imply
> > > > > > >        AO_USE_NO_SIGNALS.
> > > > > > >        * src/atomic_ops.c: Don't include signal.h if
> > > AO_USE_NO_SIGNALS.
> > > > > > >        * src/atomic_ops.c: Include time.h if AO_USE_NANOSLEEP.
> > > > > > >        * src/atomic_ops.c (AO_locks, AO_pause): Reformat the code.
> > > > > > >        * src/atomic_ops.c (AO_pause): Use nanosleep() if
> > > > > > >        AO_USE_NANOSLEEP.
> > > > > > >        * src/atomic_ops.c (all_sigs, initialized,
> > > > > > >        AO_compare_and_swap_emulation,
> > > > > > >        AO_compare_double_and_swap_double_emulation): Use
> > > > > > >        AO_USE_NO_SIGNALS instead of AO_USE_WIN32_PTHREADS.
> > > > > > >
> > > > > > > Regards.
> > > > > > >
> > > > > > > > > >
> > > > > > > > > > Fri, 14 Jan 2011 15:36:34 -0800 письмо от Elijah Taylor <
> > > > > > > > > > elijahtaylor at google.com (sentmsg?compose&To=
> > > > > elijahtaylor at google.com)
> > > > > > > >:
> > > > > > > > > >
> > > > > > > > > > > Hi Ivan,
> > > > > > > > > > >
> > > > > > > > > > > Thanks for taking a look, I'm pleasantly surprised by the
> > > level
> > > > > of
> > > > > > > > > detail
> > > > > > > > > > > here.  Specific replies inline:
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > On Fri, Jan 14, 2011 at 2:50 PM, Ivan Maidanski <
> > > > > ivmai at mail.ru
> > > > > > > > > > (sentmsg?compose&To=ivmai at mail.ru) > wrote:
> > > > > > > > > > >
> > > > > > > > > > > - the patch in  naclports repository contains a typo in a
> > > macro
> > > > > > > > > definition
> > > > > > > > > > > > (MAC_TYPE -> MACH_TYPE);
> > > > > > > > > > >
> > > > > > > > > > > Oops, will fix.
> > > > > > > > > >
> > > > > > > > > > Why not to leave MACH_TYPE as-is (e.g. "I386", etc.)? NaCl
> is
> > > a
> > > > > kind
> > > > > > > of
> > > > > > > > > OS not
> > > > > > > > > > a kind of machine hardware.
> > > > > > > > > > Is eg. I386 defined for x86?
> > > > > > > > > >
> > > > > > > > > > Also, please add a mapping comment in gcconfig.h (around
> > > "Feel
> > > > > free
> > > > > > > to
> > > > > > > > > add
> > > > > > > > > > more clauses here").
> > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > > - the patch in  naclports repository looks more suitable
> > > for
> > > > > gc
> > > > > > > v72
> > > > > > > > > than
> > > > > > > > > > > > that for mono/libgc;
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > This patch is meant to be applied to vanilla gc6.8.  The
> > > > > mono/libgc
> > > > > > > > > port is
> > > > > > > > > > > already patched directly into mono's code repository.
> > > > > > > > > >
> > > > > > > > > > Yes, I only meant the vanilla gc6.8 patch contains some more
> > > code
> > > > > > > (eg,
> > > > > > > > > for
> > > > > > > > > > PARALLEL_MARK) not present in mono/libgc.
> > > > > > > > > >
> > > > > > > > > > > > - gc_pthread_redirects.h (which is a public one) should
> > > not
> > > > > test
> > > > > > > NACL
> > > > > > > > > > macro
> > > > > > > > > > > > (or, at least, while less desirable, it should be
> > > prefixed
> > > > > with
> > > > > > > GC_);
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Ok, makes sense, I think I didn't realize this was a
> public
> > > > > header.
> > > > > > > > >  Though
> > > > > > > > > > > that explains why I had to add a test for
> __native_client__
> > > > >  (which
> > > > > > > is
> > > > > > > > > > > defined in our toolchain).  I'll fix this.
> > > > > > > > > > >
> > > > > > > > > > > > - it's not clear why you need to explicitly undef
> > > STACK_GRAN,
> > > > > > > > > > USE_M[UN]MAP,
> > > > > > > > > > > > etc. in gcconfig.h;
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > I'll do some investigation, but IIRC these were needed at
> > > one
> > > > > point
> > > > > > > for
> > > > > > > > > me.
> > > > > > > > > > > There's a good chance these may be unnecessary and
> > > vestigial.
> > > > > > > > > >
> > > > > > > > > > There should none "undef" (no other target undefining them).
> > > > > > > > > >
> > > > > > > > > > If mmap is supported by NaCl then it might be possible to
> > > support
> > > > > > > > > > USE_M[UN]MAP.
> > > > > > > > > >
> > > > > > > > > > > > - is MPROTECT_VDB supported or not?;
> > > > > > > > > > >
> > > > > > > > > > > Is MPROTECT_VDB equivalent to catching protection
> > > violations in
> > > > > the
> > > > > > > GC
> > > > > > > > > code?
> > > > > > > > > > > If so, then no, we don't support anything like that right
> > > now.
> > > > > > > > >  Protection
> > > > > > > > > > > violation in NaCl == instant death.
> > > > > > > > > >
> > > > > > > > > > Ok, so MPROTECT_VDB (i.e., incremental/generation
> collection)
> > > is
> > > > > not
> > > > > > > > > > supported.
> > > > > > > > > >
> > > > > > > > > > > > - if you you want to port gc72 please use the recent CVS
> > > > > snapshot
> > > > > > > (it
> > > > > > > > > > would
> > > > > > > > > > > > be easier to me to review and commit it);
> > > > > > > > > > >
> > > > > > > > > > > I've been grabbing source from
> > > > > > > > > > >  http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/
> > > > > > > > > > (http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/)
> > >  ...
> > > > > can
> > > > > > > you
> > > > > > > > > point
> > > > > > > > > > me
> > > > > > > > > > > to where I should be getting the latest?  It's not
> > > immediately
> > > > > > > obvious
> > > > > > > > > to
> > > > > > > > > > > me.
> > > > > > > > > >
> > > > > > > > > > http://bdwgc.cvs.sourceforge.net/viewvc/bdwgc/bdwgc/
> > > > > > > > > > (For convenience, I have a recent snapshot as a tarball
> which
> > > I
> > > > > use
> > > > > > > for
> > > > > > > > > my
> > > > > > > > > > project -
> > > > > > > > > >
> > > > > > >
> > > http://www.ivmaisoft.com/_mirror/hpl/bdwgc-7_2alpha5-20110107.tar.bz2)
> > > > > > > > > >
> > > > > > > > > > > - not sure that HEURISTIC1 really works reliably there (in
> > > > > short,
> > > > > > > > > HEURISTIC1
> > > > > > > > > > > > means you treat stack pointer at GC_init call as stack
> > > bottom
> > > > > -
> > > > > > > is it
> > > > > > > > > > > > guaranteed that GC_init call is always done at higher
> > > stack
> > > > > > > addresses
> > > > > > > > > than
> > > > > > > > > > > > any other GC call);
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > HEURISTIC2 will definitely not work for us as it wants to
> > > use a
> > > > > > > > > segfault to
> > > > > > > > > > > detect running over the stack.  I've set STACK_GRAN to
> 64K,
> > > so
> > > > > as
> > > > > > > long
> > > > > > > > > as
> > > > > > > > > > > the stack doesn't grow beyond that size before GC_init, we
> > > > > should
> > > > > > > be
> > > > > > > > > ok,as
> > > > > > > > > > > right?  The stack for the main thread right now in NaCl
> > > lives
> > > > > at a
> > > > > > > > > fixed
> > > > > > > > > > > address usually, but that isn't guaranteed for all future
> > > time,
> > > > > so
> > > > > > > I'd
> > > > > > > > > > > prefer not to hard code magic numbers here.
> > > > > > > > > >
> > > > > > > > > > No, HEURISTIC2 won't work without signals, but there are
> > > other
> > > > > > > > > alternatives:
> > > > > > > > > > - if threads-support is on then is it possible to use
> > > > > > > > > > USE_GET_STACKBASE_FOR_MAIN?;
> > > > > > > > > > - is it possible to LINUX_STACKBOTTOM (if we are on real
> > > Linux)?
> > > > > > > > > > - for NaCl on Cygwin, it might be possible to use
> > > > > > > > > GC_get_[main_]stack_base
> > > > > > > > > > based on __asm__ ("%fs:4").
> > > > > > > > > >
> > > > > > > > > > > > - is the GC port compilable (and working) on other
> > > > > (non-Linux)
> > > > > > > > > platforms
> > > > > > > > > > > > (eg., Cygwin);
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Native Client is meant to be portable, so it should run on
> > > any
> > > > > x86
> > > > > > > or
> > > > > > > > > x86-64
> > > > > > > > > > > machine once it's built.  In terms of building, I haven't
> > > built
> > > > > > > this gc
> > > > > > > > > port
> > > > > > > > > > > personally on Mac or Windows, but I just checked our build
> > > bot
> > > > > logs
> > > > > > > and
> > > > > > > > > they
> > > > > > > > > > > seem to be building ok on Mac and in Cygwin.
> > > > > > > > > >
> > > > > > > > > > So, eg. DARWIN, GC_DARWIN_THREADS,  WIN32, CYGWIN,
> > > > > GC_WIN32_THREADS
> > > > > > > won't
> > > > > > > > > ever
> > > > > > > > > > be defined when building NaCl, right?
> > > > > > > > > > Is GC_LINUX_THREADS defined when building NaCl with
> > > > > multi-threaded
> > > > > > > > > support?
> > > > > > > > > >
> > > > > > > > > > I have very little knowledge of NaCl - could you briefly
> > > explain
> > > > > what
> > > > > > > > > does
> > > > > > > > > > stand for NaCl portability - is it possible to call Win32
> API
> > > if
> > > > > I'm
> > > > > > > > > compiling
> > > > > > > > > > on Cygwin or should I use the NaCl API (and, thus, the
> > > compiled
> > > > > > > binary
> > > > > > > > > code
> > > > > > > > > > will run on any x86 target)?
> > > > > > > > > >
> > > > > > > > > > If NaCl is some kind of OS then LINUX, DARWIN, WIN32, etc
> > > > > shouldn't
> > > > > > > be
> > > > > > > > > defined
> > > > > > > > > > (even if __linux__ defined) if NACL.
> > > > > > > > > > Same for GC_xxx_THREADS - I think GC_NACL_THREADS could be
> > > > > defined
> > > > > > > > > instead of
> > > > > > > > > > GC_LINUX_THREADS, etc.
> > > > > > > > > >
> > > > > > > > > > I also think that I386 and X86_64 should stay defined for
> > > > > > > respectively
> > > > > > > > > the
> > > > > > > > > > corresponding CPU type (I guess it is already for NaCl but i
> > > > > haven't
> > > > > > > > > checked
> > > > > > > > > > yet)
> > > > > > > > > > I think there should be 2 ifdef NACL define OS_TYPE "NACL"
> > > ...
> > > > > > > sections
> > > > > > > > > (one
> > > > > > > > > > for every supported CPU).
> > > > > > > > > >
> > > > > > > > > > > > - for non-static GC-internal symbols use GC_ prefix (eg.
> > > for
> > > > > > > > > > > > nacl_thread_parked);
> > > > > > > > > > > > - define SIG_SUSPEND to -1 (instead of 0) as it is
> > > returned
> > > > > by
> > > > > > > > > > > > GC_get_suspend_signal;
> > > > > > > > > > > > - GC functions called from NaCl it self (eg,
> > > > > > > nacl_pre_syscall_hook)
> > > > > > > > > shoud
> > > > > > > > > > > > be tagged with some attribute (like public GC functions
> > > are)
> > > > > both
> > > > > > > for
> > > > > > > > > code
> > > > > > > > > > > > readability and to prevent that symbols stripping when
> > > > > compiled
> > > > > > > as a
> > > > > > > > > > shared
> > > > > > > > > > > > lib with -DGC_DLL);
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > I'll address these issues.  (note that NaCl currently
> > > doesn't
> > > > > > > support
> > > > > > > > > shared
> > > > > > > > > > > libs yet so your dll example won't happen, but I agree
> that
> > > > > these
> > > > > > > > > should be
> > > > > > > > > > > treated like other public GC functions)
> > > > > > > > > >
> > > > > > > > > > Ok. But what is eg. nacl_pre_syscall_hook() - a callback
> from
> > > the
> > > > > > > NaCl
> > > > > > > > > > subsystem? (I guess this should be treated as GC public API)
> > > > > > > > > >
> > > > > > > > > > Of course, use STATIC or static where possible (all STATIC
> > > > > symbols
> > > > > > > start
> > > > > > > > > with
> > > > > > > > > > GC_, while static typically not).
> > > > > > > > > > More tips: use GC_INNER and GC_EXTERN for internal global
> > > > > variables;
> > > > > > > use
> > > > > > > > > > GC_INNER for internal functions.
> > > > > > > > > >
> > > > > > > > > > > > - libatomic_ops does not use signals API (except for CAS
> > > > > > > emulation
> > > > > > > > > which
> > > > > > > > > > is
> > > > > > > > > > > > not used for x86/x64).
> > > > > > > > > > >
> > > > > > > > > > > I think I saw sigprocmask and related functions and
> assumed
> > > the
> > > > > > > worst,
> > > > > > > > > but I
> > > > > > > > > > > see now that's windows code.  Looking at the x86 variants
> > > it
> > > > > looks
> > > > > > > like
> > > > > > > > > a
> > > > > > > > > > > NaCl port of libatomic_ops is probably not going to be too
> > > bad.
> > > > > > >  I'll
> > > > > > > > > look
> > > > > > > > > > > into this eventually.
> > > > > > > > > >
> > > > > > > > > > Most probably, it work w/o any porting afforts but it would
> > > be
> > > > > good
> > > > > > > to
> > > > > > > > > port
> > > > > > > > > > atomic_ops.c (similar to what I did for Win32-pthreads
> > > targets -
> > > > > see
> > > > > > > > > > AO_USE_WIN32_PTHREADS, I guess you should add AO_USE_NACL
> > > macro
> > > > > > > testing
> > > > > > > > > in
> > > > > > > > > > that file (looks easy to add). I think it's worth doing
> first
> > > > > (and
> > > > > > > submit
> > > > > > > > > me a
> > > > > > > > > > separate patch for libatomics_op when done).
> > > > > > > > > >
> > > > > > > > > > What's about GC_HAVE_BUILTIN_BACKTRACE and
> > > > > GC_CAN_SAVE_CALL_STACKS?
> > > > > > > At
> > > > > > > > > least,
> > > > > > > > > > gc.h should be consistent with the GC implementation (I mean
> > > eg.
> > > > > if
> > > > > > > > > > GC_HAVE_BUILTIN_BACKTRACE not supported then it shouldn't be
> > > > > defined
> > > > > > > in
> > > > > > > > > gc.h
> > > > > > > > > > regardless of __linux__, _MSC_VER, etc. provided
> > > > >  __native_client__).
> > > > > > > > > Same for
> > > > > > > > > > GC_ADD_CALLER, GC_RETURN_ADDR.
> > > > > > > > > >
> > > > > > > > > > Regards.
> > > > > > > > > >
> > > > > > > > > > > > PS. Let me not do the benefits analysis (probably
> someone
> > > > > else
> > > > > > > can do
> > > > > > > > > > > > this).
> > > > > > > > > > > >
> > > > > > > > > > > Well, if the gc7.2 port is as easy as it's looking now, I
> > > think
> > > > > > > it's
> > > > > > > > > > > probably worth doing it.  I would still love to hear
> anyone
> > > > > chime
> > > > > > > in on
> > > > > > > > > the
> > > > > > > > > > > benefits of gc7.2 vs 6.8 though
> > > > > > > > > > >
> > > > > > > > > > > > Regards.
> > > > > > > > > > > >
> > > > > > > > > > > > Thu, 13 Jan 2011 10:21:03 -0800 Elijah Taylor <
> > > > > > > > > elijahtaylor at google.com
> > > > > > > > > > (sentmsg?compose&To=elijahtaylor at google.com) >:
> > > > > > > > > > > >
> > > > > > > > > > > > > Hi GC folks,
> > > > > > > > > > > >
> > > > > > > > > > > > > I saw a little chatter in the archives related to
> > > porting
> > > > > libgc
> > > > > > > to
> > > > > > > > > > Native
> > > > > > > > > > > > Client, so I joined this list to share some details. I'm
> > > the
> > > > > > > engineer
> > > > > > > > > at
> > > > > > > > > > > > Google who ported of libgc to Native Client for Mono.
> > > I've
> > > > > also
> > > > > > > > > included a
> > > > > > > > > > > > patch for vanilla gc6.8 in our naclports repository:
> > > > > > > > > > > >  http://code.google.com/p/naclports/ (
> > > > > > > > > http://code.google.com/p/naclports/)
> > > > > > > > > > . This version will be available to
> > > > > > > > > > > > users that want to use libgc as part of their Native
> > > Client
> > > > > > > projects.
> > > > > > > > > > > >
> > > > > > > > > > > > > Before porting gc6.8 I had attempted to port one of
> the
> > > > > newer
> > > > > > > > > versions,
> > > > > > > > > > > > gc7.2alpha4, but ran into snags. The largest snag right
> > > now I
> > > > > > > think
> > > > > > > > > is
> > > > > > > > > > that
> > > > > > > > > > > > gc 7+ includes libatomic_ops which will require some
> > > > > non-trivial
> > > > > > > > > effort in
> > > > > > > > > > > > order to work under Native Client. Most notably we don't
> > > > > support
> > > > > > > > > signals;
> > > > > > > > > > > > that was the biggest effort in porting libgc in the
> first
> > > > > place
> > > > > > > for
> > > > > > > > > NaCl,
> > > > > > > > > > > > and I assume that will require the most work in porting
> > > > > > > libatomic_ops
> > > > > > > > > too.
> > > > > > > > > > > >
> > > > > > > > > > > > > Can someone give me the high level details of what
> kind
> > > of
> > > > > > > things
> > > > > > > > > we
> > > > > > > > > > > > might be missing if we only support gc6.8 instead of the
> > > > > latest
> > > > > > > > > version?
> > > > > > > > > > > > Because of our thread stopping implementation, we may
> not
> > > > > even
> > > > > > > > > benefit
> > > > > > > > > > from
> > > > > > > > > > > > some of the newer features. I just wanted to get a sense
> > > of
> > > > > what
> > > > > > > the
> > > > > > > > > > > > benefits are of getting a newer version available for
> > > users.
> > > > > > > > > > > >
> > > > > > > > > > > > > -Elijah



More information about the Gc mailing list