Пример #1
0
/*---------------------------------------------------------------------------*/
static void
remove_key(nbr_table_key_t *least_used_key)
{
  int i;
  for(i = 0; i < MAX_NUM_TABLES; i++) {
    if(all_tables[i] != NULL && all_tables[i]->callback != NULL) {
      /* Call table callback for each table that uses this item */
      nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key);
      if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) {
        all_tables[i]->callback(removed_item);
      }
    }
  }
  /* Empty used map */
  used_map[index_from_key(least_used_key)] = 0;
  /* Remove neighbor from list */
  list_remove(nbr_table_keys, least_used_key);
}
Пример #2
0
/*---------------------------------------------------------------------------*/
static nbr_table_key_t *
nbr_table_allocate(void)
{
    nbr_table_key_t *key;
    int least_used_count = 0;
    nbr_table_key_t *least_used_key = NULL;

    key = memb_alloc(&neighbor_addr_mem);
    if(key != NULL) {
        return key;
    } else {
        /* No more space, try to free a neighbor.
                  * The replacement policy is the following: remove neighbor that is:
                  * (1) not locked
                  * (2) used by fewest tables
                  * (3) oldest (the list is ordered by insertion time)
                  * */
        /* Get item from first key */
        key = list_head(nbr_table_keys);
        while(key != NULL) {
            int item_index = index_from_key(key);
            int locked = locked_map[item_index];
            /* Never delete a locked item */
            if(!locked) {
                int used = used_map[item_index];
                int used_count = 0;
                /* Count how many tables are using this item */
                while(used != 0) {
                    if((used & 1) == 1) {
                        used_count++;
                    }
                    used >>= 1;
                }
                /* Find least used item */
                if(least_used_key == NULL || used_count < least_used_count) {
                    least_used_key = key;
                    least_used_count = used_count;
                    if(used_count == 0) { /* We won't find any least used item */
                        break;
                    }
                }
            }
            key = list_item_next(key);
        }
        if(least_used_key == NULL) {
            /* We haven't found any unlocked item, allocation fails */
            return NULL;
        } else {
            /* Reuse least used item */
            int i;
            for(i = 0; i<MAX_NUM_TABLES; i++) {
                if(all_tables[i] != NULL && all_tables[i]->callback != NULL) {
                    /* Call table callback for each table that uses this item */
                    nbr_table_item_t *removed_item = item_from_key(all_tables[i], least_used_key);
                    if(nbr_get_bit(used_map, all_tables[i], removed_item) == 1) {
                        all_tables[i]->callback(removed_item);
                    }
                }
            }
            /* Empty used map */
            used_map[index_from_key(least_used_key)] = 0;
            /* Remove neighbor from list */
            list_remove(nbr_table_keys, least_used_key);
            /* Return associated key */
            return least_used_key;
        }
    }