avr-libc-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-commit] [2151] Move some testscripts around.


From: Joerg Wunsch
Subject: [avr-libc-commit] [2151] Move some testscripts around.
Date: Wed, 09 Jun 2010 20:49:07 +0000

Revision: 2151
          http://svn.sv.gnu.org/viewvc/?view=rev&root=avr-libc&revision=2151
Author:   joerg_wunsch
Date:     2010-06-09 20:49:06 +0000 (Wed, 09 Jun 2010)
Log Message:
-----------
Move some testscripts around.
* tests/simulate/other/malloc-01.c -> tests/simulate/stdlib/malloc-8.c
* tests/simulate/other/realloc-01.c -> tests/simulate/stdlib/realloc-3.c

Modified Paths:
--------------
    trunk/avr-libc/ChangeLog

Added Paths:
-----------
    trunk/avr-libc/tests/simulate/stdlib/malloc-8.c
    trunk/avr-libc/tests/simulate/stdlib/realloc-3.c

Removed Paths:
-------------
    trunk/avr-libc/tests/simulate/other/malloc-01.c
    trunk/avr-libc/tests/simulate/other/realloc-01.c

Modified: trunk/avr-libc/ChangeLog
===================================================================
--- trunk/avr-libc/ChangeLog    2010-06-09 20:46:25 UTC (rev 2150)
+++ trunk/avr-libc/ChangeLog    2010-06-09 20:49:06 UTC (rev 2151)
@@ -1,5 +1,11 @@
 2010-06-09  Joerg Wunsch <address@hidden>
 
+       Move some testscripts around.
+       * tests/simulate/other/malloc-01.c -> tests/simulate/stdlib/malloc-8.c
+       * tests/simulate/other/realloc-01.c -> tests/simulate/stdlib/realloc-3.c
+
+2010-06-09  Joerg Wunsch <address@hidden>
+
        * libc/stdlib/malloc.c: Fix a bug introduced in r2131 that could
        cause the freelist to be discarded.
 

Deleted: trunk/avr-libc/tests/simulate/other/malloc-01.c
===================================================================
--- trunk/avr-libc/tests/simulate/other/malloc-01.c     2010-06-09 20:46:25 UTC 
(rev 2150)
+++ trunk/avr-libc/tests/simulate/other/malloc-01.c     2010-06-09 20:49:06 UTC 
(rev 2151)
@@ -1,325 +0,0 @@
-/* Copyright (c) 2009 Joerg Wunsch
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-
-   * Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-   * Redistributions in binary form must reproduce the above copyright
-     notice, this list of conditions and the following disclaimer in
-     the documentation and/or other materials provided with the
-     distribution.
-
-   * Neither the name of the copyright holders nor the names of
-     contributors may be used to endorse or promote products derived
-     from this software without specific prior written permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-  POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* $Id$ */
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdint.h>
-
-#ifdef __AVR__
-#include "../../libc/stdlib/stdlib_private.h"
-#endif
-
-/*
- * Basic malloc() test:
- *
- * Two lists are maintained simultaneously, both featuring a different
- * payload size to trigger memory fragmentation issues.  A single
- * linked list is regularly appended to, and deleted from in a
- * semi-random manner.  In parallel, a double linked list is
- * maintained in ascending order of its payload values, gets new nodes
- * inserted, and nodes removed from close to the end.  After a number
- * of runs (500), the random sequence is replayed, and the remaining
- * list entries are removed, again, in the same semi-random order they
- * have been created with.  All successful append/insert and remove
- * operations are accounted.  At the end, the number of all
- * append/insert operations and delete operations must match for each
- * of the lists, and malloc's internal free list is monitored for only
- * consisting of a single large block (representing all the dynamic
- * memory that has been freed up again).
- */
-
-#define N 500
-
-struct list1
-{
-  struct list1 *next;
-  uint16_t payload;
-};
-
-struct list2
-{
-  struct list2 *next, *prev;
-  int32_t payload;
-};
-
-struct list1 *l1head, *l1tail;
-struct list2 *l2head, *l2tail;
-
-bool l1append(uint16_t payload)
-{
-  struct list1 *ele = malloc(sizeof(struct list1));
-  if (ele == NULL)
-    return false;
-  ele->payload = payload;
-  ele->next = NULL;
-  if (l1tail == NULL)
-    {
-      l1head = l1tail = ele;
-      return true;
-    }
-  l1tail->next = ele;
-  l1tail = ele;
-
-  return true;
-}
-
-struct list1 *l1find(uint16_t payload)
-{
-  if (l1head == NULL)
-    return NULL;
-  struct list1 *ele = l1head;
-  while (ele != NULL && ele->payload != payload)
-    ele = ele->next;
-  return ele;
-}
-
-void l1delete(struct list1 *ele)
-{
-  struct list1 *e = l1head;
-  struct list1 *f = NULL;
-
-  if (ele == NULL)
-    return;
-
-  while (e != NULL && e != ele)
-    {
-      f = e;
-      e = e->next;
-    }
-  if (e == NULL)
-    exit(33);
-  if (f == NULL)
-    {
-      /* First element matched, new head. */
-      l1head = e->next;
-      if (l1tail == ele)
-       /* No member left. */
-       l1tail = NULL;
-    }
-  else
-    {
-      f->next = ele->next;
-      if (l1tail == ele)
-       /* New tail. */
-       l1tail = f;
-    }
-  free(ele);
-}
-
-bool l2insert(int32_t payload)
-{
-  struct list2 *ele = malloc(sizeof(struct list2));
-  if (ele == NULL)
-    return false;
-  ele->payload = payload;
-  ele->next = ele->prev = NULL;
-
-  if (l2head == NULL && l2tail == NULL)
-    {
-      l2head = l2tail = ele;
-      return true;
-    }
-
-  struct list2 *p = l2head;
-  while (p != NULL && p->payload < ele->payload)
-    p = p->next;
-
-  if (p == NULL)
-    {
-      /* new tail */
-      l2tail->next = ele;
-      ele->prev = l2tail;
-      l2tail = ele;
-
-      return true;
-    }
-
-  /* insert here */
-  ele->prev = p->prev;
-  ele->next = p;
-
-  if (p->prev != NULL)
-    p->prev->next = ele;
-  else
-    /* new head */
-    l2head = ele;
-  p->prev = ele;
-
-  return true;
-}
-
-void l2delete(struct list2 *ele)
-{
-  struct list2 *p = l2head;
-
-  if (ele == NULL)
-    return;
-
-  while (p != NULL && p != ele)
-    p = p->next;
-
-  if (p == NULL)
-    exit(34);
-
-  if (p->prev != NULL)
-    p->prev->next = p->next;
-  else
-    l2head = p->next;
-
-  if (p->next != NULL)
-    p->next->prev = p->prev;
-  else
-    l2tail = p->prev;
-
-  free(ele);
-}
-
-struct list2 *l2find_3rd_last(void)
-{
-  uint8_t i;
-  struct list2 *ele;
-
-  if (l2tail == NULL)
-    return NULL;
-
-  for (i = 0, ele = l2tail; i < 3; ele = ele->prev)
-    {
-      if (ele->prev == NULL)
-       break;
-    }
-
-  return ele;
-}
-
-#ifdef __AVR__
-void fill_mem(void) __attribute__((section(".init3"),naked));
-void fill_mem(void)
-{
-  extern uint8_t __bss_end;
-  uint8_t *p = &__bss_end;
-  do
-    *p++ = 0xa5;
-  while (p < (uint8_t *)RAMEND);
-}
-#else
-size_t __malloc_margin;
-#endif
-
-uint16_t stats[4];
-
-#define RAND_START_VALUE 4242
-int
-main(void)
-{
-  uint16_t i;
-  int32_t r;
-  uint8_t x;
-  int32_t v;
-
-  __malloc_margin = 32;
-
-  srandom(RAND_START_VALUE);
-  for (i = 0; i < N; i++)
-    {
-      r = random();
-      x = r & 0x0f;
-      v = ((int32_t)x << 28) | ((int32_t)x << 24) |
-      ((int32_t)x << 20) | ((int32_t)x << 16) |
-      ((int32_t)x << 12) | ((int32_t)x << 8) |
-      ((int32_t)x << 4) | (int32_t)x;
-      if (r & 0x10)
-       {
-         if (l1append(v))
-           stats[0]++;
-       }
-      else if (r & 0x20)
-       {
-         struct list1 *p = l1find(v);
-         if (p != NULL)
-           {
-             stats[1]++;
-             l1delete(p);
-           }
-       }
-      if (r & 0x40)
-       {
-         if (l2insert(v))
-           stats[2]++;
-       }
-      else if (r & 0x80)
-       {
-         struct list2 *p = l2find_3rd_last();
-         if (p != NULL)
-           {
-             stats[3]++;
-             l2delete(p);
-           }
-       }
-    }
-  srandom(RAND_START_VALUE);   /* repeat random sequence */
-  while (l1head != NULL || l2head != NULL)
-    {
-      r = random();
-      x = r & 0x0f;
-      v = ((int32_t)x << 28) | ((int32_t)x << 24) |
-      ((int32_t)x << 20) | ((int32_t)x << 16) |
-      ((int32_t)x << 12) | ((int32_t)x << 8) |
-      ((int32_t)x << 4) | (int32_t)x;
-      if (r & 0x10)
-       {
-         struct list1 *p = l1find(v);
-         if (p != NULL)
-           {
-             stats[1]++;
-             l1delete(p);
-           }
-       }
-      else if (r & 0x40)
-       {
-         struct list2 *p = l2find_3rd_last();
-         if (p != NULL)
-           {
-             stats[3]++;
-             l2delete(p);
-           }
-       }
-    }
-  if (stats[0] != stats[1] || stats[2] != stats[3])
-    exit(1);
-#ifdef __AVR__
-  if (__flp != NULL)
-    exit(2);
-#endif
-  return 0;
-}

Deleted: trunk/avr-libc/tests/simulate/other/realloc-01.c
===================================================================
--- trunk/avr-libc/tests/simulate/other/realloc-01.c    2010-06-09 20:46:25 UTC 
(rev 2150)
+++ trunk/avr-libc/tests/simulate/other/realloc-01.c    2010-06-09 20:49:06 UTC 
(rev 2151)
@@ -1,297 +0,0 @@
-/* Copyright (c) 2009 Joerg Wunsch
-   All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-
-   * Redistributions of source code must retain the above copyright
-     notice, this list of conditions and the following disclaimer.
-
-   * Redistributions in binary form must reproduce the above copyright
-     notice, this list of conditions and the following disclaimer in
-     the documentation and/or other materials provided with the
-     distribution.
-
-   * Neither the name of the copyright holders nor the names of
-     contributors may be used to endorse or promote products derived
-     from this software without specific prior written permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-  POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/* $Id$ */
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-
-#ifdef __AVR__
-#include <avr/pgmspace.h>
-#include "../../libc/stdlib/stdlib_private.h"
-#else
-#include "progmem.h"
-# define prog_char     char
-#endif
-
-/*
- * Basic realloc() test:
- *
- * Simulates a serial receiver that semi-randomly "receives"
- * characters from some builtin text strings, and queues them in
- * variable-length records, forming a FIFO.  As the data arrive one
- * byte at a time, realloc() is used to extend the current record to
- * make the data fit.  Another semi-random part pulls data from the
- * FIFO head (again, one char at a time), and deletes the records
- * once they are completely processed.
- * After N (=2000) cycles, no more data are added to the FIFO, and
- * the remaining data are drained.
- * Finally, the number of characters "received" and "sent" is
- * compared, and must match, and the free list pointer is monitored
- * to ensure it only contains a single large block of all dynamic
- * memory that has been freed after use.
- */
-
-struct list1
-{
-  struct list1 *next;
-  bool done;
-  size_t payloadlen;
-  char payload[0];
-};
-
-struct list1 *l1head, *l1tail;
-
-#if defined(__AVR_AT90S8515__)
-#  define N 500
-#else
-#  define N 2000
-#endif
-
-bool l1append(char c)
-{
-  struct list1 *ele = malloc(sizeof(struct list1) + 1);
-  if (ele == NULL)
-    return false;
-  ele->payloadlen = 1;
-  ele->payload[0] = c;
-  ele->next = NULL;
-  ele->done = false;
-  if (l1tail == NULL)
-    {
-      l1head = l1tail = ele;
-      return true;
-    }
-  l1tail->next = ele;
-  l1tail = ele;
-
-  return true;
-}
-
-bool l1extend(char c)
-{
-  if (l1tail == NULL)
-    exit(42);
-  struct list1 *ele = l1tail;
-  struct list1 *p;
-
-  p = realloc(ele, sizeof(struct list1) + ele->payloadlen + 1);
-  if (p == NULL)
-    return false;
-
-  p->payload[p->payloadlen] = c;
-  p->payloadlen++;
-  if (p != ele)
-    {
-      if (ele == l1head)
-       {
-         l1head = p;
-       }
-      else
-       {
-         struct list1 *walk = l1head;
-         while (walk != NULL && walk->next != ele)
-           walk = walk->next;
-         if (walk == NULL)
-           exit(43);
-         walk->next = p;
-       }
-      l1tail = p;
-    }
-
-  return true;
-}
-
-void l1delete(void)
-{
-  if (l1head == NULL)
-    exit(44);
-  struct list1 *p = l1head->next;
-  free(l1head);
-  l1head = p;
-}
-
-#ifdef __AVR__
-void fill_mem(void) __attribute__((section(".init3"),naked));
-void fill_mem(void)
-{
-  extern uint8_t __bss_end;
-  uint8_t *p = &__bss_end;
-  do
-    *p++ = 0xa5;
-  while (p < (uint8_t *)RAMEND);
-}
-#else
-size_t __malloc_margin;
-#endif
-
-#define S(i,s) static prog_char string##i[] = s
-
-S(0, "The ");
-S(1, "quick ");
-S(2, "brown ");
-S(3, "fox ");
-S(4, "jumps ");
-S(5, "over ");
-S(6, "the lazy ");
-S(7, "dog.  ");
-
-static prog_char *strings[8] = {
-  string0, string1, string2, string3, string4, string5, string6, string7
-};
-
-static uint8_t s_idx;
-static prog_char *cur_c;
-
-/*
- * Simulates e.g. a serial receiver.  "Receives" characters from some
- * flash strings.
- */
-char getdata(void)
-{
-  char c;
-
-  if (cur_c == NULL)
-    {
-      cur_c = strings[0];
-      c = pgm_read_byte(cur_c);
-      cur_c++;
-      return c;
-    }
-  c = pgm_read_byte(cur_c);
-  cur_c++;
-  if (c == '\0')
-    {
-      if (++s_idx == 8)
-       s_idx = 0;
-      cur_c = strings[s_idx];
-    }
-  return c;
-}
-
-static char *txp;
-
-/*
- * Simulates e.g. a serial transmitter -- but transmits to /dev/null
- * for simplicity. ;)  It always transmits data from the payload
- * portion of the current list head.
- */
-bool putdata(void)
-{
-  if (l1head == NULL)
-    return false;
-  if (txp == NULL)
-    {
-      if (!l1head->done)
-       return false;
-      txp = l1head->payload;
-    }
-  char devnull = *txp++;       /* /dev/null = devnull; */
-  if (devnull == '\0')
-    {
-      /* end of current record */
-      txp = NULL;
-      l1delete();
-    }
-  return true;
-}
-
-uint16_t stats[2];
-
-#define RAND_START_VALUE 42
-int
-main(void)
-{
-  uint16_t i;
-  long r;
-  bool rx_in_progress = false;
-
-  __malloc_margin = 50;
-
-  srandom(RAND_START_VALUE);
-  for (i = 0; i < N; i++)
-    {
-      r = random();
-      if (r & 0x01)
-       {
-         char c = getdata();
-         if (!rx_in_progress)
-           {
-             /* allocate new tail */
-             if (l1append(c))
-               stats[0]++;
-           }
-         else
-           {
-             if (l1extend(c))
-               stats[0]++;
-           }
-         if (c == '\0')
-           {
-             /* end of record, allocate new one next time */
-             rx_in_progress = false;
-             l1tail->done = true;
-           }
-         else
-           {
-             /* extend current record next time */
-             rx_in_progress = true;
-           }
-       }
-      else if (r & 0x02)
-       {
-         if (putdata())
-           stats[1]++;
-       }
-    }
-  if (rx_in_progress)
-    {
-      /* terminate current record */
-      if (l1extend('\0'))
-       stats[0]++;
-      l1tail->done = true;
-    }
-  srandom(RAND_START_VALUE);   /* repeat random sequence */
-  while (l1head != NULL)
-    {
-      if (putdata())
-       stats[1]++;
-    }
-  if (stats[0] != stats[1])
-    exit(1);
-#ifdef __AVR__
-  if (__flp->nx != NULL)
-    exit(2);
-#endif
-  return 0;
-}

Copied: trunk/avr-libc/tests/simulate/stdlib/malloc-8.c (from rev 2150, 
trunk/avr-libc/tests/simulate/other/malloc-01.c)
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/malloc-8.c                             
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/malloc-8.c     2010-06-09 20:49:06 UTC 
(rev 2151)
@@ -0,0 +1,325 @@
+/* Copyright (c) 2009 Joerg Wunsch
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* $Id$ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdint.h>
+
+#ifdef __AVR__
+#include "../../libc/stdlib/stdlib_private.h"
+#endif
+
+/*
+ * Basic malloc() test:
+ *
+ * Two lists are maintained simultaneously, both featuring a different
+ * payload size to trigger memory fragmentation issues.  A single
+ * linked list is regularly appended to, and deleted from in a
+ * semi-random manner.  In parallel, a double linked list is
+ * maintained in ascending order of its payload values, gets new nodes
+ * inserted, and nodes removed from close to the end.  After a number
+ * of runs (500), the random sequence is replayed, and the remaining
+ * list entries are removed, again, in the same semi-random order they
+ * have been created with.  All successful append/insert and remove
+ * operations are accounted.  At the end, the number of all
+ * append/insert operations and delete operations must match for each
+ * of the lists, and malloc's internal free list is monitored for only
+ * consisting of a single large block (representing all the dynamic
+ * memory that has been freed up again).
+ */
+
+#define N 500
+
+struct list1
+{
+  struct list1 *next;
+  uint16_t payload;
+};
+
+struct list2
+{
+  struct list2 *next, *prev;
+  int32_t payload;
+};
+
+struct list1 *l1head, *l1tail;
+struct list2 *l2head, *l2tail;
+
+bool l1append(uint16_t payload)
+{
+  struct list1 *ele = malloc(sizeof(struct list1));
+  if (ele == NULL)
+    return false;
+  ele->payload = payload;
+  ele->next = NULL;
+  if (l1tail == NULL)
+    {
+      l1head = l1tail = ele;
+      return true;
+    }
+  l1tail->next = ele;
+  l1tail = ele;
+
+  return true;
+}
+
+struct list1 *l1find(uint16_t payload)
+{
+  if (l1head == NULL)
+    return NULL;
+  struct list1 *ele = l1head;
+  while (ele != NULL && ele->payload != payload)
+    ele = ele->next;
+  return ele;
+}
+
+void l1delete(struct list1 *ele)
+{
+  struct list1 *e = l1head;
+  struct list1 *f = NULL;
+
+  if (ele == NULL)
+    return;
+
+  while (e != NULL && e != ele)
+    {
+      f = e;
+      e = e->next;
+    }
+  if (e == NULL)
+    exit(33);
+  if (f == NULL)
+    {
+      /* First element matched, new head. */
+      l1head = e->next;
+      if (l1tail == ele)
+       /* No member left. */
+       l1tail = NULL;
+    }
+  else
+    {
+      f->next = ele->next;
+      if (l1tail == ele)
+       /* New tail. */
+       l1tail = f;
+    }
+  free(ele);
+}
+
+bool l2insert(int32_t payload)
+{
+  struct list2 *ele = malloc(sizeof(struct list2));
+  if (ele == NULL)
+    return false;
+  ele->payload = payload;
+  ele->next = ele->prev = NULL;
+
+  if (l2head == NULL && l2tail == NULL)
+    {
+      l2head = l2tail = ele;
+      return true;
+    }
+
+  struct list2 *p = l2head;
+  while (p != NULL && p->payload < ele->payload)
+    p = p->next;
+
+  if (p == NULL)
+    {
+      /* new tail */
+      l2tail->next = ele;
+      ele->prev = l2tail;
+      l2tail = ele;
+
+      return true;
+    }
+
+  /* insert here */
+  ele->prev = p->prev;
+  ele->next = p;
+
+  if (p->prev != NULL)
+    p->prev->next = ele;
+  else
+    /* new head */
+    l2head = ele;
+  p->prev = ele;
+
+  return true;
+}
+
+void l2delete(struct list2 *ele)
+{
+  struct list2 *p = l2head;
+
+  if (ele == NULL)
+    return;
+
+  while (p != NULL && p != ele)
+    p = p->next;
+
+  if (p == NULL)
+    exit(34);
+
+  if (p->prev != NULL)
+    p->prev->next = p->next;
+  else
+    l2head = p->next;
+
+  if (p->next != NULL)
+    p->next->prev = p->prev;
+  else
+    l2tail = p->prev;
+
+  free(ele);
+}
+
+struct list2 *l2find_3rd_last(void)
+{
+  uint8_t i;
+  struct list2 *ele;
+
+  if (l2tail == NULL)
+    return NULL;
+
+  for (i = 0, ele = l2tail; i < 3; ele = ele->prev)
+    {
+      if (ele->prev == NULL)
+       break;
+    }
+
+  return ele;
+}
+
+#ifdef __AVR__
+void fill_mem(void) __attribute__((section(".init3"),naked));
+void fill_mem(void)
+{
+  extern uint8_t __bss_end;
+  uint8_t *p = &__bss_end;
+  do
+    *p++ = 0xa5;
+  while (p < (uint8_t *)RAMEND);
+}
+#else
+size_t __malloc_margin;
+#endif
+
+uint16_t stats[4];
+
+#define RAND_START_VALUE 4242
+int
+main(void)
+{
+  uint16_t i;
+  int32_t r;
+  uint8_t x;
+  int32_t v;
+
+  __malloc_margin = 32;
+
+  srandom(RAND_START_VALUE);
+  for (i = 0; i < N; i++)
+    {
+      r = random();
+      x = r & 0x0f;
+      v = ((int32_t)x << 28) | ((int32_t)x << 24) |
+      ((int32_t)x << 20) | ((int32_t)x << 16) |
+      ((int32_t)x << 12) | ((int32_t)x << 8) |
+      ((int32_t)x << 4) | (int32_t)x;
+      if (r & 0x10)
+       {
+         if (l1append(v))
+           stats[0]++;
+       }
+      else if (r & 0x20)
+       {
+         struct list1 *p = l1find(v);
+         if (p != NULL)
+           {
+             stats[1]++;
+             l1delete(p);
+           }
+       }
+      if (r & 0x40)
+       {
+         if (l2insert(v))
+           stats[2]++;
+       }
+      else if (r & 0x80)
+       {
+         struct list2 *p = l2find_3rd_last();
+         if (p != NULL)
+           {
+             stats[3]++;
+             l2delete(p);
+           }
+       }
+    }
+  srandom(RAND_START_VALUE);   /* repeat random sequence */
+  while (l1head != NULL || l2head != NULL)
+    {
+      r = random();
+      x = r & 0x0f;
+      v = ((int32_t)x << 28) | ((int32_t)x << 24) |
+      ((int32_t)x << 20) | ((int32_t)x << 16) |
+      ((int32_t)x << 12) | ((int32_t)x << 8) |
+      ((int32_t)x << 4) | (int32_t)x;
+      if (r & 0x10)
+       {
+         struct list1 *p = l1find(v);
+         if (p != NULL)
+           {
+             stats[1]++;
+             l1delete(p);
+           }
+       }
+      else if (r & 0x40)
+       {
+         struct list2 *p = l2find_3rd_last();
+         if (p != NULL)
+           {
+             stats[3]++;
+             l2delete(p);
+           }
+       }
+    }
+  if (stats[0] != stats[1] || stats[2] != stats[3])
+    exit(1);
+#ifdef __AVR__
+  if (__flp != NULL)
+    exit(2);
+#endif
+  return 0;
+}

Copied: trunk/avr-libc/tests/simulate/stdlib/realloc-3.c (from rev 2148, 
trunk/avr-libc/tests/simulate/other/realloc-01.c)
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/realloc-3.c                            
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/realloc-3.c    2010-06-09 20:49:06 UTC 
(rev 2151)
@@ -0,0 +1,297 @@
+/* Copyright (c) 2009 Joerg Wunsch
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* $Id$ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifdef __AVR__
+#include <avr/pgmspace.h>
+#include "../../libc/stdlib/stdlib_private.h"
+#else
+#include "progmem.h"
+# define prog_char     char
+#endif
+
+/*
+ * Basic realloc() test:
+ *
+ * Simulates a serial receiver that semi-randomly "receives"
+ * characters from some builtin text strings, and queues them in
+ * variable-length records, forming a FIFO.  As the data arrive one
+ * byte at a time, realloc() is used to extend the current record to
+ * make the data fit.  Another semi-random part pulls data from the
+ * FIFO head (again, one char at a time), and deletes the records
+ * once they are completely processed.
+ * After N (=2000) cycles, no more data are added to the FIFO, and
+ * the remaining data are drained.
+ * Finally, the number of characters "received" and "sent" is
+ * compared, and must match, and the free list pointer is monitored
+ * to ensure it only contains a single large block of all dynamic
+ * memory that has been freed after use.
+ */
+
+struct list1
+{
+  struct list1 *next;
+  bool done;
+  size_t payloadlen;
+  char payload[0];
+};
+
+struct list1 *l1head, *l1tail;
+
+#if defined(__AVR_AT90S8515__)
+#  define N 500
+#else
+#  define N 2000
+#endif
+
+bool l1append(char c)
+{
+  struct list1 *ele = malloc(sizeof(struct list1) + 1);
+  if (ele == NULL)
+    return false;
+  ele->payloadlen = 1;
+  ele->payload[0] = c;
+  ele->next = NULL;
+  ele->done = false;
+  if (l1tail == NULL)
+    {
+      l1head = l1tail = ele;
+      return true;
+    }
+  l1tail->next = ele;
+  l1tail = ele;
+
+  return true;
+}
+
+bool l1extend(char c)
+{
+  if (l1tail == NULL)
+    exit(42);
+  struct list1 *ele = l1tail;
+  struct list1 *p;
+
+  p = realloc(ele, sizeof(struct list1) + ele->payloadlen + 1);
+  if (p == NULL)
+    return false;
+
+  p->payload[p->payloadlen] = c;
+  p->payloadlen++;
+  if (p != ele)
+    {
+      if (ele == l1head)
+       {
+         l1head = p;
+       }
+      else
+       {
+         struct list1 *walk = l1head;
+         while (walk != NULL && walk->next != ele)
+           walk = walk->next;
+         if (walk == NULL)
+           exit(43);
+         walk->next = p;
+       }
+      l1tail = p;
+    }
+
+  return true;
+}
+
+void l1delete(void)
+{
+  if (l1head == NULL)
+    exit(44);
+  struct list1 *p = l1head->next;
+  free(l1head);
+  l1head = p;
+}
+
+#ifdef __AVR__
+void fill_mem(void) __attribute__((section(".init3"),naked));
+void fill_mem(void)
+{
+  extern uint8_t __bss_end;
+  uint8_t *p = &__bss_end;
+  do
+    *p++ = 0xa5;
+  while (p < (uint8_t *)RAMEND);
+}
+#else
+size_t __malloc_margin;
+#endif
+
+#define S(i,s) static prog_char string##i[] = s
+
+S(0, "The ");
+S(1, "quick ");
+S(2, "brown ");
+S(3, "fox ");
+S(4, "jumps ");
+S(5, "over ");
+S(6, "the lazy ");
+S(7, "dog.  ");
+
+static prog_char *strings[8] = {
+  string0, string1, string2, string3, string4, string5, string6, string7
+};
+
+static uint8_t s_idx;
+static prog_char *cur_c;
+
+/*
+ * Simulates e.g. a serial receiver.  "Receives" characters from some
+ * flash strings.
+ */
+char getdata(void)
+{
+  char c;
+
+  if (cur_c == NULL)
+    {
+      cur_c = strings[0];
+      c = pgm_read_byte(cur_c);
+      cur_c++;
+      return c;
+    }
+  c = pgm_read_byte(cur_c);
+  cur_c++;
+  if (c == '\0')
+    {
+      if (++s_idx == 8)
+       s_idx = 0;
+      cur_c = strings[s_idx];
+    }
+  return c;
+}
+
+static char *txp;
+
+/*
+ * Simulates e.g. a serial transmitter -- but transmits to /dev/null
+ * for simplicity. ;)  It always transmits data from the payload
+ * portion of the current list head.
+ */
+bool putdata(void)
+{
+  if (l1head == NULL)
+    return false;
+  if (txp == NULL)
+    {
+      if (!l1head->done)
+       return false;
+      txp = l1head->payload;
+    }
+  char devnull = *txp++;       /* /dev/null = devnull; */
+  if (devnull == '\0')
+    {
+      /* end of current record */
+      txp = NULL;
+      l1delete();
+    }
+  return true;
+}
+
+uint16_t stats[2];
+
+#define RAND_START_VALUE 42
+int
+main(void)
+{
+  uint16_t i;
+  long r;
+  bool rx_in_progress = false;
+
+  __malloc_margin = 50;
+
+  srandom(RAND_START_VALUE);
+  for (i = 0; i < N; i++)
+    {
+      r = random();
+      if (r & 0x01)
+       {
+         char c = getdata();
+         if (!rx_in_progress)
+           {
+             /* allocate new tail */
+             if (l1append(c))
+               stats[0]++;
+           }
+         else
+           {
+             if (l1extend(c))
+               stats[0]++;
+           }
+         if (c == '\0')
+           {
+             /* end of record, allocate new one next time */
+             rx_in_progress = false;
+             l1tail->done = true;
+           }
+         else
+           {
+             /* extend current record next time */
+             rx_in_progress = true;
+           }
+       }
+      else if (r & 0x02)
+       {
+         if (putdata())
+           stats[1]++;
+       }
+    }
+  if (rx_in_progress)
+    {
+      /* terminate current record */
+      if (l1extend('\0'))
+       stats[0]++;
+      l1tail->done = true;
+    }
+  srandom(RAND_START_VALUE);   /* repeat random sequence */
+  while (l1head != NULL)
+    {
+      if (putdata())
+       stats[1]++;
+    }
+  if (stats[0] != stats[1])
+    exit(1);
+#ifdef __AVR__
+  if (__flp->nx != NULL)
+    exit(2);
+#endif
+  return 0;
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]