/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/***********************************************************************
* *
* * Name : dbmalloc . c
* *
* * Description : Testing malloc ( OBSOLETE )
* *
* * Modification History :
* * 14 - May - 97 AGarcia - Converted the test to accomodate the debug_mode flag .
* * The debug mode will print all of the printfs associated with this
* test .
* * The regress mode will be the default mode . Since the regress tool
* limits
* * the output to a one line status : PASS or FAIL , all of the printf
* statements
* * have been handled with an if ( debug_mode ) statement .
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "nspr.h"
void usage(
void ) {
fprintf(stderr,
"Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename "
"[...]\n" );
exit(
0 );
}
typedef struct node_struct {
struct node_struct *next, *prev;
int line;
char value[
4 ];
} node_t, *node_pt;
node_pt get_node(
const char* line) {
node_pt rv;
int l = strlen(line);
rv = (node_pt)PR_MALLOC(
sizeof (node_t) + l +
1 -
4 );
if ((node_pt)
0 == rv) {
return (node_pt)
0 ;
}
memcpy(&rv->value[
0 ], line, l +
1 );
rv->next = rv->prev = (node_pt)
0 ;
return rv;
}
void dump(
const char* name, node_pt node, int mf, int debug) {
if ((node_pt)
0 != node->prev) {
dump(name, node->prev, mf, debug);
}
if (
0 != debug) {
printf(
"[%s]: %6d: %s" , name, node->line, node->value);
}
if (node->line == mf) {
fprintf(stderr,
"[%s]: Line %d was allocated!\n" , name, node->line);
}
if ((node_pt)
0 != node->next) {
dump(name, node->next, mf, debug);
}
return ;
}
void release(node_pt node) {
if ((node_pt)
0 != node->prev) {
release(node->prev);
}
if ((node_pt)
0 != node->next) {
release(node->next);
}
PR_DELETE(node);
}
int t2(
const char* name, int mf, int debug) {
int rv;
FILE* fp;
int l =
0 ;
node_pt head = (node_pt)
0 ;
char buffer[BUFSIZ];
fp = fopen(name,
"r" );
if ((FILE*)
0 == fp) {
fprintf(stderr,
"[%s]: Cannot open \" %s.\
"\n" , name, name);
return -
1 ;
}
/* fgets mallocs a buffer, first time through. */
if ((char*)
0 == fgets(buffer, BUFSIZ, fp)) {
fprintf(stderr,
"[%s]: \" %s\
" is empty.\n" , name, name);
(
void )fclose(fp);
return -
1 ;
}
rewind(fp);
if (PR_SUCCESS != PR_ClearMallocCount()) {
fprintf(stderr,
"[%s]: Cannot clear malloc count.\n" , name);
(
void )fclose(fp);
return -
1 ;
}
if (PR_SUCCESS != PR_SetMallocCountdown(mf)) {
fprintf(stderr,
"[%s]: Cannot set malloc countdown to %d\n" , name, mf);
(
void )fclose(fp);
return -
1 ;
}
while (fgets(buffer, BUFSIZ, fp)) {
node_pt n;
node_pt* w = &head;
if ((strlen(buffer) == (BUFSIZ -
1 )) && (buffer[BUFSIZ -
2 ] !=
'\n' )) {
buffer[BUFSIZ -
2 ] ==
'\n' ;
}
l++;
n = get_node(buffer);
if ((node_pt)
0 == n) {
printf(
"[%s]: Line %d: malloc failure!\n" , name, l);
continue ;
}
n->line = l;
while (
1 ) {
int comp;
if ((node_pt)
0 == *w) {
*w = n;
break ;
}
comp = strcmp((*w)->value, n->value);
if (comp <
0 ) {
w = &(*w)->next;
}
else {
w = &(*w)->prev;
}
}
}
(
void )fclose(fp);
dump(name, head, mf, debug);
rv = PR_GetMallocCount();
PR_ClearMallocCountdown();
release(head);
return rv;
}
int nf =
0 ;
int debug =
0 ;
void test(
const char* name) {
int n, i;
extern int nf, debug;
printf(
"[%s]: starting test 0\n" , name);
n = t2(name,
0 , debug);
if (-
1 == n) {
return ;
}
printf(
"[%s]: test 0 had %ld allocations.\n" , name, n);
if (
0 >= n) {
return ;
}
for (i =
0 ; i < nf; i++) {
int which = rand() % n;
if (
0 == which) {
printf(
"[%s]: starting test %d -- no allocation should fail\n" , name,
i +
1 );
}
else {
printf(
"[%s]: starting test %d -- allocation %d should fail\n" , name,
i +
1 , which);
}
(
void )t2(name, which, debug);
printf(
"[%s]: test %d done.\n" , name, i +
1 );
}
return ;
}
int main(int argc, char** argv) {
int okay =
0 ;
int multithread =
0 ;
struct threadlist {
struct threadlist* next;
PRThread* thread;
}* threadhead = (
struct threadlist*)
0 ;
extern int nf, debug;
srand(time(
0 ));
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL,
0 );
printf(
"[main]: We %s using the debugging malloc.\n" ,
PR_IsDebuggingMalloc() ?
"ARE" :
"ARE NOT" );
while (argv++, --argc) {
if (
'-' == argv[
0 ][
0 ]) {
switch (argv[
0 ][
1 ]) {
case 'f' :
nf = atoi(argv[
0 ][
2 ] ? &argv[
0 ][
2 ] : --argc ? *++argv :
"0" );
break ;
case 'd' :
debug =
1 ;
break ;
case 'n' :
debug =
0 ;
break ;
case 'm' :
multithread =
1 ;
break ;
case 's' :
multithread =
0 ;
break ;
default :
usage();
break ;
}
}
else {
FILE* fp = fopen(*argv,
"r" );
if ((FILE*)
0 == fp) {
fprintf(stderr,
"Cannot open \" %s.\
"\n" , *argv);
continue ;
}
okay++;
(
void )fclose(fp);
if (multithread) {
struct threadlist* n;
n = (
struct threadlist*)malloc(
sizeof (
struct threadlist));
if ((
struct threadlist*)
0 == n) {
fprintf(stderr,
"This is getting tedious. \" %s\
"\n" , *argv);
continue ;
}
n->next = threadhead;
n->thread = PR_CreateThread(PR_USER_THREAD, (
void (*)(
void *))test,
*argv, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
PR_JOINABLE_THREAD,
0 );
if ((PRThread*)
0 == n->thread) {
fprintf(stderr,
"Can't create thread for \" %s.\
"\n" , *argv);
continue ;
}
else {
threadhead = n;
}
}
else {
test(*argv);
}
}
}
if (okay ==
0 ) {
usage();
}
else
while ((
struct threadlist*)
0 != threadhead) {
struct threadlist* x = threadhead->next;
(
void )PR_JoinThread(threadhead->thread);
PR_DELETE(threadhead);
threadhead = x;
}
return 0 ;
}
Messung V0.5 in Prozent C=96 H=95 G=95
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland