[Top][All Lists]
[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;
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [avr-libc-commit] [2151] Move some testscripts around.,
Joerg Wunsch <=