[complement-svn] SF.net SVN: complement: [1485] trunk/complement/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2007-01-30 15:06:45
|
Revision: 1485 http://svn.sourceforge.net/complement/?rev=1485&view=rev Author: complement Date: 2007-01-30 07:06:35 -0800 (Tue, 30 Jan 2007) Log Message: ----------- named object manager for shared memory segment Modified Paths: -------------- trunk/complement/explore/include/mt/shm.h trunk/complement/explore/lib/mt/ChangeLog trunk/complement/explore/test/mt/mt_test.cc trunk/complement/explore/test/mt/mt_test.h trunk/complement/explore/test/mt/mt_test_suite.cc Modified: trunk/complement/explore/include/mt/shm.h =================================================================== --- trunk/complement/explore/include/mt/shm.h 2007-01-30 15:04:59 UTC (rev 1484) +++ trunk/complement/explore/include/mt/shm.h 2007-01-30 15:06:35 UTC (rev 1485) @@ -1,7 +1,7 @@ -// -*- C++ -*- Time-stamp: <06/12/26 10:24:35 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 18:59:35 ptr> /* - * Copyright (c) 2006 + * Copyright (c) 2006, 2007 * Petr Ovtchenkov * * Licensed under the Academic Free License version 3.0 @@ -69,6 +69,30 @@ typedef typename std::__type_traits<T>::is_POD_type is_ipc_sharable; }; +template <> +struct ipc_sharable<xmt::__Condition<true> > +{ + typedef std::__true_type is_ipc_sharable; +}; + +template <> +struct ipc_sharable<xmt::__Semaphore<true> > +{ + typedef std::__true_type is_ipc_sharable; +}; + +template <> +struct ipc_sharable<xmt::__Mutex<false,true> > +{ + typedef std::__true_type is_ipc_sharable; +}; + +template <> +struct ipc_sharable<xmt::__Mutex<true,true> > +{ + typedef std::__true_type is_ipc_sharable; +}; + template <int _Inst> class shm_alloc; namespace detail { @@ -277,11 +301,11 @@ if ( _last == 255 ) { throw std::range_error( "too many named objects" ); } - if ( (reinterpret_cast<void *>(&obj) <= shm_alloc<_Inst>::_seg.address()) || - (reinterpret_cast<void *>(&obj) > (reinterpret_cast<char *>(shm_alloc<_Inst>::_seg.address()) + + if ( (reinterpret_cast<const void *>(&obj) <= shm_alloc<_Inst>::_seg.address()) || + (reinterpret_cast<const void *>(&obj) > (reinterpret_cast<char *>(shm_alloc<_Inst>::_seg.address()) + shm_alloc<_Inst>::max_size() + - sizeof(shm_alloc<_Inst>::_master) + - sizeof(shm_alloc<_Inst>::_aheader) )) ) { + sizeof(typename shm_alloc<_Inst>::_master) + + sizeof(typename shm_alloc<_Inst>::_aheader) )) ) { throw std::invalid_argument( std::string("object beyond this shared segment") ); } for ( int i = 0; _nm_table[i].name != -1; ++i ) { @@ -290,7 +314,7 @@ } } _nm_table[_last].name = name; - _nm_table[_last].offset = reinterpret_cast<char *>(&obj) - reinterpret_cast<char *>(shm_alloc<_Inst>::_seg.address()); + _nm_table[_last].offset = reinterpret_cast<const char *>(&obj) - reinterpret_cast<char *>(shm_alloc<_Inst>::_seg.address()); _nm_table[_last].count = 1; ++_last; } @@ -444,6 +468,23 @@ static size_type max_size() throw() { return _seg.max_size() == 0 ? 0 : (_seg.max_size() - sizeof(_master) - sizeof(_aheader)); } + static shm_name_mgr<_Inst>& name_mgr() + { + pointer p = _seg.address(); + if ( p != reinterpret_cast<pointer>(-1) ) { + _master *m = reinterpret_cast<_master *>( p ); + if ( m->_nm == 0 ) { + xmt::__Locker<xmt::__Mutex<false,true> > lk( m->_lock ); + void *nm = _traverse( &m->_first, sizeof(shm_name_mgr<_Inst>) ); + m->_nm = reinterpret_cast<char *>(nm) - reinterpret_cast<char *>(p); + return *new ( nm ) shm_name_mgr<_Inst>(); + } + return *reinterpret_cast<shm_name_mgr<_Inst> *>(reinterpret_cast<char *>(p) + m->_nm); + } + + throw shm_bad_alloc( -2 ); + } + protected: static void *allocate( size_type n, void *hint = 0 ) { Modified: trunk/complement/explore/lib/mt/ChangeLog =================================================================== --- trunk/complement/explore/lib/mt/ChangeLog 2007-01-30 15:04:59 UTC (rev 1484) +++ trunk/complement/explore/lib/mt/ChangeLog 2007-01-30 15:06:35 UTC (rev 1485) @@ -1,3 +1,11 @@ +2007-01-30 Petr Ovtchenkov <pt...@is...> + + * shm.h: add named objects manager in shared segment + memory allocator; + + * xmt.h, xmt.cc: unification Semaphore with Condition + and Mutex---ipc flag passed as template parameter. + 2006-12-26 Petr Ovtchenkov <pt...@is...> * shm.h, shm.cc: shared memory-based allocator Modified: trunk/complement/explore/test/mt/mt_test.cc =================================================================== --- trunk/complement/explore/test/mt/mt_test.cc 2007-01-30 15:04:59 UTC (rev 1484) +++ trunk/complement/explore/test/mt/mt_test.cc 2007-01-30 15:06:35 UTC (rev 1485) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/12/26 10:45:51 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 15:35:05 ptr> /* * Copyright (c) 2006 @@ -288,3 +288,137 @@ } } + +/* + * This test is similar mt_test::fork() above, but instead plain shm_* + * functions it use allocator based on shared memory segment + */ +void mt_test::fork_shm() +{ + const char fname[] = "/tmp/mt_test.shm"; + try { + xmt::shm_alloc<0> seg; + + seg.allocate( fname, 1024, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + xmt::allocator_shm<char,0> shm; + + xmt::__Condition<true>& fcnd = *new( shm.allocate( sizeof(xmt::__Condition<true>) ) ) xmt::__Condition<true>(); + fcnd.set( false ); + try { + xmt::fork(); + + try { + + // Child code + fcnd.try_wait(); + + } + catch ( ... ) { + } + + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + try { + BOOST_CHECK( child.pid() > 0 ); + + fcnd.set( true ); + + int stat; + BOOST_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + } + catch ( ... ) { + } + } + catch ( ... ) { + } + + (&fcnd)->~__Condition<true>(); + shm.deallocate( reinterpret_cast<char *>(&fcnd), sizeof(xmt::__Condition<true>) ); + seg.deallocate(); + fs::remove( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} + +/* + * Test: how to take named object + */ +void mt_test::shm_named_obj() +{ + const char fname[] = "/tmp/mt_test.shm"; + enum { + test_Condition_Object = 1 + }; + try { + xmt::shm_alloc<0> seg; + + seg.allocate( fname, 4*4096, xmt::shm_base::create | xmt::shm_base::exclusive, 0660 ); + xmt::shm_name_mgr<0>& nm = seg.name_mgr(); + + xmt::allocator_shm<xmt::__Condition<true>,0> shm; + + xmt::__Condition<true>& fcnd = *new ( shm.allocate( 1 ) ) xmt::__Condition<true>(); + nm.named( fcnd, test_Condition_Object ); + fcnd.set( false ); + + try { + xmt::fork(); + + try { + + // Child code + xmt::shm_alloc<0> seg_ch; + + if ( seg_ch.max_size() == 0 ) { // just illustration, if seg and seg_ch + // (really xmt::shm_alloc<0>) + // in totally different address spaces + // in our case xmt::shm_name_mgr<0> instance derived from parent + // process + seg.allocate( fname, 4*4096, 0, 0660 ); + } + + xmt::shm_name_mgr<0>& nm_ch = seg_ch.name_mgr(); + xmt::__Condition<true>& fcnd_ch = nm_ch.named<xmt::__Condition<true> >( test_Condition_Object ); + fcnd_ch.set( true ); + } + catch ( const xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "Fail in child: " << err.what() ); + } + catch ( const std::invalid_argument& err ) { + BOOST_CHECK_MESSAGE( false, "Fail in child: " << err.what() ); + } + catch ( ... ) { + BOOST_CHECK_MESSAGE( false, "Fail in child" ); + } + + exit( 0 ); + } + catch ( xmt::fork_in_parent& child ) { + try { + BOOST_CHECK( child.pid() > 0 ); + + fcnd.try_wait(); + + int stat; + BOOST_CHECK( waitpid( child.pid(), &stat, 0 ) == child.pid() ); + } + catch ( ... ) { + BOOST_CHECK_MESSAGE( false, "Fail in parent" ); + } + } + catch ( ... ) { + BOOST_CHECK_MESSAGE( false, "Fail in fork" ); + } + + (&fcnd)->~__Condition<true>(); + shm.deallocate( &fcnd, 1 ); + seg.deallocate(); + fs::remove( fname ); + } + catch ( xmt::shm_bad_alloc& err ) { + BOOST_CHECK_MESSAGE( false, "error report: " << err.what() ); + } +} Modified: trunk/complement/explore/test/mt/mt_test.h =================================================================== --- trunk/complement/explore/test/mt/mt_test.h 2007-01-30 15:04:59 UTC (rev 1484) +++ trunk/complement/explore/test/mt/mt_test.h 2007-01-30 15:06:35 UTC (rev 1485) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/12/18 19:49:04 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 13:49:41 ptr> /* * Copyright (c) 2006 @@ -17,6 +17,8 @@ void pid(); void shm_segment(); void shm_alloc(); + void fork_shm(); + void shm_named_obj(); }; #endif // __MT_TEST_H Modified: trunk/complement/explore/test/mt/mt_test_suite.cc =================================================================== --- trunk/complement/explore/test/mt/mt_test_suite.cc 2007-01-30 15:04:59 UTC (rev 1484) +++ trunk/complement/explore/test/mt/mt_test_suite.cc 2007-01-30 15:06:35 UTC (rev 1485) @@ -1,4 +1,4 @@ -// -*- C++ -*- Time-stamp: <06/12/18 19:58:56 ptr> +// -*- C++ -*- Time-stamp: <07/01/29 15:36:45 ptr> /* * Copyright (c) 2006 @@ -22,12 +22,18 @@ test_case *pid_tc = BOOST_CLASS_TEST_CASE( &mt_test::pid, instance ); test_case *shm_segment_tc = BOOST_CLASS_TEST_CASE( &mt_test::shm_segment, instance ); test_case *shm_alloc_tc = BOOST_CLASS_TEST_CASE( &mt_test::shm_alloc, instance ); + test_case *fork_shm_tc = BOOST_CLASS_TEST_CASE( &mt_test::fork_shm, instance ); + test_case *shm_nm_obj_tc = BOOST_CLASS_TEST_CASE( &mt_test::shm_named_obj, instance ); pid_tc->depends_on( fork_tc ); shm_alloc_tc->depends_on( shm_segment_tc ); + fork_shm_tc->depends_on( shm_alloc_tc ); + shm_nm_obj_tc->depends_on( fork_shm_tc ); add( fork_tc ); add( pid_tc ); add( shm_segment_tc ); add( shm_alloc_tc ); + add( fork_shm_tc, 0, 5 ); + add( shm_nm_obj_tc, 0, 5 ); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |