Boost logo

Boost Users :

Subject: Re: [Boost-users] [Interprocess] updating elements in vector of maps fails in optimized code
From: Steven Maenhout (Steven.Maenhout_at_[hidden])
Date: 2011-05-12 06:23:55


> Please try latest trunk code

I just tried the latest trunk code and I'm sorry to report that the GCC
specific attribute does not solve all problems. The crashes or
indefinite waits have been resolved though.

I also noticed that the described symptoms are not merely a result of
compiler optimizations. I was experimenting with different GCC
optimization parameters in an attempt to identify the guilty ones when I
noticed that even when optimizations are completely turned off, some
weird behavior "can" occur. When I run the snippet provided below,
compiled with -O0, several times, the program behaves as expected about
half of the times and in the other runs, the map find function will fail
to find any entries, resulting in a matrix consisting of ones instead of
twos. In higher optimization levels, the find function fails consistently.

Does the snippet always work for MSVC?

kind regards,

Steven

#include <iostream>
#include <stdexcept>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

#define MATSIZE 5

typedef boost::interprocess::managed_shared_memory::segment_manager
SegmentManager_t;
typedef boost::interprocess::allocator<void , SegmentManager_t>
VoidAllocator_t;
typedef std::pair<int,double> MapValue_t;
typedef boost::interprocess::allocator<MapValue_t , SegmentManager_t>
MapValueAllocator_t;
typedef
boost::interprocess::map<int,double,std::less<int>,MapValueAllocator_t>
Map_t;
typedef boost::interprocess::allocator<Map_t,SegmentManager_t>
MapAllocator_t;
typedef boost::interprocess::vector<Map_t,MapAllocator_t> VectorofMaps_t;

int main(int argc, char **argv)
{
   VectorofMaps_t::size_type i;
   int j;
   Map_t::iterator mapiter;

   try
   {
 
boost::interprocess::shared_memory_object::remove("MySharedMemory");
     boost::interprocess::managed_shared_memory
mfile(boost::interprocess::create_only,"MySharedMemory",65536);
     VoidAllocator_t alloc_inst (mfile.get_segment_manager());
     VectorofMaps_t*
pS=mfile.construct<VectorofMaps_t>(boost::interprocess::anonymous_instance)(MATSIZE,Map_t(std::less<int>(),alloc_inst),alloc_inst);

     for(i=0;i<MATSIZE;++i)
     {
       for(j=0;j<MATSIZE;++j)
        (*pS)[i].insert(MapValue_t(j,1.0));
     }

     for(i=0;i<MATSIZE;++i)
     {
       for(j=0;j<MATSIZE;++j)
       {
        std::cout<<"looking for ("<<i<<","<<j<<") ";
         mapiter=(*pS)[i].find(j);
        if(mapiter!=(*pS)[i].end())
        {
          std::cout<<"found ("<<i<<","<<mapiter->first<<"), updating from
"<<mapiter->second<<" to ";
          mapiter->second+=1.0;
          std::cout<<mapiter->second<<std::endl;
        }
        else
          std::cout<<"not found"<<std::endl;
       }
     }

     for(i=0;i<MATSIZE;++i)
     {
       for(mapiter=(*pS)[i].begin();mapiter!=(*pS)[i].end();++mapiter)
 
std::cout<<"("<<i<<","<<mapiter->first<<")="<<mapiter->second<<" ";
        std::cout<<std::endl;
      }
      boost::interprocess::shared_memory_object::remove("MySharedMemory");
   }
   catch(boost::interprocess::interprocess_exception e)
   {
     std::cerr<<"Interprocess error: "<<e.what();
   }
   catch(std::exception e)
   {
     std::cerr<<"Standard exception: "<<e.what();
   }
   catch(...)
   {
     std::cerr<<"unknown error";
   }
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net