예제 #1
0
		BOOST_FOREACH (const std::string& s, req2) {
			elem m(s, "modification");

			if (conflicts(elem1, m, true)) {
				return true;
			}
		}
예제 #2
0
static const struct babel_route *
min_conflict(const struct zone *zone, const struct babel_route *rt)
{
    struct babel_route *rt1 = NULL;
    const struct babel_route *min = NULL;
    struct route_stream *stream = NULL;
    struct zone curr_zone;
    stream = route_stream(ROUTE_INSTALLED);
    if(!stream) {
        fprintf(stderr, "Couldn't allocate route stream.\n");
        return NULL;
    }
    while(1) {
        rt1 = route_stream_next(stream);
        if(rt1 == NULL) break;
        __builtin_prefetch(rt1->src,0,1);
        __builtin_prefetch(rt->src,0,1);

        if(!(conflicts(rt, rt1) &&
             zone_equal(inter(rt, rt1, &curr_zone), zone)))
             continue;
        min = min_route(rt1, min);
    }
    route_stream_done(stream);
    return min;
}
예제 #3
0
		BOOST_FOREACH (const std::string& id1, req1) {
			elem m1(id1, "modification");

			BOOST_FOREACH (const std::string& id2, req2) {
				elem m2(id2, "modification");

				if (conflicts(m1, m2)) {
					return true;
				}
			}
예제 #4
0
파일: main.cpp 프로젝트: jbayardo/algo3-tp3
/*
 * ./tp <ejercicio> <entrada> <salida> [corridas=1]
 */
int main(int argc, char *argv[]) {
    if (argc < 4) {
        std::cerr << "Formato de entrada: " << argv[0] << " <ejercicio> <entrada> <salida> <corridas>" << std::endl;

#ifdef DEBUG
        std::cerr << "BUILD DE DEBUG" << std::endl;
#endif

#ifdef EXPS
        std::cerr << "BUILD DE EXPERIMENTACION" << std::endl;
#endif
        return 1;
    }

    int exercise = std::atoi(argv[1]);
    std::string input(argv[2]);
    std::string output(argv[3]);
    int runs;

    if (argc == 4) {
        runs = 1;
    } else {
        runs = std::atoi(argv[4]);
    }

    Problem solver(input);
    Coloring result(solver.solve(exercise, runs));

#if defined(DEBUG) || defined(EXPS)
    ConflictColoring conflicts(result);

    std::cout << conflicts;
#endif

    std::ofstream handle;
    handle.open(output, std::ofstream::out);

    if (!handle.is_open()) {
        throw std::runtime_error("Fallo al abrir el archivo de salida");
    }

#if defined(DEBUG) || defined(EXPS)
    handle << conflicts;
#else
    handle << result;
#endif

    handle.close();

    std::string path = std::string(output);
    std::string basename = path.substr(0, path.find_last_of('.'));
    Statistics::getInstance().dump(basename + std::string(".sts"));

    return 0;
}
예제 #5
0
std::vector<std::string> manager::get_conflicting_enabled(const elem& e) const
{
	std::vector<std::string> result;

	BOOST_FOREACH(const std::string& mod, mods_) {
		if (conflicts(elem(mod, "modification"), e)) {
			result.push_back(mod);
		}
	}

	return result;
}
static
Clause conflicts_with_member(Clause c, Plist p)
{
  if (p == NULL)
    return NULL;
  else {
    Clause empty = conflicts(c, p->v);
    if (empty)
      return empty;
    else
      return conflicts_with_member(c, p->next);
  }
}  /* conflicts_with_member */
예제 #7
0
/* recursively determine solution */
static int findSolution(Queenscreen *qs, int row, int col) 
{
  if(row == qs->BOARDSIZE)
    return 1;
  
  while(col < qs->BOARDSIZE) {
    if(!conflicts(qs, row, col)) {
      qs->board[row][col] = 1;

      if(findSolution(qs, row+1, 0))
        return 1;

      qs->board[row][col] = 0;
    }

    ++col;
  }

  return 0;
}
예제 #8
0
/**
 * @brief HashVector::insert Allows to insert the hashes managed by an other HashVector into this
 * one. If there is a conflict, neither HashVector is modified.
 * @param other The other HashVector.
 * @return true if the insertion was successful (e.g. no conflicts); false otherwise.
 */
bool HashSet::insert( const HashSet& other )
{
	std::vector<Hash*> vNewHashes;
	vNewHashes.reserve( other.hashCount() );

	for ( quint8 i = 0; i < Hash::NO_OF_TYPES; ++i )
	{
		// if there is a hash at position i
		if ( other.m_pHashes[i] )
		{
			if ( !conflicts( *other.m_pHashes[i] ) )
			{
				// if it doesn't clash with an existing hash
				// and we don't have a hash for that type yet
				if ( !m_pHashes[i] )
				{
					// remember the hash for later insertion
					vNewHashes.push_back( new Hash( *other.m_pHashes[i] ) );
				}
			}
			else
			{
				// conflict detected; clear remembered hashes
				for ( size_t i = 0, nMax = vNewHashes.size(); i < nMax; ++i )
				{
					delete vNewHashes[i];
				}
				return false;
			}
		}
	}

	// no conflicts detected; insert the hashes
	for ( size_t i = 0, nMax = vNewHashes.size(); i < nMax; ++i )
	{
		const quint8 type = vNewHashes[i]->type();
		m_pHashes[type] = vNewHashes[i];
	}

	return true;
}
예제 #9
0
static const struct babel_route *
conflict_solution(const struct babel_route *rt)
{
    const struct babel_route *rt1 = NULL, *rt2 = NULL;
    struct route_stream *stream1 = NULL;
    struct route_stream *stream2 = NULL;
    const struct babel_route *min = NULL; /* == solution */
    struct zone zone;
    struct zone tmp;
    /* Having a conflict requires at least one specific route. */
    stream1 = route_stream(ROUTE_SS_INSTALLED);
    if(!stream1) {
        return NULL;
    }
    while(1) {
        rt1 = route_stream_next(stream1);
        if(rt1 == NULL) break;

        stream2 = route_stream(ROUTE_INSTALLED);
        if(!stream2) {
            route_stream_done(stream1);
            fprintf(stderr, "Couldn't allocate route stream.\n");
            return NULL;
        }

        while(1) {
            rt2 = route_stream_next(stream2);
            if(rt2 == NULL) break;
            if(!(conflicts(rt1, rt2) &&
                 zone_equal(inter(rt1, rt2, &tmp), to_zone(rt, &zone)) &&
                 rt_cmp(rt1, rt2) < 0))
                continue;
            min = min_route(rt1, min);
        }
        route_stream_done(stream2);
    }
    route_stream_done(stream1);
    return min;
}
예제 #10
0
bool MeshBVH::Intersect(const MeshBVH &left, const MeshBVH &right, MeshIntersectStatistics &stats)
{
    if(left._root == NULL || right._root == NULL) return false;
    Vector< pair<const MeshBVHNode*, const MeshBVHNode*> > conflicts(1);
    conflicts[0] = make_pair(left._root, right._root);
    while(conflicts.Length() > 0)
    {
        const auto curConflict = conflicts.Last();
        conflicts.PopEnd();
        
        stats.bboxComparisons++;

        const Vec3f centerDiff = curConflict.first->center - curConflict.second->center;
        const Vec3f varianceSum = curConflict.first->variance + curConflict.second->variance;
        if(fabsf(centerDiff.x) <= varianceSum.x &&
           fabsf(centerDiff.y) <= varianceSum.y &&
           fabsf(centerDiff.z) <= varianceSum.z)
        {
            const bool leftIsLeaf = curConflict.first->isLeafNode();
            const bool rightIsLeaf = curConflict.second->isLeafNode();
            if(leftIsLeaf && rightIsLeaf)
            {
                if(MeshBVHDebugging) Console::WriteLine("l=" + String(curConflict.first->triCount) + " r=" + String(curConflict.second->triCount));
                const UINT baseTri0Index = curConflict.first->triIndex;
                const UINT baseTri1Index = curConflict.second->triIndex;
                auto triStorage0 = left._storage.CArray();
                auto triStorage1 = right._storage.CArray();
                for(UINT tri0Index = 0; tri0Index < curConflict.first->triCount; tri0Index++)
                {
                    const MeshBVHTriangleInfo &tri0 = *triStorage0[baseTri0Index + tri0Index];
                    for(UINT tri1Index = 0; tri1Index < curConflict.second->triCount; tri1Index++)
                    {
                        stats.triComparisons++;
                        const MeshBVHTriangleInfo &tri1 = *triStorage1[baseTri1Index + tri1Index];
                        //if(Math::DistanceTriangleTriangleSq(tri0.v[0], tri0.v[1], tri0.v[2], tri1.v[0], tri1.v[1], tri1.v[2]) == 0.0f)
                        if(Math::TriangleIntersectTriangle(tri0.v[0], tri0.v[1], tri0.v[2], tri1.v[0], tri1.v[1], tri1.v[2]))
                        {
                            return true;
                        }
                    }
                }
            }
            else
            {
                if(leftIsLeaf)
                {
                    conflicts.PushEnd(make_pair(curConflict.first, curConflict.second->children[0]));
                    conflicts.PushEnd(make_pair(curConflict.first, curConflict.second->children[1]));
                }
                else if(rightIsLeaf)
                {
                    conflicts.PushEnd(make_pair(curConflict.first->children[0], curConflict.second));
                    conflicts.PushEnd(make_pair(curConflict.first->children[1], curConflict.second));
                }
                else
                {
                    conflicts.PushEnd(make_pair(curConflict.first->children[0], curConflict.second->children[0]));
                    conflicts.PushEnd(make_pair(curConflict.first->children[0], curConflict.second->children[1]));
                    conflicts.PushEnd(make_pair(curConflict.first->children[1], curConflict.second->children[0]));
                    conflicts.PushEnd(make_pair(curConflict.first->children[1], curConflict.second->children[1]));
                }

                /*bool splitLeft = rightIsLeaf;
                if(!leftIsLeaf && !rightIsLeaf)
                {
                    splitLeft = (curConflict.first->size() > curConflict.second->size());
                }
                if(splitLeft)
                {
                    conflicts.PushEnd(make_pair(curConflict.first->children[0], curConflict.second));
                    conflicts.PushEnd(make_pair(curConflict.first->children[1], curConflict.second));
                }
                else
                {
                    conflicts.PushEnd(make_pair(curConflict.first, curConflict.second->children[0]));
                    conflicts.PushEnd(make_pair(curConflict.first, curConflict.second->children[1]));
                }*/
            }
        }
    }
    return false;
}
예제 #11
0
 void ParanoidSolver::postConstraints(void) {
   provides(*this,install_,provides_,virtuals_);
   dependencies(*this,install_,deps_);
   conflicts(*this,install_,conflicts_);
 }
예제 #12
0
/**
 * Handle cp for a given src register.  This additionally handles
 * the cases of collapsing immedate/const (which replace the src
 * register with a non-ssa src) or collapsing mov's from relative
 * src (which needs to also fixup the address src reference by the
 * instruction).
 */
static void
reg_cp(struct ir3_cp_ctx *ctx, struct ir3_instruction *instr,
		struct ir3_register *reg, unsigned n)
{
	struct ir3_instruction *src = ssa(reg);

	/* don't propagate copies into a PHI, since we don't know if the
	 * src block executed:
	 */
	if (instr->opc == OPC_META_PHI)
		return;

	if (is_eligible_mov(src, true)) {
		/* simple case, no immed/const/relativ, only mov's w/ ssa src: */
		struct ir3_register *src_reg = src->regs[1];
		unsigned new_flags = reg->flags;

		combine_flags(&new_flags, src);

		if (valid_flags(instr, n, new_flags)) {
			if (new_flags & IR3_REG_ARRAY) {
				debug_assert(!(reg->flags & IR3_REG_ARRAY));
				reg->array = src_reg->array;
			}
			reg->flags = new_flags;
			reg->instr = ssa(src_reg);
		}

		src = ssa(reg);      /* could be null for IR3_REG_ARRAY case */
		if (!src)
			return;
	} else if (is_same_type_mov(src) &&
			/* cannot collapse const/immed/etc into meta instrs: */
			!is_meta(instr)) {
		/* immed/const/etc cases, which require some special handling: */
		struct ir3_register *src_reg = src->regs[1];
		unsigned new_flags = reg->flags;

		combine_flags(&new_flags, src);

		if (!valid_flags(instr, n, new_flags)) {
			/* See if lowering an immediate to const would help. */
			if (valid_flags(instr, n, (new_flags & ~IR3_REG_IMMED) | IR3_REG_CONST)) {
				debug_assert(new_flags & IR3_REG_IMMED);
				instr->regs[n + 1] = lower_immed(ctx, src_reg, new_flags);
				return;
			}

			/* special case for "normal" mad instructions, we can
			 * try swapping the first two args if that fits better.
			 *
			 * the "plain" MAD's (ie. the ones that don't shift first
			 * src prior to multiply) can swap their first two srcs if
			 * src[0] is !CONST and src[1] is CONST:
			 */
			if ((n == 1) && is_mad(instr->opc) &&
					!(instr->regs[0 + 1]->flags & (IR3_REG_CONST | IR3_REG_RELATIV)) &&
					valid_flags(instr, 0, new_flags)) {
				/* swap src[0] and src[1]: */
				struct ir3_register *tmp;
				tmp = instr->regs[0 + 1];
				instr->regs[0 + 1] = instr->regs[1 + 1];
				instr->regs[1 + 1] = tmp;
				n = 0;
			} else {
				return;
			}
		}

		/* Here we handle the special case of mov from
		 * CONST and/or RELATIV.  These need to be handled
		 * specially, because in the case of move from CONST
		 * there is no src ir3_instruction so we need to
		 * replace the ir3_register.  And in the case of
		 * RELATIV we need to handle the address register
		 * dependency.
		 */
		if (src_reg->flags & IR3_REG_CONST) {
			/* an instruction cannot reference two different
			 * address registers:
			 */
			if ((src_reg->flags & IR3_REG_RELATIV) &&
					conflicts(instr->address, reg->instr->address))
				return;

			/* This seems to be a hw bug, or something where the timings
			 * just somehow don't work out.  This restriction may only
			 * apply if the first src is also CONST.
			 */
			if ((opc_cat(instr->opc) == 3) && (n == 2) &&
					(src_reg->flags & IR3_REG_RELATIV) &&
					(src_reg->array.offset == 0))
				return;

			src_reg = ir3_reg_clone(instr->block->shader, src_reg);
			src_reg->flags = new_flags;
			instr->regs[n+1] = src_reg;

			if (src_reg->flags & IR3_REG_RELATIV)
				ir3_instr_set_address(instr, reg->instr->address);

			return;
		}

		if ((src_reg->flags & IR3_REG_RELATIV) &&
				!conflicts(instr->address, reg->instr->address)) {
			src_reg = ir3_reg_clone(instr->block->shader, src_reg);
			src_reg->flags = new_flags;
			instr->regs[n+1] = src_reg;
			ir3_instr_set_address(instr, reg->instr->address);

			return;
		}

		/* NOTE: seems we can only do immed integers, so don't
		 * need to care about float.  But we do need to handle
		 * abs/neg *before* checking that the immediate requires
		 * few enough bits to encode:
		 *
		 * TODO: do we need to do something to avoid accidentally
		 * catching a float immed?
		 */
		if (src_reg->flags & IR3_REG_IMMED) {
			int32_t iim_val = src_reg->iim_val;

			debug_assert((opc_cat(instr->opc) == 1) ||
					(opc_cat(instr->opc) == 6) ||
					ir3_cat2_int(instr->opc));

			if (new_flags & IR3_REG_SABS)
				iim_val = abs(iim_val);

			if (new_flags & IR3_REG_SNEG)
				iim_val = -iim_val;

			if (new_flags & IR3_REG_BNOT)
				iim_val = ~iim_val;

			/* other than category 1 (mov) we can only encode up to 10 bits: */
			if ((instr->opc == OPC_MOV) ||
					!((iim_val & ~0x3ff) && (-iim_val & ~0x3ff))) {
				new_flags &= ~(IR3_REG_SABS | IR3_REG_SNEG | IR3_REG_BNOT);
				src_reg = ir3_reg_clone(instr->block->shader, src_reg);
				src_reg->flags = new_flags;
				src_reg->iim_val = iim_val;
				instr->regs[n+1] = src_reg;
			} else if (valid_flags(instr, n, (new_flags & ~IR3_REG_IMMED) | IR3_REG_CONST)) {
				/* See if lowering an immediate to const would help. */
				instr->regs[n+1] = lower_immed(ctx, src_reg, new_flags);
			}

			return;
		}
	}
}
예제 #13
0
string getDBStructure()
{
	return "----------------------------------------------------------------------\n\
--\n\
--	MOPSLinux package system\n\
--	Database creation script\n\
--	$Id: dbstruct.cpp,v 1.3 2007/11/02 20:19:45 i27249 Exp $\n\
--\n\
----------------------------------------------------------------------\n\
\n\
create table packages (\n\
	package_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	package_name TEXT NOT NULL,\n\
	package_version TEXT NOT NULL,\n\
	package_arch TEXT NOT NULL,\n\
	package_build TEXT NULL,\n\
	package_compressed_size TEXT NOT NULL,\n\
	package_installed_size TEXT NOT NULL,\n\
	package_short_description TEXT NULL,\n\
	package_description TEXT NULL, \n\
	package_changelog TEXT NULL,\n\
	package_packager TEXT NULL,\n\
	package_packager_email TEXT NULL,\n\
	package_installed INTEGER NOT NULL,\n\
	package_configexist INTEGER NOT NULL,\n\
	package_action INTEGER NOT NULL,\n\
	package_md5 TEXT NOT NULL,\n\
	package_filename TEXT NOT NULL,\n\
	package_betarelease TEXT NOT NULL,\n\
	package_installed_by_dependency INTEGER NOT NULL DEFAULT '0',\n\
	package_type INTEGER NOT NULL DEFAULT '0'\n\
);\n\
create index ppname on packages (package_id, package_name, package_version, package_action, package_installed, package_md5);\n\
\n\
create table files (\n\
	file_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	file_name TEXT NOT NULL,\n\
	file_type INTEGER NOT NULL,\n\
	packages_package_id INTEGER NOT NULL\n\
);\n\
create index pname on files (file_name, packages_package_id);\n\
\n\
create table conflicts (\n\
	conflict_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	conflict_file_name TEXT NOT NULL,\n\
	backup_file TEXT NOT NULL,\n\
	conflicted_package_id INTEGER NOT NULL\n\
);\n\
\n\
create table locations (\n\
	location_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	packages_package_id INTEGER NOT NULL,\n\
	server_url TEXT NOT NULL,\n\
	location_path TEXT NOT NULL\n\
);\n\
create index locpid on locations(packages_package_id, location_path, server_url);\n\
create table tags (\n\
	tags_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	tags_name TEXT NOT NULL\n\
);\n\
create index ptag on tags (tags_id, tags_name);\n\
\n\
create table tags_links (\n\
	tags_link_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	packages_package_id INTEGER NOT NULL,\n\
	tags_tag_id INTEGER NOT NULL\n\
);\n\
create index ptaglink on tags_links (packages_package_id, tags_tag_id);\n\
\n\
create table dependencies (\n\
	dependency_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
	packages_package_id INTEGER NOT NULL,\n\
	dependency_condition INTEGER NOT NULL DEFAULT '1',\n\
	dependency_type INTEGER NOT NULL DEFAULT '1',\n\
	dependency_package_name TEXT NOT NULL,\n\
	dependency_package_version TEXT NULL,\n\
	dependency_build_only INTEGER NOT NULL DEFAULT '0' \
);\n\
\n\
create index pdeps on dependencies (packages_package_id, dependency_id, dependency_package_name, dependency_package_version, dependency_condition);\n\
\n\
-- INTERNATIONAL SUPPORT\n\
\n\
--create table descriptions (\n\
--	description_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
--	packages_package_id INTEGER NOT NULL,\n\
--	description_language TEXT NOT NULL,\n\
--	description_text TEXT NOT NULL,\n\
--	short_description_text TEXT NOT NULL\n\
--);\n\
\n\
--create table changelogs (\n\
--	changelog_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
--	packages_package_id INTEGER NOT NULL,\n\
--	changelog_language TEXT NOT NULL,\n\
--	changelog_text TEXT NOT NULL\n\
--);\n\
\n\
-- RATING SYSTEM - SUPPORT FOR FUTURE\n\
--create table ratings (\n\
--	rating_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,\n\
--	rating_value INTEGER NOT NULL,\n\
--	packages_package_name TEXT NOT NULL\n\
--);\n\
";
}
예제 #14
0
파일: ir3_group.c 프로젝트: chemecse/mesa
static void
group_n(struct group_ops *ops, void *arr, unsigned n)
{
	unsigned i, j;

	/* first pass, figure out what has conflicts and needs a mov
	 * inserted.  Do this up front, before starting to setup
	 * left/right neighbor pointers.  Trying to do it in a single
	 * pass could result in a situation where we can't even setup
	 * the mov's right neighbor ptr if the next instr also needs
	 * a mov.
	 */
restart:
	for (i = 0; i < n; i++) {
		struct ir3_instruction *instr = ops->get(arr, i);
		if (instr) {
			struct ir3_instruction *left = (i > 0) ? ops->get(arr, i - 1) : NULL;
			struct ir3_instruction *right = (i < (n-1)) ? ops->get(arr, i + 1) : NULL;
			bool conflict;

			/* check for left/right neighbor conflicts: */
			conflict = conflicts(instr->cp.left, left) ||
				conflicts(instr->cp.right, right);

			/* Mixing array elements and higher register classes
			 * (ie. groups) doesn't really work out in RA.  See:
			 *
			 * https://trello.com/c/DqeDkeVf/156-bug-with-stk-70frag
			 */
			if (instr->regs[0]->flags & IR3_REG_ARRAY)
				conflict = true;

			/* we also can't have an instr twice in the group: */
			for (j = i + 1; (j < n) && !conflict; j++)
				if (in_neighbor_list(ops->get(arr, j), instr, i))
					conflict = true;

			if (conflict) {
				ops->insert_mov(arr, i, instr);
				/* inserting the mov may have caused a conflict
				 * against the previous:
				 */
				goto restart;
			}
		}
	}

	/* second pass, now that we've inserted mov's, fixup left/right
	 * neighbors.  This is guaranteed to succeed, since by definition
	 * the newly inserted mov's cannot conflict with anything.
	 */
	for (i = 0; i < n; i++) {
		struct ir3_instruction *instr = ops->get(arr, i);
		if (instr) {
			struct ir3_instruction *left = (i > 0) ? ops->get(arr, i - 1) : NULL;
			struct ir3_instruction *right = (i < (n-1)) ? ops->get(arr, i + 1) : NULL;

			debug_assert(!conflicts(instr->cp.left, left));
			if (left) {
				instr->cp.left_cnt++;
				instr->cp.left = left;
			}

			debug_assert(!conflicts(instr->cp.right, right));
			if (right) {
				instr->cp.right_cnt++;
				instr->cp.right = right;
			}
		}
	}
}
예제 #15
0
bool manager::conflicts(const elem& elem1, const elem& elem2, bool directonly) const
{
	if (elem1 == elem2) {
		return false;
	}

	// We ignore inexistent elements at this point, they will generate
	// errors in change_era()/change_scenario() anyways.
	if (!exists(elem1) || !exists(elem2)) {
		return false;
	}

	config data1 = depinfo_.find_child(elem1.type, "id", elem1.id);
	config data2 = depinfo_.find_child(elem2.type, "id", elem2.id);

	// Whether we should skip the check entirely
	if (data1.has_attribute("ignore_incompatible_" + elem2.type)) {
		std::vector<std::string> ignored =
						utils::split(data1["ignore_incompatible_" + elem2.type]);

		if ( util::contains(ignored, elem2.id) ) {
			return false;
		}
	}

	if (data2.has_attribute("ignore_incompatible_" + elem1.type)) {
		std::vector<std::string> ignored =
						utils::split(data2["ignore_incompatible_" + elem1.type]);

		if ( util::contains(ignored, elem1.id) ) {
			return false;
		}
	}

	bool result = false;

	// Checking for direct conflicts between elem1 and elem2
	if (data1.has_attribute("allow_" + elem2.type)) {
		std::vector<std::string> allowed =
						utils::split(data1["allow_" + elem2.type]);

		result = !util::contains(allowed, elem2.id) && !requires(elem1, elem2);
	} else if (data1.has_attribute("disallow_" + elem2.type)) {
		std::vector<std::string> disallowed =
						utils::split(data1["disallow_" + elem2.type]);

		result = util::contains(disallowed, elem2.id);
	}

	if (data2.has_attribute("allow_" + elem1.type)) {
		std::vector<std::string> allowed =
						utils::split(data2["allow_" + elem1.type]);

		result = result || (!util::contains(allowed, elem1.id) && !requires(elem2, elem1));
	} else if (data2.has_attribute("disallow_" + elem1.type)) {
		std::vector<std::string> disallowed =
						utils::split(data2["disallow_" + elem1.type]);

		result = result || util::contains(disallowed, elem1.id);
	}

	if (result) {
		return true;
	}

	// Checking for indirect conflicts (i.e. conflicts between dependencies)
	if (!directonly) {
		std::vector<std::string>	req1 = get_required(elem1),
									req2 = get_required(elem2);

		BOOST_FOREACH (const std::string& s, req1) {
			elem m(s, "modification");

			if (conflicts(elem2, m, true)) {
				return true;
			}
		}
예제 #16
0
파일: ir3_group.c 프로젝트: Distrotech/Mesa
static void
group_n(struct group_ops *ops, void *arr, unsigned n)
{
	unsigned i, j;

	/* first pass, figure out what has conflicts and needs a mov
	 * inserted.  Do this up front, before starting to setup
	 * left/right neighbor pointers.  Trying to do it in a single
	 * pass could result in a situation where we can't even setup
	 * the mov's right neighbor ptr if the next instr also needs
	 * a mov.
	 */
restart:
	for (i = 0; i < n; i++) {
		struct ir3_instruction *instr = ops->get(arr, i);
		if (instr) {
			struct ir3_instruction *left = (i > 0) ? ops->get(arr, i - 1) : NULL;
			struct ir3_instruction *right = (i < (n-1)) ? ops->get(arr, i + 1) : NULL;
			bool conflict;

			/* check for left/right neighbor conflicts: */
			conflict = conflicts(instr->cp.left, left) ||
				conflicts(instr->cp.right, right);

			/* RA can't yet deal very well w/ group'd phi's: */
			if (is_meta(instr) && (instr->opc == OPC_META_PHI))
				conflict = true;

			/* we also can't have an instr twice in the group: */
			for (j = i + 1; (j < n) && !conflict; j++)
				if (ops->get(arr, j) == instr)
					conflict = true;

			if (conflict) {
				ops->insert_mov(arr, i, instr);
				/* inserting the mov may have caused a conflict
				 * against the previous:
				 */
				goto restart;
			}
		}
	}

	/* second pass, now that we've inserted mov's, fixup left/right
	 * neighbors.  This is guaranteed to succeed, since by definition
	 * the newly inserted mov's cannot conflict with anything.
	 */
	for (i = 0; i < n; i++) {
		struct ir3_instruction *instr = ops->get(arr, i);
		if (instr) {
			struct ir3_instruction *left = (i > 0) ? ops->get(arr, i - 1) : NULL;
			struct ir3_instruction *right = (i < (n-1)) ? ops->get(arr, i + 1) : NULL;

			debug_assert(!conflicts(instr->cp.left, left));
			if (left) {
				instr->cp.left_cnt++;
				instr->cp.left = left;
			}

			debug_assert(!conflicts(instr->cp.right, right));
			if (right) {
				instr->cp.right_cnt++;
				instr->cp.right = right;
			}
		}
	}
}
예제 #17
0
    LockResult LockManager::lock(const ResourceId& resId, LockRequest* request, LockMode mode) {
        dassert(mode > MODE_NONE);

        // Fast path for acquiring the same lock multiple times in modes, which are already covered
        // by the current mode. It is safe to do this without locking, because 1) all calls for the
        // same lock request must be done on the same thread and 2) if there are lock requests
        // hanging off a given LockHead, then this lock will never disappear.
        if ((LockConflictsTable[request->mode] | LockConflictsTable[mode]) == 
                LockConflictsTable[request->mode]) {
            request->recursiveCount++;
            return LOCK_OK;
        }

        // TODO: For the time being we do not need conversions between unrelated lock modes (i.e.,
        // modes which both add and remove to the conflicts set), so these are not implemented yet
        // (e.g., S -> IX).
        invariant((LockConflictsTable[request->mode] | LockConflictsTable[mode]) == 
                LockConflictsTable[mode]);

        LockBucket* bucket = _getBucket(resId);
        scoped_spinlock scopedLock(bucket->mutex);

        LockHead* lock;

        LockHeadMap::iterator it = bucket->data.find(resId);
        if (it == bucket->data.end()) {
            // Lock is free (not on the map)
            invariant(request->status == LockRequest::STATUS_NEW);

            lock = new LockHead(resId);
            bucket->data.insert(LockHeadPair(resId, lock));
        }
        else {
            // Lock is not free
            lock = it->second;
        }

        // Sanity check if requests are being reused
        invariant(request->lock == NULL || request->lock == lock);

        request->lock = lock;
        request->recursiveCount++;

        if (request->status == LockRequest::STATUS_NEW) {
            invariant(request->recursiveCount == 1);

            // New lock request
            if (conflicts(mode, lock->grantedModes)) {
                request->status = LockRequest::STATUS_WAITING;
                request->mode = mode;
                request->convertMode = MODE_NONE;

                // Put it on the conflict queue. This is the place where various policies could be
                // applied for where in the wait queue does a request go.
                lock->addToConflictQueue(request);
                lock->changeConflictModeCount(mode, LockHead::Increment);

                return LOCK_WAITING;
            }
            else {  // No conflict, new request
                request->status = LockRequest::STATUS_GRANTED;
                request->mode = mode;
                request->convertMode = MODE_NONE;

                lock->addToGrantedQueue(request);
                lock->changeGrantedModeCount(mode, LockHead::Increment);

                return LOCK_OK;
            }
        }
        else {
            // If we are here, we already hold the lock in some mode. In order to keep it simple,
            // we do not allow requesting a conversion while a lock is already waiting or pending
            // conversion, hence the assertion below.
            invariant(request->status == LockRequest::STATUS_GRANTED);
            invariant(request->recursiveCount > 1);
            invariant(request->mode != mode);

            // Construct granted mask without our current mode, so that it is not counted as
            // conflicting
            uint32_t grantedModesWithoutCurrentRequest = 0;

            // We start the counting at 1 below, because LockModesCount also includes MODE_NONE
            // at position 0, which can never be acquired/granted.
            for (uint32_t i = 1; i < LockModesCount; i++) {
                const uint32_t currentRequestHolds =
                                    (request->mode == static_cast<LockMode>(i) ? 1 : 0);

                if (lock->grantedCounts[i] > currentRequestHolds) {
                    grantedModesWithoutCurrentRequest |= modeMask(static_cast<LockMode>(i));
                }
            }

            // This check favours conversion requests over pending requests. For example:
            //
            // T1 requests lock L in IS
            // T2 requests lock L in X
            // T1 then upgrades L from IS -> S
            //
            // Because the check does not look into the conflict modes bitmap, it will grant L to
            // T1 in S mode, instead of block, which would otherwise cause deadlock.
            if (conflicts(mode, grantedModesWithoutCurrentRequest)) {
                request->status = LockRequest::STATUS_CONVERTING;
                request->convertMode = mode;

                lock->conversionsCount++;
                lock->changeGrantedModeCount(request->convertMode, LockHead::Increment);

                return LOCK_WAITING;
            }
            else {  // No conflict, existing request
                lock->changeGrantedModeCount(mode, LockHead::Increment);
                lock->changeGrantedModeCount(request->mode, LockHead::Decrement);
                request->mode = mode;

                return LOCK_OK;
            }
        }
    }
예제 #18
0
    void LockManager::_onLockModeChanged(LockHead* lock, bool checkConflictQueue) {
        // Unblock any converting requests (because conversions are still counted as granted and
        // are on the granted queue).
        for (LockRequest* iter = lock->grantedQueue;
            (iter != NULL) && (lock->conversionsCount > 0);
            iter = iter->next) {

            // Conversion requests are going in a separate queue
            if (iter->status == LockRequest::STATUS_CONVERTING) {
                invariant(iter->convertMode != 0);

                // Construct granted mask without our current mode, so that it is not accounted as
                // a conflict
                uint32_t grantedModesWithoutCurrentRequest = 0;

                // We start the counting at 1 below, because LockModesCount also includes
                // MODE_NONE at position 0, which can never be acquired/granted.
                for (uint32_t i = 1; i < LockModesCount; i++) {
                    const uint32_t currentRequestHolds =
                        (iter->mode == static_cast<LockMode>(i) ? 1 : 0);

                    const uint32_t currentRequestWaits = 
                        (iter->convertMode == static_cast<LockMode>(i) ? 1 : 0);

                    // We cannot both hold and wait on the same lock mode
                    invariant(currentRequestHolds + currentRequestWaits <= 1);

                    if (lock->grantedCounts[i] > (currentRequestHolds + currentRequestWaits)) {
                        grantedModesWithoutCurrentRequest |= modeMask(static_cast<LockMode>(i));
                    }
                }

                if (!conflicts(iter->convertMode, grantedModesWithoutCurrentRequest)) {
                    lock->conversionsCount--;
                    lock->changeGrantedModeCount(iter->mode, LockHead::Decrement);
                    iter->status = LockRequest::STATUS_GRANTED;
                    iter->mode = iter->convertMode;
                    iter->convertMode = MODE_NONE;

                    iter->notify->notify(lock->resourceId, LOCK_OK);
                }
            }
        }

        // Grant any conflicting requests, which might now be unblocked
        LockRequest* iterNext = NULL;

        for (LockRequest* iter = lock->conflictQueueBegin;
             (iter != NULL) && checkConflictQueue;
             iter = iterNext) {

            invariant(iter->status == LockRequest::STATUS_WAITING);

            // Store the actual next pointer, because we muck with the iter below and move it to
            // the granted queue.
            iterNext = iter->next;

            if (conflicts(iter->mode, lock->grantedModes)) continue;

            iter->status = LockRequest::STATUS_GRANTED;

            lock->removeFromConflictQueue(iter);
            lock->addToGrantedQueue(iter);

            lock->changeGrantedModeCount(iter->mode, LockHead::Increment);
            lock->changeConflictModeCount(iter->mode, LockHead::Decrement);

            iter->notify->notify(lock->resourceId, LOCK_OK);
        }

        // This is a convenient place to check that the state of the two request queues is in sync
        // with the bitmask on the modes.
        invariant((lock->grantedModes == 0) ^ (lock->grantedQueue != NULL));
        invariant((lock->conflictModes == 0) ^ (lock->conflictQueueBegin != NULL));
    }
예제 #19
0
    void DeadlockDetector::_processNextNode(const UnprocessedNode& node) {
        // Locate the request
        LockManager::LockBucket* bucket = _lockMgr._getBucket(node.resId);
        SimpleMutex::scoped_lock scopedLock(bucket->mutex);

        LockManager::LockHeadMap::const_iterator iter = bucket->data.find(node.resId);
        if (iter == bucket->data.end()) {
            return;
        }

        const LockHead* lock = iter->second;

        LockRequest* request = lock->findRequest(node.lockerId);

        // It is possible that a request which was thought to be waiting suddenly became
        // granted, so check that before proceeding
        if (!request || (request->status == LockRequest::STATUS_GRANTED)) {
            return;
        }

        std::pair<WaitForGraph::iterator, bool> val =
            _graph.insert(WaitForGraphPair(node.lockerId, Edges(node.resId)));
        if (!val.second) {
            // We already saw this locker id, which means we have a cycle.
            if (!_foundCycle) {
                _foundCycle = (node.lockerId == _initialLockerId);
            }

            return;
        }

        Edges& edges = val.first->second;

        bool seen = false;
        for (LockRequest* it = lock->grantedQueueEnd; it != NULL; it = it->prev) {
            // We can't conflict with ourselves
            if (it == request) {
                seen = true;
                continue;
            }

            // If we are a regular conflicting request, both granted and conversion modes need to
            // be checked for conflict, since conversions will be granted first.
            if (request->status == LockRequest::STATUS_WAITING) {
                if (conflicts(request->mode, modeMask(it->mode)) ||
                    conflicts(request->mode, modeMask(it->convertMode))) {

                    const LockerId lockerId = it->locker->getId();
                    const ResourceId waitResId = it->locker->getWaitingResource();

                    if (waitResId.isValid()) {
                        _queue.push_front(UnprocessedNode(lockerId, waitResId));
                        edges.owners.push_back(lockerId);
                    }
                }

                continue;
            }

            // If we are a conversion request, only requests, which are before us need to be
            // accounted for.
            invariant(request->status == LockRequest::STATUS_CONVERTING);

            if (conflicts(request->convertMode, modeMask(it->mode)) ||
                (seen && conflicts(request->convertMode, modeMask(it->convertMode)))) {

                const LockerId lockerId = it->locker->getId();
                const ResourceId waitResId = it->locker->getWaitingResource();

                if (waitResId.isValid()) {
                    _queue.push_front(UnprocessedNode(lockerId, waitResId));
                    edges.owners.push_back(lockerId);
                }
            }
        }

        // All conflicting waits, which would be granted before us
        for (LockRequest* it = request->prev;
             (request->status == LockRequest::STATUS_WAITING) &&  (it != NULL);
             it = it->prev) {

            // We started from the previous element, so we should never see ourselves
            invariant(it != request);

            if (conflicts(request->mode, modeMask(it->mode))) {
                const LockerId lockerId = it->locker->getId();
                const ResourceId waitResId = it->locker->getWaitingResource();

                if (waitResId.isValid()) {
                    _queue.push_front(UnprocessedNode(lockerId, waitResId));
                    edges.owners.push_back(lockerId);
                }
            }
        }
    }