[interprocess] problem in boost/interprocess/detail/atomic.hpp

I ran across this bug while running on a 2.6.9 Linux kernel. Since that kernel version doesn't have native interprocess mutexes and condition variables the interprocess library uses some emulation code. The x86 verion of the emulated semaphore uses atomic_dec32() from atomic.hpp but that function wasn't behaving properly. The following change in oost/interprocess/detail/atomic.hpp made things work properly: BEFORE: inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) { unsigned char prev; asm volatile ("lock; decl %1;\n\t" "setnz %%al" : "=a" (prev) : "m" (*(mem)) : "memory", "cc"); return prev; } AFTER: inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) { boost::uint32_t prev; // acts like an atomic 'return (*mem)--;' asm volatile ("movl $-1, %0;\n\t" "lock; xaddl %0, %1" : "=r" (prev) : "m" (*(mem)) : "memory", "cc" ); return prev; } -glenn

Hi Glenn, Glenn Schrader wrote:
Thanks for the change. However, I'm pretty sure that Linux has process-shared mutexes and condition variables. This might be a bug from the last version. Can you check against the CVS code? I will apply your patch ASAP to CVS. This really shows that atomic functions in hands of non expert people like me are really dangerous! Let's hope we can see soon an atomic operations library in Boost. Regards, Ion

Hello Ion, Ion Gaztañaga wrote:
Since interprocess isn't in the official tarball yet i've been working with the head version from CVS. Whether or not emulation is used is determined by the value in _POSIX_THREAD_PROCESS_SHARED. In a 2.6.17 kernel that I'm running on another system the value is 200112L so indeed the native mutexes and condition variables are used. The system that I was having a problem with has a 2.6.9 kernel and the _POSIX_THREAD_PROCESS_SHARED value of -1; corresponding to "not supported".
No problem and and thanks! -glenn

Ion Gaztañaga wrote:
Hey Ion, I am getting seg faults running the following interprocess code using the latest boost cvs distro. Conditions work properly using the old shmem libs but I think something must have changed since then to cause this. The seg fault happens in the atomic function atomic_dec32. I'm running kernel 2.6.9-42 if that helps. If I'm doing something wrong here, please let me know but this has worked in the past. Thanks, Harold //client code follows... #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/sync/mutex_family.hpp> #include <boost/interprocess/sync/scoped_lock.hpp> #include <boost/interprocess/sync/interprocess_condition.hpp> using namespace boost::interprocess; class MyClass { public: interprocess_condition sent_condition; interprocess_condition received_condition; interprocess_mutex mutex; }; int main () { managed_shared_memory* psegment = new managed_shared_memory( open_or_create, "MySharedMemory", //segment name 256000000); //segment size in bytes MyClass *instance = psegment->find_or_construct<MyClass> ("MyClass") /*name of the object*/ (); scoped_lock<mutex_family::mutex_type> lock(instance->mutex); std::cout << "Waiting on Server..." << std::endl; instance->sent_condition.wait(lock); instance->received_condition.notify_all(); return 0; } //server code follows... #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/sync/mutex_family.hpp> #include <boost/interprocess/sync/scoped_lock.hpp> #include <boost/interprocess/sync/interprocess_condition.hpp> using namespace boost::interprocess; class MyClass { public: interprocess_condition sent_condition; interprocess_condition received_condition; interprocess_mutex mutex; }; int main () { managed_shared_memory* psegment = new managed_shared_memory( open_or_create, "MySharedMemory", //segment name 256000000); //segment size in bytes MyClass *instance = psegment->find_or_construct<MyClass> ("MyClass") /*name of the object*/ (); instance->sent_condition.notify_all(); scoped_lock<mutex_family::mutex_type> lock(instance->mutex); std::cout << "Waiting on Client..." << std::endl; instance->received_condition.wait(lock); psegment->destroy<MyClass>("MyClass"); shared_memory_object::remove("MySharedMemory"); return 0; }
participants (3)
-
Glenn Schrader
-
Harold Pirtle
-
Ion Gaztañaga