/* 
LIST.C
usage: list [nodesize]
allocates and frees a lot of memory; uses linked list; 
    can specify node size

real mode:
    C:\>cl /AL list.c 
    C:\>list

protected mode:
    C:\>cl386 /c list.c
    C:\>386link list @msc386
    C:\>list
*/

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <time.h>

typedef struct node {
    unsigned long num;
    void *data;
    struct node *next;
    } NODE;
    
main(int argc, char *argv[])
{
    NODE *p, *q;
    time_t t1, t2, t3;
    unsigned long nodes, freed;
    unsigned nodesize = (argc > 1) ? atoi(argv[1]) : 512;
    
    time(&t1);
    
    for (q = NULL, nodes = 0; ; q->next = p)
    {
	p = q;
        if ((q = malloc(sizeof(NODE))) == NULL)
            break;
        if ((q->data = malloc(nodesize)) == NULL)
        {
            free(q);
            break;
        }
        q->num = nodes++;
	printf(".");
    }
        
    time(&t2);

    for (freed = nodes; p != NULL; p = q)
    {
	q = p->next;
        if (p->num != --freed)
	{
            printf("list corrupt: freed=%lu num=%lu\n", 
                freed, p->num);
	    return 1;
	}
        free(p->data);
        free(p);
    }
    if (freed != 0)
    {
        printf("list corrupt: allocated %lu blocks, freed %lu blocks\n",
		nodes, nodes - freed);
        return 1;
    }

    time(&t3);
    printf("\nAllocated %lu nodes, %uK\n",
        nodes, (nodes * (sizeof(NODE)+nodesize)) >> 10);
    printf("Total time: %lu seconds\n", t3 - t1);
    printf("Allocate time: %lu, freeing time: %lu\n",
    	t2 - t1, t3 - t2);

    return 0;
}

