/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1999-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#include "dttest.h"
#include <vmalloc.h>
/* Test insert/delete/search in shared/persistent memory region. */
#ifndef N_PROC
#endif
#if N_PROC < 8
#endif
/* a persistent object is a pair of string and decimal number */
typedef struct obj_s
/* below are extra data good to help debugging */
} Obj_t;
/* Cdt discipline to allocate memory from a vmalloc region */
typedef struct _mmdisc_s
int pid;
} Mmdisc_t;
/* allocate data from the shared memory region */
{
}
/* handle dictionary events */
{
if(data) /* at the start of a dictionary opening */
{ if(!ctrl) /* data area not yet constructed */
return 0;
else /* got data area, just return it */
return 1;
}
}
else return 0;
}
if(!ctrl) /* data area just constructed, record it */
}
else return 0; /* data area existed */
}
return 1; /* make sure no objects get deleted */
return 0; /* all done */
}
else if(type & DT_ANNOUNCE)
terror("Process %d: refn != LONGGONE op=%d obj[%d,refn=%d,fpid=%d]",
tpause("Process %d: Op=%d != DT_DELETE obj[%d,refn=%d,fpid=%d]",
}
{ /* Wait-loop for object completion. The below "if"
** statement causes the loop to be executed in all
** cases except for the dtinsert()/dtattach() that
** will complete constructing the object.
*/
asorelax(1);
/* increase reference count */
tpause("Process %d: refn<0 on adding op=%d obj[%d,refn=%d,fpid=%d]",
}
return 0;
}
else return 0;
}
/* compare two objects by their integer keys */
{
}
/* free a deleted object */
{
int refn;
terror("Process %d: multiple deletion? obj[%d,sval=%s,free=%d,pid=%d,refn=%d]",
asorelax(1);
asorelax(1);
/* set reference number to LONGGONE */
terror("Process %d: refn=%d > 0? obj[%d,sval=%s,free=%d,pid=%d,refn=%d,op=%d]",
}
/* open a shared dictionary based on a common backing store */
{
/* discipline for objects identified by their decimal values */
return dt;
}
{
int i;
else if(pid > 0 ) /* return to parent process */
return pid;
else
i = 0;
if (aso)
argv[i++] = "--child";
argv[i++] = 0;
}
return -1;
}
{
char *sval;
/* open the shared/persistent dictionary */
/* get the discipline structure with the Vmalloc region */
/* all writers wait until they are all ready before going */
}
else /* searchers wait for everyone to be ready before going */
}
}
tinfo("%s %s [num=%d,pid=%d]: range=[%d,%d) ready to go", actor, type, num, pid, base, base+W_EXTENT);
for(i = 0; i < W_EXTENT; ++i)
{ /* insert a new object */
if(rv == o) /* successfully inserted, complete it by making string value */
{ insert += 1;
if(o->dval < 0) /* this ain't no way! */
terror("%s %s [num=%d,pid=%d]: already freed? obj[dval=%d,pid=%d]",
terror("%s %s [num=%d,pid=%d]: refn != 1? obj[dval=%d,refn=%d,op=%d,opid=%d]",
}
else
terror("%s %s [num=%d,pid=%d]: refn <= 0? obj[dval=%d,refn=%d,op=%d,opid=%d]",
}
}
tinfo("%s %s [num=%d,pid=%d]: done, base=%d try=%d insert=%d[+%d]",
/* total number of successful inserts */
}
walk += 1;
if(o->refn <= 0 ) /* refn should be >= 1 */
terror("%s %s [num=%d,pid=%d]: refn <= 0? obj[dval=%d,refn=%d,op=%d,opid=%d]",
if(!o->sval) /* count incomplete objects */
else delete += 1;
}
tinfo("%s %s [num=%d,pid=%d]: done, size=%d[walk=%d] delete=%d[+%d]",
size = 0; /* make sure that free elements were deleted right */
size += 1;
terror("%s %s [num=%d,pid=%d]: multiple delete? obj[dval=%d,free=%d,fpid=%d]",
terror("%s %s [num=%d,pid=%d]: Wrong deleter obj[dval=%d,free=%d,fpid=%d]",
}
/* save the number of deleted objects */
}
{ for(k = 0; k < size; ++k)
unsrch += 1;
else
{ search += 1;
terror("%s %s [num=%d,pid=%d]: already freed? obj[%d,fpid=%d]",
terror("%s %s [num=%d,pid=%d]: refn <= 0? obj[%d,refn=%d,op=%d,opid=%d]",
}
}
tinfo("%s %s [num=%d,pid=%d]: done, dtsize=%d search=%d[+%d]",
}
else /* this searcher walks the dictionary */
for(k = 0; k < size; ++k)
walk += 1;
first += 1;
else break; /* empty dictionary */
if(o->dval < 0) /* should not be deleted yet */
terror("%s %s [num=%d,pid=%d]: already freed obj[%d,refn=%d,fpid=%d,op=%d,opid=%d ",
if(o->refn <= 0 ) /* refn must be >= 1 */
terror("%s %s [num=%d,pid=%d]: refn<=0? obj[%d,refn=%d,op=%d,opid=%d",
if(!o->sval) /* count incomplete objects */
}
tinfo("%s %s [num=%d,pid=%d]: done, dtsize=%d walk=%d first=%d",
}
}
walk += 1;
/* concurrently walk the dictionary and add count to appropriate fields */
{ if(o->dval < 0)
terror("%s %s [num=%d,pid=%d]: object %d already freed",
if(i == 1) /* inserter */
#ifdef DEBUG
#endif
}
else if(i == 2) /* deleter */
#ifdef DEBUG
#endif
}
else
#ifdef DEBUG
#endif
}
}
/* close dictionary and shared/persistent region */
return 0;
}
tmain()
{
int t;
Obj_t *o;
if(k = tchild())
else
a = argv[k++];
if(strcmp(a, "inserter") == 0 ||
strcmp(a, "deleter") == 0 ||
strcmp(a, "searcher") == 0 )
terror("%s: invalid child process operation -- { inserter deleter searcher } expected", a);
}
else if(*++argv)
t = -1;
else
t = 0;
terror("Parent: can't get process id");
for(; t < 2; t++)
{ switch (t)
{
case -1:
else
break;
case 0:
type = "map";
#if __sun
continue;
#else
break;
#endif
case 1:
type = "shm";
break;
}
gettimeofday(&begtm, 0);
for(p = i = 0; i < N_INSERT; ++i) /* start inserters */
for(i = 0; i < N_DELETE; ++i) /* start deleters */
for(i = 0; i < N_SEARCH; ++i) /* start searchers */
terror("workload subprocess error");
walk = 0; /* count objects from "persistent" dictionary itself */
terror("parent %s [pid=%d]: object %d has wrong insert count %d",
terror("parent %s [pid=%d]: object %d has wrong search count %d",
terror("parent %s [pid=%d]: object %d has wrong delete count %d",
#ifdef DEBUG
#endif
walk += 1;
}
tinfo("Storage type=%s, #insertions=%d #inserters=%d #deleters=%d #searchers=%d",
gettimeofday(&endtm, 0);
}
tinfo("Storage method %s: running time = %ld.%lds",
}
texit(0);
}