Re: MemSet inline for newNode - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: MemSet inline for newNode
Date
Msg-id 200211111918.gABJIFn21757@candle.pha.pa.us
Whole thread Raw
In response to Re: MemSet inline for newNode  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: MemSet inline for newNode  (Bruce Momjian <pgman@candle.pha.pa.us>)
List pgsql-patches
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I can't do MemSet in a macro that returns a value, as palloc requires.
> > MemSet has a loop, and that can't be done in a macro that returns a value.
>
> Hm.  How did Neil test this originally --- was he relying on being able
> to "inline" newNode()?

Yes.

> Anyway, I don't think that passing an extra parameter can be a win.
> If there has to be a runtime test, testing whether the two low bits
> of the length are zero is probably about the same speed as testing a
> boolean parameter.  It's unlikely to be enough slower to justify the
> cost of passing another parameter.

OK, new version attached, with extra parameter removed.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/backend/utils/mmgr/mcxt.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/mmgr/mcxt.c,v
retrieving revision 1.35
diff -c -c -r1.35 mcxt.c
*** src/backend/utils/mmgr/mcxt.c    10 Nov 2002 02:17:25 -0000    1.35
--- src/backend/utils/mmgr/mcxt.c    11 Nov 2002 19:11:05 -0000
***************
*** 453,466 ****
  }

  /*
!  * MemoryContextAllocZero
   *        Like MemoryContextAlloc, but clears allocated memory
   *
   *    We could just call MemoryContextAlloc then clear the memory, but this
   *    function is called too many times, so we have a separate version.
   */
  void *
! MemoryContextAllocZero(MemoryContext context, Size size)
  {
      void *ret;

--- 453,466 ----
  }

  /*
!  * MemoryContextAllocPalloc0
   *        Like MemoryContextAlloc, but clears allocated memory
   *
   *    We could just call MemoryContextAlloc then clear the memory, but this
   *    function is called too many times, so we have a separate version.
   */
  void *
! MemoryContextAllocPalloc0(MemoryContext context, Size size)
  {
      void *ret;

***************
*** 471,477 ****
               (unsigned long) size);

      ret = (*context->methods->alloc) (context, size);
!     MemSet(ret, 0, size);
      return ret;
  }

--- 471,477 ----
               (unsigned long) size);

      ret = (*context->methods->alloc) (context, size);
!     MemSetLoop(ret, 0, size);
      return ret;
  }

Index: src/include/c.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/c.h,v
retrieving revision 1.131
diff -c -c -r1.131 c.h
*** src/include/c.h    11 Nov 2002 03:02:19 -0000    1.131
--- src/include/c.h    11 Nov 2002 19:11:08 -0000
***************
*** 577,602 ****
   *    memset() functions.  More research needs to be done, perhaps with
   *    platform-specific MEMSET_LOOP_LIMIT values or tests in configure.
   *
   *    bjm 2002-10-08
   */
! #define MemSet(start, val, len) \
!     do \
!     { \
!         int32 * _start = (int32 *) (start); \
!         int        _val = (val); \
!         Size    _len = (len); \
  \
!         if ((( ((long) _start) | _len) & INT_ALIGN_MASK) == 0 && \
!             _val == 0 && \
!             _len <= MEMSET_LOOP_LIMIT) \
!         { \
!             int32 * _stop = (int32 *) ((char *) _start + _len); \
!             while (_start < _stop) \
!                 *_start++ = 0; \
!         } \
!         else \
!             memset((char *) _start, _val, _len); \
!     } while (0)

  #define MEMSET_LOOP_LIMIT  1024

--- 577,612 ----
   *    memset() functions.  More research needs to be done, perhaps with
   *    platform-specific MEMSET_LOOP_LIMIT values or tests in configure.
   *
+  *    MemSet has been split into two parts so MemSetTest can be optimized
+  *    away for constant 'val' and 'len'.  This is used by palloc0().
+  *
+  *    Note, arguments are evaluated more than once.
+  *
   *    bjm 2002-10-08
   */
! #define MemSetTest(val, len) \
!     ( ((len) & INT_ALIGN_MASK) == 0 && \
!     (len) <= MEMSET_LOOP_LIMIT && \
!     (val) == 0 )
!
! #define MemSetLoop(start, val, len) \
! do \
! { \
!     int32 * _start = (int32 *) (start); \
!     int32 * _stop = (int32 *) ((char *) _start + (len)); \
  \
!     while (_start < _stop) \
!         *_start++ = 0; \
! } while (0)
!
! #define MemSet(start, val, len) \
! do \
! { \
!     if (MemSetTest(val, len) && ((long)(start) & INT_ALIGN_MASK) == 0 ) \
!         MemSetLoop(start, val, len); \
!     else \
!         memset((char *)(start), (val), (len)); \
! } while (0)

  #define MEMSET_LOOP_LIMIT  1024

Index: src/include/utils/palloc.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/utils/palloc.h,v
retrieving revision 1.22
diff -c -c -r1.22 palloc.h
*** src/include/utils/palloc.h    10 Nov 2002 02:17:25 -0000    1.22
--- src/include/utils/palloc.h    11 Nov 2002 19:11:10 -0000
***************
*** 46,56 ****
   * Fundamental memory-allocation operations (more are in utils/memutils.h)
   */
  extern void *MemoryContextAlloc(MemoryContext context, Size size);
! extern void *MemoryContextAllocZero(MemoryContext context, Size size);

  #define palloc(sz)    MemoryContextAlloc(CurrentMemoryContext, (sz))

! #define palloc0(sz)    MemoryContextAllocZero(CurrentMemoryContext, (sz))

  extern void pfree(void *pointer);

--- 46,59 ----
   * Fundamental memory-allocation operations (more are in utils/memutils.h)
   */
  extern void *MemoryContextAlloc(MemoryContext context, Size size);
! extern void *MemoryContextAllocPalloc0(MemoryContext context, Size size);

  #define palloc(sz)    MemoryContextAlloc(CurrentMemoryContext, (sz))

! #define palloc0(sz)    \
!     ( MemSetTest(0, (sz)) ? \
!         MemoryContextAllocPalloc0(CurrentMemoryContext, (sz)) : \
!         memset(palloc(sz), 0, (sz)))

  extern void pfree(void *pointer);


pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: minor SGML fix
Next
From: Peter Eisentraut
Date:
Subject: Re: minor SGML fix