Пример #1
0
/* to take over. */
void E2FilterIORB (PIORB pIORB)
{
 NPRecHeader	pUnitRec;			/* Ptr to unit rec for IORB */
 NPIORBQueue	pQueue;				/* Ptr to queue for IORB */

 if (pIORB->CommandCode==IOCC_CONFIGURATION)	/* For configuration IORBs: */
  pUnitRec= (NPRecHeader) VirtUnits;		/* Assign IORB to the first */
						/* virtual unit. (For queue) */
 else
  pUnitRec= (NPRecHeader) pIORB->UnitHandle;	/* Get pointer to unit */
						/* from the unit handle */
 /* Check to see if pUnitRec is a pointer to a valid unit record. */
 if (!(IS_ELEMENT(pUnitRec,BaseUnits,NumBaseUnits)||
       IS_ELEMENT(pUnitRec,VirtUnits,NumVirtUnits)))
 {
  IORBError (pIORB,IOERR_NO_SUCH_UNIT);		/* Tell them they are crazy! */
  NotifyDone (pIORB);				/* Notify that we are done */
 }
 else
 {
  pQueue= &(pUnitRec->IORBQueue);		/* Get pointer to IORB queue */
  DISABLE					/* Same safety... */
  AddIORBToQueue (pQueue,pIORB);		/* Add IORB to queue */
  ENABLE					/* Re-enable interrupts */
  StartIORBQueue (pQueue);			/* Try to restart the queue */
 }
}
Пример #2
0
/* %start-doc actions SmartDisperse

The @code{SmartDisperse([All|Selected])} action is a special-purpose
optimization for dispersing elements.

Run with @code{:SmartDisperse()} or @code{:SmartDisperse(Selected)}
(you can also say @code{:SmartDisperse(All)}, but that's the default).

%end-doc */
static int
smartdisperse (int argc, char **argv, Coord x, Coord y)
{
  char *function = ARG(0);
  NetListType *Nets;
  char *visited;
//  PointerListType stack = { 0, 0, NULL };
  int all;
//  int changed = 0;
//  int i;

  if (! function)
  {
    all = 1;
  }
  else if (strcmp(function, "All") == 0)
  {
    all = 1;
  }
  else if (strcmp(function, "Selected") == 0)
  {
    all = 0;
  }
  else
  {
    AFAIL (smartdisperse);
  }

  Nets = ProcNetlist (&PCB->NetlistLib);
  if (! Nets)
  {
    Message (_("Can't use SmartDisperse because no netlist is loaded.\n"));
    return 0;
  }

  /* remember which elements we finish with */
  visited = calloc (PCB->Data->ElementN, sizeof(*visited));

  /* if we're not doing all, mark the unselected elements as "visited" */
  ELEMENT_LOOP (PCB->Data);
  {
    if (! (all || TEST_FLAG (SELECTEDFLAG, element)))
    {
      visited[n] = 1;
    }
  }
  END_LOOP;

  /* initialize variables for place() */
  minx = GAP;
  miny = GAP;
  maxx = GAP;
  maxy = GAP;

  /*
   * Pick nets with two connections.  This is the start of a more
   * elaborate algorithm to walk serial nets, but the datastructures
   * are too gross so I'm going with the 80% solution.
   */
  NET_LOOP (Nets);
  {
    ConnectionType *conna, *connb;
    ElementType *ea, *eb;
//    ElementType *epp;

    if (net->ConnectionN != 2)
      continue;

    conna = &net->Connection[0];
    connb = &net->Connection[1];
    if (!IS_ELEMENT(conna) || !IS_ELEMENT(conna))
      continue;

    ea = (ElementType *) conna->ptr1;
    eb = (ElementType *) connb->ptr1;

    /* place this pair if possible */
    if (VISITED((GList *)ea) || VISITED((GList *)eb))
      continue;
    VISITED ((GList *)ea) = 1;
    VISITED ((GList *)eb) = 1;

    /* a weak attempt to get the linked pads side-by-side */
    if (padorder(conna, connb))
    {
      place ((ElementType *) ea);
      place ((ElementType *) eb);
    }
    else
    {
      place (eb);
      place (ea);
    }
  }
  END_LOOP;

  /* Place larger nets, still grouping by net */
  NET_LOOP (Nets);
  {
    CONNECTION_LOOP (net);
    {
      ElementType *element;

      if (! IS_ELEMENT(connection))
        continue;

      element = (ElementType *) connection->ptr1;

      /* place this one if needed */
      if (VISITED ((GList *) element))
        continue;
      VISITED ((GList *) element) = 1;
      place (element);
    }
    END_LOOP;
  }
  END_LOOP;

  /* Place up anything else */
  ELEMENT_LOOP (PCB->Data);
  {
    if (! visited[n])
    {
      place (element);
    }
  }
  END_LOOP;

  free (visited);

  IncrementUndoSerialNumber ();
  Redraw ();
  SetChangedFlag (1);

  return 0;
}
Пример #3
0
/* being serviced before entering the service loop. */
void StartIORBQueue (NPIORBQueue pQueue)
{
 PIORB			pIORB;			/* Ptr to IORB to execute */
 NPRecHeader		pUnitRec;		/* Pointer to unit record */

 DISABLE					
 if (!(pQueue->Flags&F_SERVER_ACTIVE))		/* Check to no one is busy */
						/* servicing this queue */
 {
  pQueue->Flags|=F_SERVER_ACTIVE;		/* Grap control of queue */
  /* If we get where we have exclusize access to the queue. */
  while ((!(pQueue->Flags&F_REQUEST_BUSY))&&
         ((pIORB= GetIORBFromQueue (pQueue))!=NULL))
						/* Loop while there is an */
						/* IORB ready to be serviced */
						/* and the previous IORB is */
						/* finished. */
  {
   pQueue->Flags|=F_REQUEST_BUSY;		/* Show request in progress */
   ENABLE

   if (pIORB->CommandCode==IOCC_CONFIGURATION)	/* For configuration IORBs: */
    pUnitRec= (NPRecHeader) VirtUnits;		/* Assign IORB to the first */
						/* virtual unit. (For queue) */
   else
    pUnitRec= (NPRecHeader) pIORB->UnitHandle;	/* Get pointer to unit */
						/* from the unit handle */

   /* We will handle (de)allocation and allocation checks here since it is */
   /* common between the two parts- filter and virtual units. */
   if (pIORB->CommandCode==IOCC_UNIT_CONTROL)	/* Unit control command? */
   {
    if (pIORB->CommandModifier==IOCM_ALLOCATE_UNIT)
    {						/* Allocate unit??? */
     if (pUnitRec->Flags&F_ALLOCATED)		
      IORBError (pIORB,IOERR_UNIT_ALLOCATED);	/* Error if allocated */
     else
      pUnitRec->Flags|=F_ALLOCATED;		/* Else allocate the unit */
     pQueue->Flags&=~F_REQUEST_BUSY;		/* Indicate queue finished */
     NotifyDone (pIORB);
     continue;					/* Service next request */
    }
    if (pIORB->CommandModifier==IOCM_DEALLOCATE_UNIT)
    {						/* Deallocate unit??? */
     if (!(pUnitRec->Flags&F_ALLOCATED))	
      IORBError (pIORB,IOERR_UNIT_NOT_ALLOCATED);
						/* Error if not allocated */
     else
      pUnitRec->Flags&=~F_ALLOCATED;		/* Else deallocate unit */
     pQueue->Flags&=~F_REQUEST_BUSY;		/* Indicate queue finished */
     NotifyDone (pIORB);
     continue;					/* Service next request */
    }
   }

   /* Do allocations checks... if notify points to us, skip check. */
   if (!(pUnitRec->Flags&F_ALLOCATED))		/* If unit is not allocated: */
    if (pIORB->NotifyAddress!=&PartNotifyWrapper)
						/* and we didn't make request */
     if (pIORB->CommandCode!=IOCC_CONFIGURATION)
						/*  and not configuration */
     {
      IORBError (pIORB,IOERR_UNIT_NOT_ALLOCATED);
						/* Then it is an error */
      pQueue->Flags&=~F_REQUEST_BUSY;		/* Indicate queue finished */
      NotifyDone (pIORB);
      continue;					/* Service next request */
     }


   if (IS_ELEMENT(pUnitRec,BaseUnits,NumBaseUnits)) 
    FilterHandler (pIORB);			/* Handler for base units */
   else if (IS_ELEMENT(pUnitRec,VirtUnits,NumVirtUnits))
    PartHandler (pIORB);			/* Handler for virtual units */
   DISABLE
  }
  /* Tell others that this server is not active any more... */
  pQueue->Flags&=~F_SERVER_ACTIVE;
 }