Monday, June 17, 2013

Shared memory code sample 3.0

Evolution never stops, even on sample code :-)
As such, I'd like to insert minor changes on the previous coding.
Check out sample outputs for both ISM and DISM experiments.

The sample learning code below is using the SHM_SHARE_MMU flag to ::shmat() which is for ISM, but exactly the same code can be used replacing the flag for SHM_PAGEABLE (DISM) or 0 (System V Shared Memory).

Don't forget to compile it for 64-bits (-m64) if you want segments larger than 4 GB. This version has a crude pause() routine to avoid relying on a debugger. 
 
001: /*
002:  * File:   main.cpp
003:  * Author: AZ
004:  *
005:  * Created on June 4, 2013, 7:31 AM
006:  *
007:  */
008:
009: #include <iostream>
010:
011: #include <sys/ipc.h>
012: #include <sys/shm.h>
013:
014: #include <sys/mman.h>
015: #include <errno.h>
016:
017: void pause( char const * message )
018: {
019:     std::cout << message << std::endl 
                   << "Press <ENTER> to continue...";

020:     std::cin.get( );
021: }
022:
023: void success( )
024: {
025:     std::cout << "Success!" << std::endl 
                   << std::endl;
026: }
027:
028: void failure( )
029: {
030:     std::cout << "Failure!" << std::endl 
                   << std::endl;
031: }
032:
033: int main( )
034: {
035:     pause( "Getting shared memory." );
036:
037:     std::size_t const size = 
         1UL * 1024UL * 1024UL * 1024UL;
038:
039:     int id = 
         ::shmget( 1, size, IPC_CREAT | IPC_EXCL
         SHM_R | SHM_W | ( SHM_R >> 3 ) | ( SHM_W >> 3 ) );
040:
041:     if ( id == -1 )
042:     {
043:         failure( );
044:     }
045:     else
046:     {
047:         success( );
048:
049:         pause( "Attaching to shared memory." );
050:
051:         void * p = ::shmat( id, 0, SHM_SHARE_MMU );
052:
053:         if ( reinterpret_cast < intptr_t > ( p ) == -1 )
054:         {
055:             failure( );
056:         }
057:         else
058:         {
059:             success( );
060:
061:             pause( "Locking shared memory." );
062:
063:             if ( ::mlock( p, size ) == 0 )
064:             {
065:                 success( );
066:
067:                 pause( "Using shared memory." );
068:
069:                 ::memset( p, '*', size );
070:
071:                 success( );
072:
073:                 pause( "Unlocking shared memory." );
074:
075:                 switch ( ::munlock( p, size ) )
076:                 {
077:                     case 0:
078:                         success( );
079:                         break;
080:
081:                     case -1:
082:                         failure( );
083:                         break;
084:                 }
085:
086:             }
087:             else
088:             {
089:                 ::perror( 0 );
090:
091:                 failure( );
092:             }
093:
094:             pause( "Detaching shared memory." );
095:
096:             switch ( ::shmdt( p ) )
097:             {
098:                 case 0:
099:                     success( );
100:                     break;
101:
102:                 case -1:
103:                     failure( );
104:                     break;
105:             }
106:         }
107:
108:         pause( "Removing shared memory." );
109:
110:         switch ( ::shmctl( id, IPC_RMID, 0 ) )
111:         {
112:             case 0:
113:                 success( );
114:                 break;
115:
116:             case -1:
117:                 failure( );
118:                 break;
119:         }
120:     }
121:
122:     pause( "Exiting program." );
123:   
124:     return 0;
125: }