Exemple #1
0
unsigned pa_aupdate_write_begin(pa_aupdate *a) {
    unsigned n;

    pa_assert(a);

    pa_mutex_lock(a->write_lock);

    n = (unsigned) pa_atomic_load(&a->read_lock);

    a->swapped = false;

    return !WHICH(n);
}
Exemple #2
0
unsigned pa_aupdate_read_begin(pa_aupdate *a) {
    unsigned n;

    pa_assert(a);

    /* Increase the lock counter */
    n = (unsigned) pa_atomic_inc(&a->read_lock);

    /* When n is 0 we have about 2^31 threads running that all try to
     * access the data at the same time, oh my! */
    pa_assert(COUNTER(n)+1 > 0);

    /* The uppermost bit tells us which data to look at */
    return WHICH(n);
}
Exemple #3
0
unsigned pa_aupdate_write_swap(pa_aupdate *a) {
    unsigned n;

    pa_assert(a);

    for (;;) {
        n = (unsigned) pa_atomic_load(&a->read_lock);

        /* If the read counter is > 0 wait; if it is 0 try to swap the lists */
        if (COUNTER(n) > 0)
            pa_semaphore_wait(a->semaphore);
        else if (pa_atomic_cmpxchg(&a->read_lock, (int) n, (int) (n ^ MSB)))
            break;
    }

    a->swapped = true;

    return WHICH(n);
}
Exemple #4
0
void check_topology(int Tflag, int argc, char **argv)
{
    extern int	application_bounds(int *minmsg, int *maxmsg);
    extern int	check_ethernets(BOOL **adj);

    CnetAddr	a;
    NODEATTR	*na;
    int		n, p, nrouters;
    int		x, y, rootn;
    int		appl_minmsg, appl_maxmsg;

    LINK	*lp;
    BOOL	**adj;

    for(n=0, nrouters=0 ; n<_NNODES ; n++) {
	extern char	*random_osname(int randint);

/*  ASSIGN A RANDOM OPERATING SYSTEM TYPE IF NECESSARY */
	if(NP[n].nodetype == NT_ROUTER)
	    ++nrouters;
	else if(NP[n].nattr.osname == (char *)NULL)
	    NP[n].nattr.osname = random_osname((int)nrand48(xsubi));
    }
    n = _NNODES - nrouters;
    if(dflag)
	fprintf(stderr,"%d host%s, %d router%s and %d link%s\n",
				    P(n), P(nrouters), P(_NLINKS) );

/*  ENSURE THAT WE HAVE AT LEAST 2 HOSTS (APPLICATION LAYERS) */
    if(n < 2) {
	fputs("A network must have >= 2 hosts\n",stderr);
	++nerrors;
    }

    application_bounds(&appl_minmsg, &appl_maxmsg);
    for(n=0 ; n<(_NNODES-1) ; n++) {
	int	my_minmsg;
	int	my_maxmsg;

/*  NEXT, CHECK FOR DUPLICATE USER-SPECIFIED NODE ADDRESSES */
	na	= &NP[n].nattr;
	a	= na->address;
	for(p=n+1 ; p<_NNODES ; p++)
	    if(a == NP[p].nattr.address) {
		fprintf(stderr, "%s and %s have the same node address (%u)\n",
				NP[n].nodename, NP[p].nodename, a);
		++nerrors;
	    }

/*  CHECK THAT USER-REQUESTED MESSAGE SIZES ARE NEITHER TOO BIG NOR TOO SMALL */
	my_minmsg	= WHICH(na->minmessagesize, DEFAULTNODE.minmessagesize);
	my_maxmsg	= WHICH(na->maxmessagesize, DEFAULTNODE.maxmessagesize);

	if(my_minmsg < appl_minmsg) {
	    fprintf(stderr,
	    "%s has minmessagesize(=%d) < application layer requirements(=%d)\n",
			    NP[n].nodename, my_minmsg, appl_minmsg);
	    ++nerrors;
	}
	if(my_maxmsg > appl_maxmsg) {
	    fprintf(stderr,
	    "%s has maxmessagesize(=%d) > application layer requirements(=%d)\n",
			    NP[n].nodename, my_maxmsg, appl_maxmsg);
	    ++nerrors;
	}
	if(my_minmsg > my_maxmsg) {
	    fprintf(stderr,"%s has minmessagesize(=%d) > maxmessagesize(=%d)\n",
			    NP[n].nodename, my_minmsg, my_maxmsg);
	    ++nerrors;
	}
    }

/*  ALLOCATE AND INITIALIZE THE ADJACENCY MATIRX (CHECK FOR ETHERNETS TOO) */
    adj		= (BOOL **)malloc(_NNODES * sizeof(BOOL *));
    for(n=0 ; n<_NNODES ; ++n) {
	adj[n]	= (BOOL *)malloc(_NNODES * sizeof(BOOL));
	memset(adj[n], 0, _NNODES * sizeof(BOOL));
    }

    check_ethernets(adj);

/*  IF ANY SIGNIFICANT ERRORS OCCURED, TERMINATE THE PROGRAM */
    if(nerrors)
	cleanup(1);

    rootn	= (int)sqrt((double)(_NNODES-1)) + 1;
    for(n=0 ; n < _NNODES ; n++) {
	na	= &NP[n].nattr;
	x	= n%rootn;
	y	= n/rootn;

/*  GIVE SOME DEFAULT X,Y COORDINATES IF THEY HAVE NOT BEEN SPECIFIED */
	if(na->x == 0)
	    na->x		= (2*x+1) * DEF_NODE_X;
	if(na->y == 0)
	    na->y		= (2*y+1) * DEF_NODE_Y;
	if(na->winx == 0)
	    na->winx		= (5*x+1) * DEF_NODE_X;
	if(na->winy == 0)
	    na->winy		= (5*y+1) * DEF_NODE_Y;

/*  ADD ANY REBOOT ARGUMENTS IF NOT PROVIDED BY TOPOLOGY FILE */
	if(na->reboot_args == (char **)NULL)
	    init_reboot_args(na, argc, argv);
    }

/*  NEXT, PROVIDE A WARNING (ONLY) IF THE TOPOLOGY IS NOT CONNECTED */
    for(n=0, lp=LP ; n<_NLINKS ; n++, lp++)
	if(LP[n].linktype == LT_POINT2POINT) {
	    int	from	= lp->endmin;
	    int	to	= lp->endmax;
	    adj[from][to] = adj[to][from] = TRUE;
	}

    if(!connected(_NNODES, adj))
	fprintf(stderr, "*** warning: this topology is not connected\n");
    for(n=0 ; n<_NNODES ; ++n)
	free(adj[n]);
    free(adj);

/*  IF ATTEMPTING TO DRAWN FRAMES IN A 2-NODE WORLD (ONLY), POSITION NODES */
    if(_NNODES == 2 && gattr.drawframes && nethernets == 0 && !Tflag && Wflag) {
	NP[0].nattr.x		= DEF_NODE_X;
	NP[0].nattr.y		= DEF_NODE_Y;
	NP[1].nattr.x		= DRAWFRAME_WIDTH - DEF_NODE_X;
	NP[1].nattr.y		= DEF_NODE_Y;
    }
    else
	gattr.drawframes	= FALSE;
}