//////////////////////////////////////////////////////////////////////////////

//

// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost

// Software License, Version 1.0. (See accompanying file

// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

//

// See http://www.boost.org/libs/interprocess for documentation.

//

//////////////////////////////////////////////////////////////////////////////



#include <boost/interprocess/detail/posix_time_types_wrk.hpp>



namespace boost {



namespace interprocess {



inline interprocess_mutex::interprocess_mutex() 

   : m_s(0) 

{

   //Note that this class is initialized to zero.

   //So zeroed memory can be interpreted as an

   //initialized mutex

}



inline interprocess_mutex::~interprocess_mutex() 

{

   //Trivial destructor

}



inline void interprocess_mutex::lock(void)

{

   do{

      boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0);



      if (m_s == 1 && prev_s == 0){

            break;

      }

      // relinquish current timeslice

      detail::thread_yield();

   }while (true);

}



inline bool interprocess_mutex::try_lock(void)

{

   boost::uint32_t prev_s = detail::atomic_cas32((boost::uint32_t*)&m_s, 1, 0);   

   return m_s == 1 && prev_s == 0;

}



inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time)

{

   //Obtain current count and target time

   boost::posix_time::ptime now = microsec_clock::universal_time();



   if(now >= abs_time) return false;



   do{

      if(this->try_lock()){

         break;

      }

      now = microsec_clock::universal_time();



      if(now >= abs_time){

         return false;

      }

      // relinquish current time slice

     detail::thread_yield();

   }while (true);



   return true;

}



inline void interprocess_mutex::unlock(void)

{  detail::atomic_cas32((boost::uint32_t*)&m_s, 0, 1);   }



}  //namespace interprocess {



}  //namespace boost {

