Beispiel #1
0
int main() {
    TItem *list =  malloc(sizeof(TItem));
    *list = malloc(sizeof(TItem));
    *((TItem *) *list) = NULL;
    dispose_list(&list);
    dispose_list(&list);
    return 0;
}
Beispiel #2
0
static int free_inodes(int goal)
{
	struct list_head *tmp, *head = &inode_in_use;
	LIST_HEAD(freeable);
	int found = 0, depth = goal << 1;

	while ((tmp = head->prev) != head && depth--) {
		struct inode * inode = list_entry(tmp, struct inode, i_list);
		list_del(tmp);
		if (CAN_UNUSE(inode)) {
			list_del(&inode->i_hash);
			INIT_LIST_HEAD(&inode->i_hash);
			list_add(tmp, &freeable);
			if (++found < goal)
				continue;
			break;
		}
		list_add(tmp, head);
	}
	if (found) {
		spin_unlock(&inode_lock);
		dispose_list(&freeable);
		spin_lock(&inode_lock);
	}
	return found;
}
Beispiel #3
0
static int free_inodes(void)
{
	struct list_head list, *entry, *freeable = &list;
	int found = 0;

	INIT_LIST_HEAD(freeable);
	entry = inode_in_use.next;
	while (entry != &inode_in_use) {
		struct list_head *tmp = entry;

		entry = entry->next;
		if (!CAN_UNUSE(INODE(tmp)))
			continue;
		list_del(tmp);
		list_del(&INODE(tmp)->i_hash);
		INIT_LIST_HEAD(&INODE(tmp)->i_hash);
		list_add(tmp, freeable);
		list_entry(tmp, struct inode, i_list)->i_state = I_FREEING;
		found = 1;
	}

	if (found)
		dispose_list(freeable);

	return found;
}
Beispiel #4
0
/*
 * This is a two-stage process. First we collect all
 * offending inodes onto the throw-away list, and in
 * the second stage we actually dispose of them. This
 * is because we don't want to sleep while messing
 * with the global lists..
 */
int invalidate_inodes(struct super_block * sb)
{
	int busy;
	LIST_HEAD(throw_away);

	spin_lock(&inode_lock);
	busy = invalidate_list(&inode_in_use, sb, &throw_away);
	busy |= invalidate_list(&sb->s_dirty, sb, &throw_away);
	dispose_list(&throw_away);
	spin_unlock(&inode_lock);

	return busy;
}
Beispiel #5
0
/* Adds memory dependencies based on ordering type:
  0 - exact; 1 - strong; 2 - weak;  3 - none */
void add_memory_dep (cuc_func *f, int otype)
{
  int b, i;
  dep_list *all_mem = NULL;

  for (b = 0; b < f->num_bb; b++) {
    cuc_insn *insn = f->bb[b].insn;
    for (i = 0; i < f->bb[b].ninsn; i++)
      if (insn[i].type & IT_MEMORY) {
        dep_list *tmp = all_mem;
        while (tmp) {
          //PRINTF ("%x %x\n", REF (b,i), tmp->ref);
          if (check_memory_conflict (f, &insn[i], &f->INSN(tmp->ref), otype))
            add_dep (&insn[i].dep, tmp->ref);
          tmp = tmp->next;
        }
        add_dep (&all_mem, REF (b, i));
      }
  }
  dispose_list (&all_mem);
}
Beispiel #6
0
static w_query_expr *parse_list(w_query *query, json_t *term, bool allof)
{
    struct w_expr_list *list;
    size_t i;

    /* don't allow "allof" on its own */
    if (!json_is_array(term) || json_array_size(term) < 2) {
        query->errmsg = strdup("must use [\"allof\", expr...]");
        return NULL;
    }

    list = calloc(1, sizeof(*list));
    if (!list) {
        query->errmsg = strdup("out of memory");
        return NULL;
    }

    list->allof = allof;
    list->num = json_array_size(term) - 1;
    list->exprs = calloc(list->num, sizeof(list->exprs[0]));

    for (i = 0; i < list->num; i++) {
        w_query_expr *parsed;
        json_t *exp = json_array_get(term, i + 1);

        parsed = w_query_expr_parse(query, exp);
        if (!parsed) {
            // other expression parser sets errmsg
            dispose_list(list);
            return NULL;
        }

        list->exprs[i] = parsed;
    }

    return w_query_expr_new(eval_list, dispose_list, list);
}
Beispiel #7
0
/* Schedule memory accesses
  0 - exact; 1 - strong; 2 - weak;  3 - none */
int schedule_memory (cuc_func *f, int otype)
{
  int b, i, j;
  int modified = 0;
  f->nmsched = 0;
  
  for (b = 0; b < f->num_bb; b++) {
    cuc_insn *insn = f->bb[b].insn;
    for (i = 0; i < f->bb[b].ninsn; i++)
      if (insn[i].type & IT_MEMORY) {
        f->msched[f->nmsched++] = REF (b, i);
        if (otype == MO_NONE || otype == MO_WEAK) insn[i].type |= IT_FLAG1; /* mark unscheduled */
      }
  }

  for (i = 0; i < f->nmsched; i++)
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
  cucdebug (2, "\n");
  
  /* We can reorder just more loose types
     We assume, that memory accesses are currently in valid (but not neccesserly)
     optimal order */
  if (otype == MO_WEAK || otype == MO_NONE) {
    for (i = 0; i < f->nmsched; i++) {
      int best = i;
      int tmp;
      for (j = i + 1; j < f->nmsched; j++) if (REF_BB(f->msched[j]) == REF_BB(f->msched[best])) {
        if (mem_ordering_cmp (f, &f->INSN (f->msched[j]), &f->INSN(f->msched[best]))) {
          /* Check dependencies */
          dep_list *t = f->INSN(f->msched[j]).dep;
          while (t) {
            if (f->INSN(t->ref).type & IT_FLAG1) break;
            t = t->next;
          }
          if (!t) best = j; /* no conflicts -> ok */
        }
      }
      
      /* we have to shift instructions up, to maintain valid dependencies
         and make space for best candidate */

      /* make local copy */
      tmp = f->msched[best];
      for (j = best; j > i; j--) f->msched[j] = f->msched[j - 1];
      f->msched[i] = tmp;
      f->INSN(f->msched[i]).type &= ~IT_FLAG1; /* mark scheduled */
    }
  }
  
  for (i = 0; i < f->nmsched; i++)
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
  cucdebug (2, "\n");
  
  /* Assign memory types */
  for (i = 0; i < f->nmsched; i++) {
    cuc_insn *a = &f->INSN(f->msched[i]);
    f->mtype[i] = !II_IS_LOAD(a->index) ? MT_STORE : MT_LOAD;
    f->mtype[i] |= II_MEM_WIDTH (a->index);
    if (a->type & IT_SIGNED) f->mtype[i] |= MT_SIGNED;
  }

  if (same_transfers (f, otype)) modified = 1;
  if (join_transfers (f, otype)) modified = 1;

  for (i = 0; i < f->nmsched; i++)
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
  cucdebug (2, "\n");
  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL");
  
  if (config.cuc.enable_bursts) {
    //PRINTF ("\n");
    for (i = 1; i < f->nmsched; i++) {
      cuc_insn *a = &f->INSN(f->msched[i - 1]);
      cuc_insn *b = &f->INSN(f->msched[i]);
      int aw = f->mtype[i - 1] & MT_WIDTH;

      /* Burst can only be out of words */
      if (aw != 4) continue;

      if ((a->opt[1] & OPT_REF) && f->INSN(a->op[1]).index == II_ADD
        &&(b->opt[1] & OPT_REF) && f->INSN(b->op[1]).index == II_ADD) {
        a = &f->INSN(a->op[1]);
        b = &f->INSN(b->op[1]);
        /* Not in usual form? */
        if (a->opt[1] != b->opt[1] || a->op[1] != b->op[1]
         || a->opt[2] != OPT_CONST || b->opt[2] != OPT_CONST) continue; 

        //PRINTF ("%i %i, ", a->op[2], b->op[2]);
        
        /* Check if they touch together */
        if (a->op[2] + aw == b->op[2]
          && REF_BB(f->msched[i - 1]) == REF_BB(f->msched[i])) {
          /* yes => do burst */
          f->mtype[i - 1] &= ~MT_BURSTE;
          f->mtype[i - 1] |= MT_BURST;
          f->mtype[i] |= MT_BURST | MT_BURSTE;
        }
      }
    }
  }

  for (i = 0; i < f->nmsched; i++)
    cucdebug (2, "[%x]%x%c ", f->msched[i], f->mtype[i] & MT_WIDTH, (f->mtype[i] & MT_BURST) ? (f->mtype[i] & MT_BURSTE) ? 'E' : 'B' : ' ');
  cucdebug (2, "\n");
  
  /* We don't need dependencies in non-memory instructions */
  for (b = 0; b < f->num_bb; b++) {
    cuc_insn *insn = f->bb[b].insn;
    for (i = 0; i < f->bb[b].ninsn; i++) if (!(insn[i].type & IT_MEMORY))
      dispose_list (&insn[i].dep);
  }

  if (cuc_debug > 5) print_cuc_bb (f, "AFTER_MEM_REMOVAL2");
  /* Reduce number of dependecies, keeping just direct dependencies, based on memory schedule */
  {
    int lastl[3] = {-1, -1, -1};
    int lasts[3] = {-1, -1, -1};
    int lastc[3] = {-1, -1, -1};
    int last_load = -1, last_store = -1, last_call = -1;
    for (i = 0; i < f->nmsched; i++) {
      int t = f->mtype[i] & MT_LOAD ? 0 : f->mtype[i] & MT_STORE ? 1 : 2;
      int maxl = lastl[t];
      int maxs = lasts[t];
      int maxc = lastc[t];
      dep_list *tmp = f->INSN(f->msched[i]).dep;
      cucdebug (7, "!%i %x %p\n", i, f->msched[i], tmp);
      while (tmp) {
        if (f->INSN(tmp->ref).type & IT_MEMORY && REF_BB(tmp->ref) == REF_BB(f->msched[i])) {
          cucdebug (7, "%i %x %lx\n", i, f->msched[i], tmp->ref);
          /* Search for the reference */
          for (j = 0; j < f->nmsched; j++) if (f->msched[j] == tmp->ref) break;
          assert (j < f->nmsched);
          if (f->mtype[j] & MT_STORE) {
            if (maxs < j) maxs = j;
          } else if (f->mtype[j] & MT_LOAD) {
            if (maxl < j) maxl = j;
          } else if (f->mtype[j] & MT_CALL) {
            if (maxc < j) maxc = j;
          }
        }
        tmp = tmp->next;
      }
      dispose_list (&f->INSN(f->msched[i]).dep);
      if (f->mtype[i] & MT_STORE) {
        maxs = last_store;
        last_store = i;
      } else if (f->mtype[i] & MT_LOAD) {
        maxl = last_load;
        last_load = i;
      } else if (f->mtype[i] & MT_CALL) {
        maxc = last_call;
        last_call = i;
      }
      
      if (maxl > lastl[t]) {
        add_dep (&f->INSN(f->msched[i]).dep, f->msched[maxl]);
        lastl[t] = maxl;
      }
      if (maxs > lasts[t]) {
        add_dep (&f->INSN(f->msched[i]).dep, f->msched[maxs]);
        lasts[t] = maxs;
      }
      if (maxc > lastc[t]) {
        add_dep (&f->INSN(f->msched[i]).dep, f->msched[maxc]);
        lastc[t] = maxc;
      }
      //PRINTF ("%i(%i)> ml %i(%i) ms %i(%i) lastl %i %i lasts %i %i last_load %i last_store %i\n", i, f->msched[i], maxl, f->msched[maxl], maxs, f->msched[maxs], lastl[0], lastl[1], lasts[0], lasts[1], last_load, last_store);
      
      /* What we have to wait to finish this BB? */
      if (i + 1 >= f->nmsched || REF_BB(f->msched[i + 1]) != REF_BB(f->msched[i])) {
        if (last_load > lastl[t]) {
          add_dep (&f->bb[REF_BB(f->msched[i])].mdep, f->msched[last_load]);
          lastl[t] = last_load;
        }
        if (last_store > lasts[t]) {
          add_dep (&f->bb[REF_BB(f->msched[i])].mdep, f->msched[last_store]);
          lasts[t] = last_store;
        }
        if (last_call > lastc[t]) {
          add_dep (&f->bb[REF_BB(f->msched[i])].mdep, f->msched[last_call]);
          lastc[t] = last_call;
        }
      }
    }
  }
  return modified;
}