home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / tests / dbmalloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  8.1 KB  |  329 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. /***********************************************************************
  20. **
  21. ** Name: dbmalloc.c
  22. **
  23. ** Description: Testing malloc (OBSOLETE)
  24. **
  25. ** Modification History:
  26. ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
  27. **             The debug mode will print all of the printfs associated with this test.
  28. **             The regress mode will be the default mode. Since the regress tool limits
  29. **           the output to a one line status:PASS or FAIL,all of the printf statements
  30. **             have been handled with an if (debug_mode) statement. 
  31. ***********************************************************************/
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <time.h>
  35. #include <string.h>
  36. #include "nspr.h"
  37.  
  38. void
  39. usage
  40. (
  41.     void
  42. )
  43. {
  44.     fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n");
  45.     exit(0);
  46. }
  47.  
  48. typedef struct node_struct
  49. {
  50.     struct node_struct *next, *prev;
  51.     int line;
  52.     char value[4];
  53. }
  54.     node_t,
  55.    *node_pt;
  56.  
  57. node_pt get_node(const char *line)
  58. {
  59.     node_pt rv;
  60.     int l = strlen(line);
  61.     rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4);
  62.     if( (node_pt)0 == rv ) return (node_pt)0;
  63.     memcpy(&rv->value[0], line, l+1);
  64.     rv->next = rv->prev = (node_pt)0;
  65.     return rv;
  66. }
  67.  
  68. void
  69. dump
  70. (
  71.     const char *name,
  72.     node_pt     node,
  73.     int         mf,
  74.     int         debug
  75. )
  76. {
  77.     if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug);
  78.     if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value);
  79.     if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line);
  80.     if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug);
  81.     return;
  82. }
  83.  
  84. void
  85. release
  86. (
  87.     node_pt node
  88. )
  89. {
  90.     if( (node_pt)0 != node->prev ) release(node->prev);
  91.     if( (node_pt)0 != node->next ) release(node->next);
  92.     PR_DELETE(node);
  93. }
  94.  
  95. int
  96. t2
  97. (
  98.     const char *name,
  99.     int         mf,
  100.     int         debug
  101. )
  102. {
  103.     int rv;
  104.     FILE *fp;
  105.     int l = 0;
  106.     node_pt head = (node_pt)0;
  107.     char buffer[ BUFSIZ ];
  108.  
  109.     fp = fopen(name, "r");
  110.     if( (FILE *)0 == fp )
  111.     {
  112.         fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name);
  113.         return -1;
  114.     }
  115.  
  116.     /* fgets mallocs a buffer, first time through. */
  117.     if( (char *)0 == fgets(buffer, BUFSIZ, fp) )
  118.     {
  119.         fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name);
  120.         (void)fclose(fp);
  121.         return -1;
  122.     }
  123.  
  124.     rewind(fp);
  125.  
  126.     if( PR_SUCCESS != PR_ClearMallocCount() )
  127.     {
  128.         fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name);
  129.         (void)fclose(fp);
  130.         return -1;
  131.     }
  132.  
  133.     if( PR_SUCCESS != PR_SetMallocCountdown(mf) )
  134.     {
  135.         fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf);
  136.         (void)fclose(fp);
  137.         return -1;
  138.     }
  139.  
  140.     while( fgets(buffer, BUFSIZ, fp) )
  141.     {
  142.         node_pt n;
  143.         node_pt *w = &head;
  144.  
  145.         if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') )
  146.             buffer[BUFSIZ-2] == '\n';
  147.  
  148.         l++;
  149.  
  150.         n = get_node(buffer);
  151.         if( (node_pt)0 == n ) 
  152.         {
  153.             printf("[%s]: Line %d: malloc failure!\n", name, l);
  154.             continue;
  155.         }
  156.  
  157.         n->line = l;
  158.  
  159.         while( 1 )
  160.         {
  161.             int comp;
  162.  
  163.             if( (node_pt)0 == *w )
  164.             {
  165.                 *w = n;
  166.                 break;
  167.             }
  168.  
  169.             comp = strcmp((*w)->value, n->value);
  170.             if( comp < 0 ) w = &(*w)->next;
  171.             else w = &(*w)->prev;
  172.         }
  173.     }
  174.  
  175.     (void)fclose(fp);
  176.  
  177.     dump(name, head, mf, debug);
  178.  
  179.     rv = PR_GetMallocCount();
  180.     PR_ClearMallocCountdown();
  181.  
  182.     release(head);
  183.  
  184.     return rv;
  185. }
  186.  
  187. int nf = 0;
  188. int debug = 0;
  189.  
  190. void
  191. test
  192. (
  193.     const char *name
  194. )
  195. {
  196.     int n, i;
  197.  
  198.     extern int nf, debug;
  199.  
  200.     printf("[%s]: starting test 0\n", name);
  201.     n = t2(name, 0, debug);
  202.     if( -1 == n ) return;
  203.     printf("[%s]: test 0 had %ld allocations.\n", name, n);
  204.  
  205.     if( 0 >= n ) return;
  206.  
  207.     for( i = 0; i < nf; i++ )
  208.     {
  209.         int which = rand() % n;
  210.         if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1);
  211.         else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which);
  212.         (void)t2(name, which, debug);
  213.         printf("[%s]: test %d done.\n", name, i+1);
  214.     }
  215.  
  216.     return;
  217. }
  218.  
  219. int
  220. main
  221. (
  222.     int     argc,
  223.     char   *argv[]
  224. )
  225. {
  226.     int okay = 0;
  227.     int multithread = 0;
  228.  
  229.     struct threadlist
  230.     {
  231.         struct threadlist *next;
  232.         PRThread *thread;
  233.     }
  234.         *threadhead = (struct threadlist *)0;
  235.  
  236.     extern int nf, debug;
  237.  
  238.     srand(time(0));
  239.  
  240.     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  241.     PR_STDIO_INIT();
  242.  
  243.     printf("[main]: We %s using the debugging malloc.\n",
  244.            PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT");
  245.  
  246.     while( argv++, --argc )
  247.     {
  248.         if( '-' == argv[0][0] )
  249.         {
  250.             switch( argv[0][1] )
  251.             {
  252.                 case 'f':
  253.                     nf = atoi(argv[0][2] ? &argv[0][2] :
  254.                               --argc ? *++argv : "0");
  255.                     break;
  256.                 case 'd':
  257.                     debug = 1;
  258.                     break;
  259.                 case 'n':
  260.                     debug = 0;
  261.                     break;
  262.                 case 'm':
  263.                     multithread = 1;
  264.                     break;
  265.                 case 's':
  266.                     multithread = 0;
  267.                     break;
  268.                 default:
  269.                     usage();
  270.                     break;
  271.             }
  272.         }
  273.         else
  274.         {
  275.             FILE *fp = fopen(*argv, "r");
  276.             if( (FILE *)0 == fp )
  277.             {
  278.                 fprintf(stderr, "Cannot open \"%s.\"\n", *argv);
  279.                 continue;
  280.             }
  281.  
  282.             okay++;
  283.             (void)fclose(fp);
  284.             if( multithread )
  285.             {
  286.                 struct threadlist *n;
  287.  
  288.                 n = (struct threadlist *)malloc(sizeof(struct threadlist));
  289.                 if( (struct threadlist *)0 == n ) 
  290.                 {
  291.                     fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv);
  292.                     continue;
  293.                 }
  294.  
  295.                 n->next = threadhead;
  296.                 n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, 
  297.                                             *argv, PR_PRIORITY_NORMAL, 
  298.                                             PR_LOCAL_THREAD, PR_JOINABLE_THREAD,
  299.                                             0);
  300.                 if( (PRThread *)0 == n->thread )
  301.                 {
  302.                     fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv);
  303.                     continue;
  304.                 }
  305.                 else
  306.                 {
  307.                     threadhead = n;
  308.                 }
  309.             }
  310.             else
  311.             {
  312.                 test(*argv);
  313.             }
  314.         }
  315.     }
  316.  
  317.     if( okay == 0 ) usage();
  318.     else while( (struct threadlist *)0 != threadhead )
  319.     {
  320.         struct threadlist *x = threadhead->next;
  321.         (void)PR_JoinThread(threadhead->thread);
  322.         PR_DELETE(threadhead);
  323.         threadhead = x;
  324.     }
  325.  
  326.     return 0;
  327. }
  328.  
  329.