Пример #1
0
void *
pool_Address (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pool_tRef		r
)
{
  pwr_tStatus		lsts;
  pool_uRefBits		prf;
  pool_sGsegment	*gpsp;
  pool_sSegment		*psp;

  if (r == pool_cNRef)
    return NULL;

  prf.m = r;
//  comparison always false prf.b.seg 8 bits and pool_cSegs 1 << 8, 9 bits
//  if (prf.b.seg > pool_cSegs)
//    errh_ReturnOrBugcheck(NULL, sts, POOL__BADSEG, "");

  psp = &php->seg[prf.b.seg];
  gpsp = &php->gphp->seg[prf.b.seg];

  if (gpsp->generation > 0) {
    psp = ensureMapped(&lsts, php, psp);
    if (psp == NULL) errh_ReturnOrBugcheck(NULL, sts, lsts, "");

    if (prf.b.offs < gpsp->size) {
      return (pool_sData *)((char *)psp->base + prf.b.offs);
    }
  }

  errh_ReturnOrBugcheck(NULL, sts, POOL__BADOFFS, "");
}
Пример #2
0
static pool_sSegment *
mapSegment (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pool_sSegment		*psp
)
{
  pwr_tStatus		lsts;
  sect_sHead		*shp;
  pwr_tBoolean		created;
  char			name[16];
  pool_sGhead		*gphp = php->gphp;

  /* Map the section */

  segName(name, gphp->name, psp->gpsp->generation);

  shp = sect_Alloc(&lsts, &created, &psp->sect, psp->gpsp->size << pool_cOffsGranul, name);
  if (shp == NULL) errh_ReturnOrBugcheck(NULL, sts, lsts, "");

  if (created) errh_Bugcheck(POOL__NOTCREATED, "pool was not created"); 

  psp->generation = psp->gpsp->generation;
  psp->base = psp->sect.base;

  return psp;
}
Пример #3
0
pwr_tBoolean
sect_Lock (
  pwr_tStatus		*sts,
  sect_sHead		*shp,
  sect_sMutex		*mp
)
{
  pwr_tStatus		lsts = 1;

#if defined(OS_ELN)
  ELN$LOCK_AREA((AREA)shp->area, *mp);
#elif defined(OS_VMS)
  {
    sect_sMutexEntry	*ep;
    int			i;

    /* Get free list entry.  */

    while ( 1) {
      i = _REMQHI(&mp->freeroot, (void **)&ep);
      if ( i == 1)
        continue;
      else if (i == 3) 
        sleep(1);
      else
        break;
    }

    /* Insert in ownership list.  */

    while ((i = _INSQTI(ep, &mp->ownerroot)) == 1);
    if (i == 0) {

      /* Contention, we must wait for the resource.  */

      lsts = sys$ascefc(64, &shp->namedsc, 0, 0);
      if (ODD(lsts)) lsts = sys$waitfr(ep->flag);
      if (ODD(lsts)) lsts = sys$clref(ep->flag);
    }
  }
#elif defined(OS_LYNX)
  while (sem_wait(mp) != 0) {
    if (errno != EINTR) {
      perror("sect_Lock: sem_wait ");
      lsts = 2;
      break;
    }
  }
#elif defined OS_POSIX
  while (posix_sem_wait(mp) != 0) {
    if (errno != EINTR) {
      perror("sect_Lock: sem_wait ");
      lsts = 2;
      break;
    }
  }
#endif

  errh_ReturnOrBugcheck(ODD(lsts), sts, lsts, "");
}
Пример #4
0
pwr_tBoolean
sect_Unlock (
  pwr_tStatus		*sts,
  sect_sHead		*shp,
  sect_sMutex		*mp
)
{
  pwr_tStatus		lsts = 1;

#if defined(OS_ELN)
  ELN$UNLOCK_AREA((AREA)shp->area, *mp);
#elif defined(OS_VMS)
  {
    sect_sMutexEntry	*ep;
    pwr_tUInt32		i;

    /* When the entry is removed the resource becomes
       free if noone else is waiting...  */

    while ((i = _REMQHI(&mp->ownerroot, (void **)&ep)) == 1);
    if (i == 3) {
      lsts = LIB$_QUEWASEMP;
    } else {

      /* Reinsert entry in free list */

      while (_INSQTI(ep, &mp->freeroot) == 1);

      if (i == 0) {
	/* Someone was waiting.  */

	ep = (sect_sMutexEntry *)(
	  ((pwr_tUInt32)&mp->ownerroot) +
	  mp->ownerroot.low /* flink */);
	lsts = sys$ascefc(64, &shp->namedsc, 0, 0);
	if (ODD(lsts)) lsts = sys$setef(ep->flag);
      }
    }
  }
#elif defined(OS_LYNX)
  if (sem_post(mp) != 0) {
    perror("sect_Unlock: sem_signal ");
    lsts = 2;
  }
#elif defined OS_POSIX
  if (posix_sem_post(mp) != 0) {
    perror("sect_Unlock: sem_signal ");
    lsts = 2;
  }
#endif

  errh_ReturnOrBugcheck(ODD(lsts), sts, lsts, "");

}
Пример #5
0
pwr_tBoolean
pool_FreeReference (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pool_tRef		r
)
{
  pwr_tStatus		lsts;
  pool_sEntry		*ep;

  /* Check & translate poolref */

  if (r == pool_cNRef)
    errh_ReturnOrBugcheck(NO, sts, POOL__NULLREF, "");

  ep = (pool_sEntry *) pool_Address(&lsts, php, r);

  ep = entryPAdd( ep, -sizeof(pool_sEntry));		/* Back to the header */

  if (r != ep->next)
    errh_ReturnOrBugcheck(NO, sts, POOL__NOMARK, "");

  return freeItem(sts, php, ep);
}
Пример #6
0
pwr_tBoolean
pool_Free (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  void			*p
)
{
  pwr_tStatus		lsts;
  pool_sEntry		*ep;

  /* Check & translate poolref */

  if (p == NULL)
    errh_ReturnOrBugcheck(NO, sts, POOL__NULLADDR, "");

  ep = (pool_sEntry *) p;

  ep = entryPAdd( ep, -sizeof(pool_sEntry));		/* Back to the header */

  if (p != pool_Address(&lsts, php, ep->next))
    errh_ReturnOrBugcheck(NO, sts, POOL__NOMARK, "");

  return freeItem(sts, php, ep);
}
Пример #7
0
static pool_sSegment *
ensureMapped (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pool_sSegment		*psp
)
{
  if (psp->generation == psp->gpsp->generation) 
    return psp;

  if (psp->generation != 0)
    errh_ReturnOrBugcheck(NULL, sts, POOL__REMAPNYI, "");

  return mapSegment(sts, php, psp);
}
Пример #8
0
pwr_tBoolean
sect_InitLock (
  pwr_tStatus		*sts,
  sect_sHead		*shp,
  sect_sMutex		*mp
)
{
  pwr_tStatus		lsts = 1;

#ifdef	OS_ELN
  ELN$INITIALIZE_AREA_LOCK((AREA)shp->area, *mp, &lsts);

#elif defined(OS_VMS)
  {
    pwr_tUInt32		i;

    /* Clear mutex variable and build free list.  */

    memset(mp, 0, sizeof(*mp));
    lsts = sys$ascefc(64, &shp->namedsc, 0, 0);
    if (ODD(lsts)) {
      for (i=0; i<32; i++) {
	while (_INSQTI(&mp->list[i].entry, &mp->freeroot) == 1);
	mp->list[i].flag = 64+i;
	lsts = sys$clref(mp->list[i].flag);
	if (EVEN(lsts)) break;
      }
    }
  }

#elif defined(OS_LYNX)
  if (sem_init(mp, 1, 1) != 0) {
    errh_Error("sect_InitLock: sem_init, errno: %d", errno);
    lsts = 2;
  }
#elif defined OS_POSIX
  if (posix_sem_init_shared(mp, ftok(shp->name, 'P'), 1) != 0) {
    errh_Error("sect_InitLock: sem_init(%s), errno: %d", shp->name, errno);
    lsts = 2;
  }  
#endif

  errh_ReturnOrBugcheck(ODD(lsts), sts, lsts, "");
}
Пример #9
0
void *
pool_Alloc (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pwr_tUInt32		size
)
{
  pwr_tStatus		lsts = 1;
  pool_sGhead		*gphp;
  pool_sGsegment	*gpsp;
  pool_sSegment		*psp;
  pool_sEntry		*ep;
  pool_sEntry		*prevp;
  pool_sEntry		*tmpp;
  pwr_tUInt32		esize;	/* True size ( incl header) in pool_sData units */
  pwr_tUInt32		tmpsize;
  pwr_tBoolean		found;
  pool_uRefBits		pr;
  pwr_tUInt32		i = 0;

#if 0
  pwr_SetStatus(sts, 1);
#endif

  gphp = php->gphp;

  if (size == gphp->la[0].size) {
    if (gphp->la[0].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[0]);
  } else if (size == gphp->la[1].size) {
    if (gphp->la[1].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[1]);
  } else if (size == gphp->la[2].size) {
    if (gphp->la[2].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[2]);
  } else if (size == gphp->la[3].size) {
    if (gphp->la[3].next != pool_cNOffset)
      return allocLookaside(sts, php, &gphp->la[3]);
  }

  esize = entryUnits(size + sizeof(pool_sEntry));	 /* Add space for header */

  /* Find a segment where there is room.  */

  found = FALSE;
  for (
    i = 0, gpsp = &gphp->seg[0], psp = &php->seg[0];
    i < pool_cSegs;
    i++, gpsp++, psp++
  ) {
    if (gpsp->generation == 0)
      break;

    if (gpsp->type != pool_eSegType_dynamic)
      continue;

    if (gpsp->fragmax >= esize) {
      found = TRUE;
      break;
    }
  }

  /* Allocate a new segment if noone fits,
     otherwise make sure the existing segment is mapped.  */

  if (!found)
    psp = newSegment(&lsts, php, MAX(gphp->extendsize, esize));
  else
    psp = ensureMapped(&lsts, php, psp);

  if (psp == NULL)
    errh_ReturnOrBugcheck(NULL, sts, lsts, "");

  /* Walk through the free list of the chosen segment.
     The segment is pointed out by psp/gpsp!  */

  ep = NULL;
  prevp = &gpsp->freeroot;
  while (prevp->next != pool_cNOffset) {
    tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
    if (tmpp->size >= esize) {	/* Found */
      ep = tmpp;
      break;
    } /* If the entry is larger or equal to the requested */

    prevp = tmpp;			/* Try next */
  } /* While more entries in free list */

  /* Now ep points to the chosen free list entry. Remove this entry
     from the list, or split it if it is larger than requested.
     We need to update the fragmentation information, too.

     If we come here without a selection
     there is an internal consistency problem.  */

  if (ep == NULL)
    errh_Bugcheck(POOL__BUGCHECK, "");

  tmpsize = ep->size;

  if (ep->size == esize || 
      (ep->size - esize > 0 && 
       (ep->size - esize) * pool_cDataSize < sizeof(pool_sEntry))) {	/* Entry fits exactly */
    prevp->next = ep->next;
    --gpsp->fragcnt;
  }
  else {	/* Entry is to big, split it */
    prevp->next = prevp->next + esize;
    tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
    tmpp->next = ep->next;
    tmpp->size = ep->size - esize;
    ep->size = esize;
  }
  memset( entryPAdd(ep, sizeof(pool_sEntry)), 0, esize*pool_cDataSize - sizeof(pool_sEntry));
  ep->next = cEntryMark;

  gpsp->alloccnt++;
  gpsp->fragsize -= esize;

  /* Keep track of the maximum fragment size and count */

  if (tmpsize == gpsp->fragmax) {
    if ((--gpsp->fragmaxcnt) == 0) {	/* In this special case we need to */
				    /* rebuild the fragmax&cnt info */
      gpsp->fragmax = 0;
      gpsp->fragmaxcnt = 1;
      prevp = &gpsp->freeroot;
      while (prevp->next != pool_cNOffset) {
	tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
	if (tmpp->size >= gpsp->fragmax) {
	  if (tmpp->size == gpsp->fragmax) gpsp->fragmaxcnt++;
	  else {
	    gpsp->fragmaxcnt = 1;
	    gpsp->fragmax = tmpp->size;
	  } /* new fragmax entry found */
	} /* new or equal to fragmax found */
	prevp = tmpp;			/* next entry */
      } /* While more entries in free list */
    } /* If no more fragmax entries left */
  } /* If this was a fragmax entry */

  pr.m = pool_cNRef;
  pr.b.seg = psp->seg;
  pr.b.offs = (pool_tOffset)((char *)ep + sizeof(pool_sEntry) - (char *)psp->base);
  ep->next = pr.m;

  return (void *)(entryPAdd(ep, sizeof(pool_sEntry)));
}
Пример #10
0
static pwr_tBoolean
freeItem (
  pwr_tStatus		*sts,
  pool_sHead		*php,
  pool_sEntry		*ep
)
{
  pwr_tStatus		lsts;
  pool_sGhead		*gphp;
  pool_sGsegment	*gpsp;
  pool_sSegment		*psp;
  pool_sEntry		*prevp;
  pool_sEntry		*tmpp;
  pool_tOffset		offs;
  pwr_tUInt32		seg;
  pool_uRefBits		pr;
  pool_sList		*lp;

  pr.m = ep->next;

  /* Fill returned entry with with the bit pattern '01010101'...  */
  memset( entryPAdd(ep, sizeof(pool_sEntry)), 85, ep->size*pool_cDataSize - sizeof(pool_sEntry));

  /* Setup pointers */

  gphp = php->gphp;
  seg = pr.b.seg;
  offs = entryUnits(pr.b.offs - sizeof(pool_sEntry));
  psp = &php->seg[seg];
  gpsp = &gphp->seg[seg];

  psp = ensureMapped(&lsts, php, psp);
  if (psp == NULL)
    errh_ReturnOrBugcheck(NO, sts, lsts, "");

  switch (gpsp->type) {
  case pool_eSegType_lookaside:
    lp = &gphp->la[gpsp->la_idx];
    ep->next = lp->next;
    lp->next = offs;
    gpsp->alloccnt--;
    return YES;
    break;
  case pool_eSegType_named:
    errh_ReturnOrBugcheck(NO, sts, POOL__FREENAMED, "");
    break;
  default:
    break;
  }


  /* Find where the offs belongs in free list */

  prevp = &gpsp->freeroot;
  while (prevp->next != pool_cNOffset) {
    if (offs < prevp->next) break;		/* found */
    prevp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize); /* try next */
  } /* While more free entries */

  /* Here prevp points to the entry after which insertion should be done
     NOTE. Prevp can point to the header or to the last fragment!  */

  ep->next = prevp->next;
  prevp->next = ((char *)ep - (char *)psp->base)/pool_cDataSize;
  gpsp->fragcnt++;
  gpsp->fragsize += ep->size;
  gpsp->alloccnt--;
  if (ep->size >= gpsp->fragmax) {
    if (ep->size == gpsp->fragmax) gpsp->fragmaxcnt++;
    else {
      gpsp->fragmax = ep->size;
      gpsp->fragmaxcnt = 1;
    }
  }

  /* Join with succeeding/preceeding fragment? */

  do {
    tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);

    if (entryPAdd(prevp, prevp->size * pool_cDataSize) == tmpp) {
      prevp->size += tmpp->size;
      prevp->next = tmpp->next;
      /* Fill recovered list info with the bit pattern '01010101'...  */
      memset(tmpp, 85, sizeof(*tmpp));

      gpsp->fragcnt--;
      if (prevp->size >= gpsp->fragmax) {
	if (prevp->size == gpsp->fragmax) gpsp->fragmaxcnt++;
	else {
	  gpsp->fragmax = prevp->size;
	  gpsp->fragmaxcnt = 1;
	} /* if new fragmax found */
      } /* if fragmax is affected */
    } /* if adjacent */
    else prevp = tmpp;

  } while ((prevp->next != pool_cNOffset) && (prevp <= ep));

  return YES;
}