Esempio n. 1
0
void GWEN_MemCache_PurgeEntries(GWEN_MEMCACHE *mc,
                                uint32_t id, uint32_t mask) {
  GWEN_IDMAP_RESULT res;
  uint32_t currentId;

  assert(mc);
  GWEN_MemCache_Lock(mc);

  res=GWEN_MemCacheEntry_IdMap_GetFirst(mc->idMap, &currentId);
  while(res==GWEN_IdMapResult_Ok) {
    uint32_t nextId;

    nextId=currentId;
    res=GWEN_MemCacheEntry_IdMap_GetNext(mc->idMap, &nextId);
    if ((currentId & mask)==id) {
      GWEN_MEMCACHE_ENTRY *me;

      me=GWEN_MemCacheEntry_IdMap_Find(mc->idMap, currentId);
      if (me) {
        me->isValid=0;
        GWEN_MemCacheEntry_IdMap_Remove(mc->idMap, currentId);
        if (me->useCounter==0)
          GWEN_MemCacheEntry_free(me);
      }

    }
    currentId=nextId;
  }

  GWEN_MemCache_Unlock(mc);
}
Esempio n. 2
0
void GWEN_MemCacheEntry_EndUse(GWEN_MEMCACHE_ENTRY *me) {
  int rv;

  assert(me);
  rv=GWEN_MemCache_Lock(me->memCache);
  if (rv) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    assert(0);
  }
  if (me->useCounter>0) {
    me->useCounter--;
    if (me->useCounter==0) {
      if (!(me->isValid)) {
        GWEN_MemCacheEntry_free(me);
      }
      else
        me->unusedSince=time(0);
    }
  }
  else {
    DBG_ERROR(GWEN_LOGDOMAIN, "Use counter < 1, aborting");
    GWEN_MemCache_Unlock(me->memCache);
    assert(me->useCounter>0);
  }
  GWEN_MemCache_Unlock(me->memCache);
}
Esempio n. 3
0
GWEN_MEMCACHE_ENTRY *GWEN_MemCache_CreateEntry(GWEN_MEMCACHE *mc,
                                               uint32_t id,
                                               void *dataPtr,
                                               size_t dataLen)
{
  GWEN_MEMCACHE_ENTRY *me;

  assert(mc);
  GWEN_MemCache_Lock(mc);

  /* invalidate possibly existing entry in any case */
  me=GWEN_MemCacheEntry_IdMap_Find(mc->idMap, id);
  if (me) {
    me->isValid=0;
    GWEN_MemCacheEntry_IdMap_Remove(mc->idMap, id);
    if (me->useCounter==0)
      GWEN_MemCacheEntry_free(me);
  }

  /* check for limits: entry count */
  if (mc->currentCacheEntries>=mc->maxCacheEntries) {
    int rv;

    /* release unused entries (at least 1 byte) */
    rv=GWEN_MemCache__MakeRoom(mc, 1);
    if (rv) {
      DBG_WARN(GWEN_LOGDOMAIN, "Too many entries in use");
      GWEN_MemCache_Unlock(mc);
      return NULL;
    }
  }

  /* check for limits: memory in use */
  if ((mc->currentCacheMemory+dataLen)>=mc->maxCacheMemory) {
    size_t diff;
    int rv;

    diff=(mc->currentCacheMemory+dataLen)-mc->maxCacheMemory;
    /* release unused entries */
    rv=GWEN_MemCache__MakeRoom(mc, diff);
    if (rv) {
      DBG_WARN(GWEN_LOGDOMAIN, "Too much memory in use");
      GWEN_MemCache_Unlock(mc);
      return NULL;
    }
  }

  /* create new entry */
  me=GWEN_MemCacheEntry_new(mc, id, dataPtr, dataLen);
  assert(me);
  me->useCounter++;
  GWEN_MemCacheEntry_IdMap_Insert(mc->idMap, id, me);

  GWEN_MemCache_Unlock(mc);

  return me;
}
Esempio n. 4
0
void GWEN_MemCache_PurgeEntry(GWEN_MEMCACHE *mc,
                              uint32_t id) {
  GWEN_MEMCACHE_ENTRY *me;

  assert(mc);
  GWEN_MemCache_Lock(mc);
  me=GWEN_MemCacheEntry_IdMap_Find(mc->idMap, id);
  if (me) {
    me->isValid=0;
    GWEN_MemCacheEntry_IdMap_Remove(mc->idMap, id);
    if (me->useCounter==0)
      GWEN_MemCacheEntry_free(me);
  }
  GWEN_MemCache_Unlock(mc);
}
Esempio n. 5
0
int GWEN_MemCache__MakeRoom(GWEN_MEMCACHE *mc,
                            size_t neededSize)
{
  assert(mc);

  /* release unused entries until there is enough memory */
  while (neededSize) {
    GWEN_MEMCACHE_ENTRY *oldestEntry;
    GWEN_IDMAP_RESULT res;
    uint32_t currentId;

    /* get oldest entry */
    oldestEntry=NULL;
    res=GWEN_MemCacheEntry_IdMap_GetFirst(mc->idMap, &currentId);
    while (res==GWEN_IdMapResult_Ok) {
      GWEN_MEMCACHE_ENTRY *me;

      me=GWEN_MemCacheEntry_IdMap_Find(mc->idMap, currentId);
      if (me) {
        if (me->isValid && me->useCounter==0) {
          if (oldestEntry==NULL)
            oldestEntry=me;
          else {
            if (me->unusedSince<oldestEntry->unusedSince)
              oldestEntry=me;
          }
        }
      }
      res=GWEN_MemCacheEntry_IdMap_GetNext(mc->idMap, &currentId);
    }

    if (oldestEntry==NULL)
      /* no unused entry found */
      break;

    /* subtract size of to-be-removed entry from needed size */
    if (neededSize<oldestEntry->dataLen)
      neededSize=0;
    else
      neededSize-=oldestEntry->dataLen;

    /* remove oldest entry (it is unused, so we also delete it here) */
    GWEN_MemCacheEntry_IdMap_Remove(mc->idMap, oldestEntry->id);
    GWEN_MemCacheEntry_free(oldestEntry);
  }

  return (neededSize==0)?0:GWEN_ERROR_MEMORY_FULL;
}