From: Joe deBlaquiere (joe@wirespeed.com)
Date: Thu Jul 20 2000 - 14:21:51 EDT
the pthreads library in glibc works great... and if you want to do your own
thread management, the clone() system call works (FYI : you might make sure
the kernel version you have actually uses the new stack area you pass
in...).
porting pthreads to uc-libc might be somewhat tedious, but still very
possible.
> -----Original Message-----
> From: owner-uclinux-dev@uClinux.org
> [mailto:owner-uclinux-dev@uClinux.org]On Behalf Of David Beckemeyer
> Sent: Thursday, July 20, 2000 12:06 PM
> To: uclinux-dev@uClinux.org
> Subject: Re: [uClinux-dev] RE: [UCLINUX] Old kernel, old argument, new
> (maybe) point(s)
>
>
>
> Nice list. You list multihread as (2). Does that mean you believe
> it's on the easier side? That would be better than fork() IMHO for
> my purposes.
>
>
> On Thu, Jul 20, 2000 at 05:37:58PM +0200, Vadim Lebedev wrote:
> > 1) implement a trivial malloc/free/realloc in libc which
> does not make mmap
> > for each allocation, because mmap allocate stuff in PAGEs
> so you make
> > malloc(12) and you get 1K allocated, very vasteful
>
> I implemented the following hack the other afternoon to solve the
> mekory leak problem I mentioned in a separate message. Perhaps
> this is something like what you describe, but either way I'd like
> peer review since I'm now using this in my libc (so far so good and
> it did resolve the memory leak for my case).
>
> ----------------------------------------------------------------
> #include <unistd.h>
> #include <sys/mman.h>
> #include <stdio.h>
> #include <stdlib.h>
>
>
> struct memblk
> {
> int mb_magic;
> struct memblk *mb_next;
> struct memblk *mb_prev;
> size_t mb_len;
> struct poolblk *mb_pool;
> };
>
>
> struct poolblk
> {
> struct poolblk *pb_next;
> struct memblk *pb_freelist;
> };
>
> static struct poolblk *poollist;
>
> #define POOLSIZE 8*1024
>
> #define MEM_MAGIC_FREE 0x46524545
> #define MEM_MAGIC_USED 0x55534544
>
> static void *
> real_malloc (size_t len)
> {
> void *result = mmap ((void *) 0, len, PROT_READ | PROT_WRITE,
> MAP_SHARED | MAP_ANONYMOUS, 0, 0);
> if (result == (void *) -1)
> return 0;
>
> return result;
>
>
> }
>
> /* unlink from the freelist */
> static
> mb_unlink (struct memblk *mb)
> {
> if (mb->mb_prev)
> mb->mb_prev->mb_next = mb->mb_next;
> else
> mb->mb_pool->pb_freelist = mb->mb_next;
> if (mb->mb_next)
> mb->mb_next->mb_prev = mb->mb_prev;
> mb->mb_magic = MEM_MAGIC_USED;
> }
>
> /* relink onto the end of the freelist */
> static
> mb_link (struct memblk *mb)
> {
> struct memblk *lastmb;
>
> lastmb = mb->mb_pool->pb_freelist;
> if (lastmb)
> {
> while (lastmb->mb_next)
> lastmb = lastmb->mb_next;
> lastmb->mb_next = mb;
> }
> else
> {
> mb->mb_pool->pb_freelist = mb;
> }
> mb->mb_prev = lastmb;
> mb->mb_next = 0;
> mb->mb_magic = MEM_MAGIC_FREE;
> }
>
>
> static char *
> alloc_memblk (struct memblk *mb, size_t len)
> {
> size_t newlen;
> struct memblk *newmb;
>
> newlen = mb->mb_len - len;
> if (newlen > 1023)
> {
> newmb = (struct memblk *) ((char *) mb + len);
>
> /* re-link the freelist */
> *newmb = *mb;
> if (mb->mb_prev)
> mb->mb_prev->mb_next = newmb;
> else
> mb->mb_pool->pb_freelist = newmb;
> if (mb->mb_next)
> mb->mb_next->mb_prev = newmb;
> newmb->mb_len = newlen;
> mb->mb_len = len;
> }
> else
> {
> mb_unlink (mb);
> }
> mb->mb_prev = mb->mb_next = 0;
> return ((char *) ++mb);
> }
>
> #ifdef MEMORY_DEBUG
> show_pools ()
> {
> struct poolblk *pb;
> struct memblk *mb;
>
> printf ("====\n");
> for (pb = poollist; pb; pb = pb->pb_next)
> {
> printf ("Pool %x\n", pb);
> for (mb = pb->pb_freelist; mb; mb = mb->mb_next)
> {
> printf (" Block: at %x %d bytes\n", mb, mb->mb_len);
> }
> }
> printf ("~~~~\n");
> }
> #endif
>
> static struct memblk *
> m_search_pool (size_t len)
> {
> struct poolblk *pb;
> struct memblk *mb;
>
> for (pb = poollist; pb; pb = pb->pb_next)
> {
> for (mb = pb->pb_freelist; mb; mb = mb->mb_next)
> if (mb->mb_len >= len)
> {
> #ifdef MEMORY_DEBUG
> printf ("found free segment at %x\n", mb);
> #endif
> return (mb);
> }
> }
> return ((struct memblk *) 0);
> }
>
> static
> defrag_heap ()
> {
> struct poolblk *pb;
> struct memblk *mb, *mb2, *mbend;
>
> #ifdef MEMORY_DEBUG
> printf ("Before defrag: ");
> show_pools ();
> #endif
>
> for (pb = poollist; pb; pb = pb->pb_next)
> {
> mb_again:
> for (mb = pb->pb_freelist; mb; mb = mb->mb_next)
> {
> mbend = (struct memblk *) ((char *) mb + mb->mb_len);
> for (mb2 = pb->pb_freelist; mb2; mb2 = mb2->mb_next)
> {
> if (mb2 == mbend)
> {
> /* unlink mb2 */
> mb_unlink (mb2);
> mb->mb_len += mb2->mb_len;
> goto mb_again;
> }
> }
> }
> }
>
> #ifdef MEMORY_DEBUG
> printf ("After defrag: ");
> show_pools ();
> #endif
> }
>
>
> void *
> malloc (size_t len)
> {
> struct poolblk *pb, *newpb;
> struct memblk *mb;
> size_t lenadj, poolsz;
> char *end;
>
> lenadj = (len + sizeof (struct memblk) + 1023) & ~1023;
> #ifdef MEMORY_DEBUG
> printf ("searching for segment of %d bytes\n", lenadj);
> #endif
>
> if (poollist)
> {
> mb = m_search_pool (lenadj);
> if (mb)
> return (alloc_memblk (mb, lenadj));
> #ifdef MEMORY_DEBUG
> printf ("cleaning the heap\n");
> #endif
> defrag_heap ();
> mb = m_search_pool (lenadj);
> if (mb)
> return (alloc_memblk (mb, lenadj));
> }
> #ifdef MEMORY_DEBUG
> printf ("allocating new pool\n");
> #endif
> if (lenadj + sizeof (struct poolblk) > POOLSIZE)
> poolsz = (lenadj + sizeof (struct poolblk) + 1023) & ~1023;
> else
> poolsz = POOLSIZE;
> newpb = (struct poolblk *) real_malloc (poolsz);
> if (!newpb)
> return ((char *) 0);
> if (poollist)
> {
> for (pb = poollist; pb->pb_next; pb = pb->pb_next)
> ;
> pb->pb_next = newpb;
> }
> else
> {
> poollist = newpb;
> }
> newpb->pb_next = 0;
> end = (char *) newpb + poolsz;
> mb = newpb->pb_freelist = (struct memblk *) (newpb + 1);
> mb->mb_next = 0;
> mb->mb_prev = 0;
> mb->mb_pool = newpb;
> mb->mb_len = end - (char *) mb;
> mb->mb_magic = MEM_MAGIC_FREE;
> #ifdef MEMORY_DEBUG
> printf ("newpb=%x\n", newpb);
> printf ("newpb->pb_freelist=%x\n", newpb->pb_freelist);
> printf ("newpb->pb_freelist->mb_len=%x\n",
> newpb->pb_freelist->mb_len);
> show_pools ();
> #endif
> mb = m_search_pool (lenadj);
> if (mb)
> return (alloc_memblk (mb, lenadj));
> #ifdef MEMORY_DEBUG
> printf ("huh? m_search_pool failed?");
> #endif
> return ((char *) 0);
> }
>
> void
> free (void *p)
> {
> struct memblk *mb;
>
> mb = (struct memblk *) p;
> --mb;
> if (mb->mb_magic != MEM_MAGIC_USED) {
> assert("attempted to free block with corrupt MAGIC");
> kill(getpid(), 11);
> }
> mb_link (mb);
> }
> This message resent by the uclinux-dev@uclinux.org list
> server http://www.uClinux.org/
>
This message resent by the uclinux-dev@uclinux.org list server http://www.uClinux.org/
This archive was generated by hypermail 2.1.4 : Thu Sep 19 2002 - 13:19:15 EDT