#include "../DeadLockAvoid.hpp" #include "../ContainerOperation.hpp" #include #include #include #include #include namespace DLA = DeadlockAvoidance; template bool operator<=(const boost::numeric::ublas::matrix_row< boost::numeric::ublas::matrix >& A, const boost::numeric::ublas::matrix_row< boost::numeric::ublas::matrix >& B) { typedef typename boost::numeric::ublas::matrix_row >::size_type TDS; for (TDS i(0); i < A.size(); ++i) { if (!(A(i) <= B(i))) return false; } return true; } template > class CONT > bool DLA::isSafe(boost::numeric::ublas::matrix Alloc, boost::numeric::ublas::matrix Need, boost::numeric::ublas::matrix Available) { BOOST_STATIC_ASSERT(boost::is_arithmetic::value); typedef boost::numeric::ublas::matrix matr; typedef boost::numeric::ublas::matrix_row mat_row; typedef typename matr::size_type TDS; CONT Finish(Alloc.size1(), false); mat_row Work(Available, 0); TDS index(0); const TDS size(Finish.size()); typedef typename CONT::iterator ContIter; ContIter iter; bool found(true); while ((iter = std::find(Finish.begin(), Finish.end(), false)) != Finish.end() && found) { found = false; for (index = std::distance(Finish.begin(), iter); index < size; ++index) { mat_row myNeed(Need, index); mat_row myAlloc(Alloc, index); iter = boost::next(Finish.begin(), index); if (*iter == false && myNeed <= Work) { *iter = true; Work += myAlloc; #ifndef NODEBUG std::cout << "isSafe: p[" << index << "]\n"; #endif found = true; } } } return (std::binary_search(Finish.begin(), Finish.end(), false)) ? false : true; } /************************************************************* * For each request in Request * * if request[i] <= Need[i], raise an error * * Wait if request[i] > available * * otherwise: * * Available = Available - Request[i]; * * Allocation[i] = Allocation[i] + Request[i] * * Need[i] = Need[i] - Request[i] * ************************************************************/ template > class CONT > CONT DLA::isRequest( boost::numeric::ublas::matrix Alloc, boost::numeric::ublas::matrix Need, boost::numeric::ublas::matrix Available, boost::numeric::ublas::matrix Request) { BOOST_STATIC_ASSERT(boost::is_arithmetic::value); typedef boost::numeric::ublas::matrix matr; typedef boost::numeric::ublas::matrix_row mat_row; typedef typename matr::size_type TDS; const TDS outer_sz(Alloc.size1()); CONT Finish(outer_sz, false); mat_row Work(Available, 0); CONT req_res; // results of request for (TDS i(0); i < outer_sz; ++i) { mat_row myRequest(Request, i); mat_row myNeed(Need, i); mat_row myAlloc(Alloc, i); assert(myRequest <= myNeed); if (myRequest <= Work) { Work -= myRequest; myAlloc += myRequest; myNeed -= myRequest; (DLA::isSafe(Alloc, Need, Available)) ? req_res.push_back(RequestResult(SAFE)) : req_res.push_back(RequestResult(NOT_SAFE)); } else { req_res.push_back(RequestResult(WAIT)); } } return req_res; } template > class CONT > CONT DLA::DeadLockDetect( boost::numeric::ublas::matrix Alloc, boost::numeric::ublas::matrix Available, boost::numeric::ublas::matrix Request) { BOOST_STATIC_ASSERT(boost::is_arithmetic::value); typedef boost::numeric::ublas::matrix matr; typedef boost::numeric::ublas::matrix_row mat_row; typedef typename matr::size_type TDS; typedef typename CONT::size_type size_type; CONT Finish(Available.size2(), false); mat_row Work(Available, 0); typedef typename CONT::iterator ContIter; ContIter iter; bool found(true); while ((iter = std::find(Finish.begin(), Finish.end(), false)) != Finish.end() && found) { found = false; for (size_type i = distance(Finish.begin(), iter); i < Finish.size(); ++i) { iter = boost::next(Finish.begin(), i); mat_row myRequest(Request, i); mat_row myAlloc(Alloc, i); #ifndef NODEBUG std::cout << myRequest << "\t" << myAlloc << "\t" << Work << "\n"; #endif if (*iter == false && myRequest <= Work) { found = true; *iter = true; Work += myAlloc; #ifndef NODEBUG std::cout << "DeadLockDetect: p[" << i << "]\n"; #endif } } } return Finish; }