Example #1
0
/* Symbol tables storing the FROM symbols of arcs do not necessarily
   have distinct address ranges.  For example, somebody might request
   -k /_mcount to suppress any arcs into _mcount, while at the same
   time requesting -k a/b.  Fortunately, those symbol tables don't get
   very big (the user has to type them!), so a linear search is probably
   tolerable.  */
bfd_boolean
sym_id_arc_is_present (Sym_Table *sym_tab, Sym *from, Sym *to)
{
  Sym *sym;

  for (sym = sym_tab->base; sym < sym_tab->limit; ++sym)
    {
      if (from->addr >= sym->addr && from->addr <= sym->end_addr
	  && arc_lookup (sym, to))
	return TRUE;
    }

  return FALSE;
}
Example #2
0
// the returned object is retained, the caller must call arc_release_resource(obj) to release it
arc_resource_t 
arc_lookup(arc_t *cache, const void *key, size_t len, void **valuep, int async)
{
    // NOTE: this is an atomic operation ensured by the hashtable implementation,
    //       we don't do any real copy in our callback but we just increase the refcount
    //       of the object (if found)
    arc_object_t *obj = ht_get_deep_copy(cache->hash, (void *)key, len, NULL, retain_obj_cb, cache);
    if (obj) {
        if (!ATOMIC_READ(cache->mode) || UNLIKELY(ATOMIC_READ(obj->state) != &cache->mfu)) {
            if (UNLIKELY(arc_move(cache, obj, &cache->mfu) == -1)) {
                fprintf(stderr, "Can't move the object into the cache\n");
                return NULL;
            }
            arc_balance(cache);
        }

        if (valuep)
            *valuep = obj->ptr;

        return obj;
    }

    obj = arc_object_create(cache, key, len);
    if (!obj)
        return NULL;

    // let our cache user initialize the underlying object
    cache->ops->init(key, len, async, (arc_resource_t)obj, obj->ptr, cache->ops->priv);
    obj->async = async;

    retain_ref(cache->refcnt, obj->node);
    // NOTE: atomicity here is ensured by the hashtable implementation
    int rc = ht_set_if_not_exists(cache->hash, (void *)key, len, obj, sizeof(arc_object_t));
    switch(rc) {
        case -1:
            fprintf(stderr, "Can't set the new value in the internal hashtable\n");
            release_ref(cache->refcnt, obj->node);
            break;
        case 1:
            // the object has been created in the meanwhile
            release_ref(cache->refcnt, obj->node);
            // XXX - yes, we have to release it twice
            release_ref(cache->refcnt, obj->node);
            return arc_lookup(cache, key, len, valuep, async);
        case 0:
            /* New objects are always moved to the MRU list. */
            rc  = arc_move(cache, obj, &cache->mru);
            if (rc >= 0) {
                arc_balance(cache);
                *valuep = obj->ptr;
                return obj;
            }
            break;
        default:
            fprintf(stderr, "Unknown return code from ht_set_if_not_exists() : %d\n", rc);
            release_ref(cache->refcnt, obj->node);
            break;
    } 
    release_ref(cache->refcnt, obj->node);
    return NULL;
}