delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/01/11/20:02:44

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Thu, 11 Jan 2001 20:02:48 -0500
MIME-Version: 1.0
Subject: memalign & valloc patch v2
Message-ID: <3A5E1168.31413.E8B6A2@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

Aloha,

The updated memalign & valloc now pass the grueling gcc bootstrap test.

However, all attempts to deal with releasing the space between the malloc'ed 
pointer and the aligned pointer (in the memalign context)  when the space is 
< 8 have not passed the gcc test so far. Any ideas on how to somehow free up 
this space? One way that works is to allocate the amount requested plus two 
times the alignment. Then adjust the aligned pointer's value up by 
'alignment' if it's too close to the unaligned pointer (in the memalign 
context). However, this fragments memory even more than the current memalign.

*** /dev/null	Thu Jan 11 19:48:42 2001
--- include/libc/malloc.h	Mon Jan  8 17:18:50 2001
***************
*** 0 ****
--- 1,40 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+ #ifndef __dj_include_libc_malloc_h__
+ #define __dj_include_libc_malloc_h__
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ 
+ #ifndef __dj_ENFORCE_ANSI_FREESTANDING
+ 
+ #ifndef __STRICT_ANSI__
+ 
+ #ifndef _POSIX_SOURCE
+ 
+ typedef struct BLOCK {
+   size_t size;
+   struct BLOCK *next;
+   int bucket;
+ } BLOCK;
+ 
+ #define BEFSZ(bp)	(*(size_t *)((char *)bp - 4))
+ #define ENDSZ(bp)	(*(size_t *)((char *)bp + (bp->size & ~1) + 4))
+ #define BEFORE(bp)	((BLOCK *)((char *)bp - (BEFSZ(bp) & ~1) - 8))
+ #define AFTER(bp)	((BLOCK *)((char *)bp + ((bp->size & ~1) + 8)))
+ #define DATA(bp)	((char *)&(bp->next))
+ 
+ #define ALIGN		8
+ 
+ #endif /* !_POSIX_SOURCE */
+ #endif /* !__STRICT_ANSI__ */
+ #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+ 
+ #ifndef __dj_ENFORCE_FUNCTION_CALLS
+ #endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif /* __dj_include_libc_atexit_h__ */
*** /dev/null	Thu Jan 11 19:48:42 2001
--- src/libc/compat/stdlib/valloc.c	Wed Jan 10 00:52:16 2001
***************
*** 0 ****
--- 1,15 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+ 
+ #include <unistd.h>
+ void *memalign (size_t, size_t);
+ 
+ void *
+ valloc (size_t amt)
+ {
+   static int page_size = -1;
+ 
+   if (page_size == -1)
+     page_size = getpagesize();
+ 
+   return memalign (amt, page_size);
+ }
*** /dev/null	Thu Jan 11 19:48:42 2001
--- src/libc/compat/stdlib/valloc.txh	Thu Jan 11 19:02:20 2001
***************
*** 0 ****
--- 1,27 ----
+ @node valloc, memory
+ @subheading Syntax
+ 
+ @example
+ #include <stdlib.h>
+ 
+ void *valloc(size_t size);
+ @end example
+ 
+ @subheading Description
+ 
+ This function is just like @code{malloc} (@pxref{malloc}) except the returned
+ pointer is a multiple of the CPU page size or 4096 bytes.
+ 
+ @subheading Return Value
+ 
+ A pointer to a newly allocated block of memory. 
+ 
+ @subheading Portability
+ 
+ @portability !ansi, !posix
+ 
+ @subheading Example
+ 
+ @example
+ char *page = valloc(getpagesize());
+ @end example
*** /dev/null	Thu Jan 11 19:48:42 2001
--- src/libc/compat/stdlib/memalign.c	Thu Jan 11 19:43:04 2001
***************
*** 0 ****
--- 1,94 ----
+ /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+ #include <stdlib.h>
+ #include <libc/malloc.h>
+ 
+ /* Make VAL a multiple of ALIGN.  */
+ static inline
+ size_t
+ align_val (size_t val, size_t align)
+ {
+   return ((val + (align - 1)) & ~(align - 1));
+ }
+ 
+ /* Split a chunk of previously allocated memory into two chunks so both can
+    be released with a call to free().  */
+ static void *
+ split_alloc (char *ptr, size_t split_pos)
+ {
+   BLOCK *b1, *b2;
+   char *split_ptr;
+   
+   b1 = (BLOCK *)(ptr - 4);
+ 
+   /* Set location of second pointer and its block info.  */
+   split_ptr = ptr + split_pos;
+   b2 = (BLOCK *)(split_ptr - 4);
+ 
+   /* Set up the two blocks.  */
+   b2->size = (b1->size - split_pos) | 1;
+   b1->size = (split_pos - 8) | 1;
+   
+   ENDSZ(b1) = b1->size;
+   ENDSZ(b2) = b2->size;
+ 
+   return DATA(b2);  
+ }
+ 
+ /* Return a block of memory AMT bytes long whose address is a multiple
+    ALIGN.  ALIGN must be a power of 2.  */
+ 
+ #define DEBUG 0
+ void *
+ memalign (size_t amt, size_t align)
+ {
+   char *ptr, *aligned_ptr;
+   BLOCK *b;
+   size_t alloc_size, before_size, after_size;
+ 
+   if (align != align_val(align, align))
+     return NULL;
+ 
+   if (align < ALIGN)
+     align = ALIGN;
+ 
+   if (align == ALIGN)
+     return malloc (amt);
+     
+   amt = align_val (amt, ALIGN);
+   alloc_size = amt + align;
+   
+   ptr = malloc(alloc_size);
+   if (ptr == NULL)
+     return ptr;
+ 
+   aligned_ptr = (char *)align_val((size_t)ptr, align);
+ 
+   /* Amount of space between the malloc'ed pointer
+      and the aligned pointer.  */
+   before_size = (aligned_ptr - ptr);
+ 
+ #if DEBUG
+   printf ("# align = %i, amt = %i, before_size = %i, after_size = %i, ptr = %x, aligned_ptr = %x\n",
+           align, amt, before_size, (alloc_size - before_size - amt), (void *)ptr, (void *)aligned_ptr);
+ #endif
+   if (before_size)
+   {
+     aligned_ptr = split_alloc (ptr, before_size);
+     /* FIXME: What to do when before_size <= 8?  */
+     if (before_size > 8)
+       free (ptr);
+   }
+ 
+   /* Release extra space after the aligned block. Avoid
+      creating an empty block.  */
+   after_size = alloc_size - before_size - amt;
+   if (after_size >= 16)
+   {
+     char *after;
+     after = split_alloc (aligned_ptr, amt + 8);
+     free (after);
+   }
+ 
+   return aligned_ptr;
+ }
+ 
*** /dev/null	Thu Jan 11 19:48:42 2001
--- src/libc/compat/stdlib/memalign.txh	Thu Jan 11 19:02:24 2001
***************
*** 0 ****
--- 1,28 ----
+ @node memalign, memory
+ @subheading Syntax
+ 
+ @example
+ #include <stdlib.h>
+ 
+ void *memalign(size_t size, size_t alignment);
+ @end example
+ 
+ @subheading Description
+ 
+ This function is just like @code{malloc} (@pxref{malloc}) except the returned
+ pointer is a multiple of @var{alignment}. @var{alignment} must be a power of
+ 2.
+ 
+ @subheading Return Value
+ 
+ A pointer to a newly allocated block of memory. 
+ 
+ @subheading Portability
+ 
+ @portability !ansi, !posix
+ 
+ @subheading Example
+ 
+ @example
+ char *page = memalign(1024, 1024 * 4);
+ @end example
*** src/libc/ansi/stdlib/malloc.c.orig	Sun Jan  7 00:01:36 2001
--- src/libc/ansi/stdlib/malloc.c	Thu Jan 11 19:47:36 2001
***************
*** 7,27 ****
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
! 
! typedef struct BLOCK {
!   size_t size;
!   struct BLOCK *next;
!   int bucket;
! } BLOCK;
! 
! #define BEFORE(bp)	((BLOCK *)((char *)bp - *(int *)((char *)bp - 4) - 8))
! #define BEFSZ(bp)	(*(size_t *)((char *)bp - 4))
! #define ENDSZ(bp)	(*(size_t *)((char *)bp + bp->size + 4))
! #define AFTER(bp)	((BLOCK *)((char *)bp + bp->size + 8))
! #define DATA(bp)	((char *)&(bp->next))
  
  #define NUMSMALL	0
- #define ALIGN		8
  #define SMALL		(NUMSMALL*ALIGN)
  
  static BLOCK *slop = 0;
--- 7,15 ----
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
! #include <libc/malloc.h>
  
  #define NUMSMALL	0
  #define SMALL		(NUMSMALL*ALIGN)
  
  static BLOCK *slop = 0;
*** include/stdlib.h.orig	Sun Jan  7 00:05:42 2001
--- include/stdlib.h	Sun Jan  7 00:07:18 2001
*************** long long	llabs(long long _i);
*** 102,107 ****
--- 102,108 ----
  lldiv_t		lldiv(long long _numer, long long _denom);
  void            lcong48(unsigned short param[7]);
  unsigned long   lrand48(void);
+ void *		memalign(size_t _size, size_t _align);
  long            mrand48(void);
  unsigned long   nrand48(unsigned short state[3]);
  int		putenv(const char *_val);
*************** long double	_strtold(const char *_s, cha
*** 113,118 ****
--- 114,120 ----
  long long	strtoll(const char *_s, char **_endptr, int _base);
  unsigned long long strtoull(const char *_s, char **_endptr, int _base);
  void		swab(const void *from, void *to, int nbytes);
+ void *		valloc(size_t _amount);
  
  #ifndef alloca
  #define alloca __builtin_alloca
*** src/libc/compat/stdlib/makefile.orig	Sun Jan  7 00:10:42 2001
--- src/libc/compat/stdlib/makefile	Sun Jan  7 00:11:38 2001
*************** SRC += fcvtbuf.c
*** 22,27 ****
  SRC += fcvt.c
  SRC += gcvt.c
  SRC += rand48.c
! 
  
  include $(TOP)/../makefile.inc
--- 22,28 ----
  SRC += fcvt.c
  SRC += gcvt.c
  SRC += rand48.c
! SRC += memalign.c
! SRC += valloc.c
  
  include $(TOP)/../makefile.inc

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019