Menu

deque and some more questions

Help
Chang Luo
2004-01-12
2004-01-16
  • Chang Luo

    Chang Luo - 2004-01-12

            My requirement is to use "deque" in shared memory for 2 processes
    (generated by fork()).  Shall I use "Multi_Process_Pool_alloc" or only
    "pooled_allocator" would be fine?

            I was actually trying to use "list" in case "deque" doesn't work.  But I
    kept getting the same error below.  Even if I run the old vector example now I
    still get the same error:
    shared_memory.cc:202: locks::lock(): semaphore lock: Invalid argument result: -1
    : semaphore lock errno: Invalid argument result: -1 lock attempt error. semid:
    -1 page_num: 34
    Aborted

            I use "ipcs" and did not see anything related.

            some more basic questions:
    1. In manpage of mmap(start, ..., offset), it says offset is only a hint and
    could be 0.  Does it mean I can put anything to "key_addr" in your example? What
    does "0x400d0000" mean?

    2. What does "key_container" use for?  Can I change it?

    3. It seems I can't use slist (not found).  But I can use list.  This is a STL
    question (difference between SGI and GNU STL?)and has nothing to do with your program.  Do you know why?

     
    • Marc Bumble

      Marc Bumble - 2004-01-12

      1. The key_addr is the virtual address in the process where
          mmap maps the shared memory segment opened by
          the POSIX sem_open call.  If mmap cannot map to the
          value provided by the key_addr value, an exception is
          thrown.  See the mmap call in the shared_memory.h
          file in the include directory.

      2. The key_container value is an ASCII string used by
          secondary exception processes to attach to a given
          class.  So the 1st process sets up the STL data structure.
          Then another class which wants to attach to that data
          structure, effectively uses the key_container value to
          lookup the addresses and other needed information to
           attach and work with the same class.  The key_container
           value is effectively a lookup key which allows other
           process to attach to existing containers.  It is used by
           the Multi_Process_Pool_alloc<>::attach() method.
           See that member function in the pooled_allocator.h
           file.

      3.  I haven't tried slist.  I mostly use the original STL classes.
           This project originally worked with STLPORT, which is a
           version of the STL and was later migrated to work with
           the GNU implementation.  I would like to get the systems
           working fully with the GNU implementation though.  That
           is the goal.

      I have it running without the upper level classes as in the listing below.

      Hope some of this helps.  I continue to work on the project
      as time allows.  Could definitely use some assistance if you
      are interested,

      Marc

      // file: main.cc
      // author: Marc Bumble
      // April 29, 2003
      // Page memory source for shared memory
      // Copyright (C) 2003 by Marc D. Bumble

      //  This program is free software; you can redistribute it and/or
      //  modify it under the terms of the GNU General Public License
      //  as published by the Free Software Foundation; either version 2
      //  of the License, or (at your option) any later version.

      //  This program is distributed in the hope that it will be useful,
      //  but WITHOUT ANY WARRANTY; without even the implied warranty of
      //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      //  GNU General Public License for more details.

      //  You should have received a copy of the GNU General Public License
      //  along with this program; if not, write to the Free Software
      //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

      #include <iostream> 
      #include <pooled_allocator.h>
      #include <deque>

      char key_val[] = "/allocate_key";  // needs a leading slash, see manpage.
      char key_container[] = "container_lookup_key";
      char key_addr[] = "0x400d0000";

      int main(int argc, char** argv) {

        typedef pooled_allocator::Pool_alloc<int,
          key_val,
          key_addr> my_deque_alloc_t;
       
        std::cout << "Insert ints" << std::endl;

        std::deque<int,my_deque_alloc_t> Q;
        Q.push_back(3);
        Q.push_front(1);
        Q.insert(Q.begin() + 1, 2);
        Q[2] = 0;
        for (std::deque<int>::iterator it = Q.begin();
             it != Q.end(); it++)
          std::cout << "Deque val: " << *it << std::endl; 

        return 0;

      }

       
    • Chang Luo

      Chang Luo - 2004-01-16

      Thanks for your invitation and replies!  I am interested in working with you.  My first priority, however, is to finish my current project.  If there is any bug fixing involved in using your program, I am glad to take a shot.

      Here are some more questions.  thanks for your patience:
      1. what is the rule of setting key_addr?  How do you calculate the current value of "0x400d0000"?

      I tried to first run the vector example, then remove the writing section thus only reading the shared memory.  It gives me an error:
      "Floating point exception"
      I will attach the code below.  I guess it is something to do with the key_addr.

      2. In the paper, you mention there is a first version which works fine for parent-children processes.  I wonder if it would work for deque and where I can download it.

      3. Is the below logic correct for parent-children processes:

       
      • Marc Bumble

        Marc Bumble - 2004-01-16

        Answers to above questions

        1. The value for key_addr is an address value passed to mmap
            in the shared_memory.h code.  For the example, a random
            value is just selected.  Read the man page on mmap
            concerning the value of the first parameter.  It serves as a
             hint for placement.

        2. All versions are checked into the CVS repository.  You can
            pull and play with earlier versions from that repository.

        3. There may be examples for the earlier parent/child
            setup, but I am trying to advance beyond that version.

        Marc

         
    • Chang Luo

      Chang Luo - 2004-01-16

      (continued)

        typedef pooled_allocator::Pool_alloc<int,
          key_val,
          key_addr> my_vector_alloc_t;
       
        typedef std::vector<int,my_vector_alloc_t> my_vector_t;

        pooled_allocator::Multi_Process_Pool_alloc<my_vector_t,
          int,
          key_val,
          key_container,
          key_addr> temp_alloc;

        if (fork()){
          my_vector_t* vec_ptr = temp_alloc.attach();
          // read
          ...
        }
        else {
          my_vector_t* vec_ptr = temp_alloc.attach();
          // read
          ...
        }

      =========== bug ==============

      char key_val[] = "/allocate_key123";  // needs a leading slash, see manpage.
      char key_container[] = "container_lookup_key";
      char key_addr[] = "0x400d0000";

      int main(int argc, char** argv) {

        typedef pooled_allocator::Pool_alloc<int,
          key_val,
          key_addr> my_vector_alloc_t;
       
        typedef std::vector<int,my_vector_alloc_t> my_vector_t;

        pooled_allocator::Multi_Process_Pool_alloc<my_vector_t,
          int,
          key_val,
          key_container,
          key_addr> temp_alloc;

        my_vector_t* vec_ptr = temp_alloc.attach();

        const int& segment_num = temp_alloc.get_proj_id();
        const int& segment_page_num = temp_alloc.get_segment_page_num();

        /*  when I remove this writing section, it gives me error.  otherwise it runs fine.

        temp_alloc.lock(segment_num,segment_page_num);

        std::cout << "Insert ints" << std::endl;
        for (int i = 0; i < 10; i++) {
          vec_ptr->push_back(i);
          std::cout << "Pushed a " << i << "\t Read a " << (*vec_ptr)[i] << std::endl;
        };
        temp_alloc.unlock(segment_num,segment_page_num);
        */
        std::cout << "Read 1st time" << std::endl;

        for (my_vector_t::iterator it = vec_ptr->begin();
             it != vec_ptr->end(); it++)
          std::cout << "Vector val: " << *it << std::endl;

        std::cout << "Read 2nd time" << std::endl;

        for (my_vector_t::iterator it = vec_ptr->begin();
             it != vec_ptr->end(); it++)
          std::cout << "Vector val: " << *it << std::endl;

        return 0;

      }

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.