1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#include <iostream>
#include <cstring>
#include <pthread.h>
#include <bobcat/sharedmemory>
#include <bobcat/exception>
using namespace std;
using namespace FBB;
int main(int argc, char **argv)
try
{
if (argc == 1)
{
cout <<
"Argument:\n"
" c: create a shared memory segment, display its ID\n"
" k <id>: kill shared memory segment <id>\n"
" l <id>: lock a SharedMutex in shared memory segment <id>\n"
" L <id>: create mutex, condition variable and count in "
"ID <id>\n"
" W <id>: condition wait for the mutex in shared memory "
"segment <id>\n"
" w <id>: wait for a lock set by 'l' to be released "
"(id = <id>)\n"
;
return 0;
}
switch (argv[1][0])
{
case 'c':
{
SharedMemory shmem(1, SharedMemory::kB);
void *ptr = shmem.ptr();
cout << "ID = " << shmem.id() << ", data at " << ptr << '\n' <<
shmem << endl;
break;
}
case 'l':
{
SharedMemory shmem(stoll(argv[2]));
shmem.seek(sizeof(SharedMutex));
shmem.seek(0);
SharedMutex *smPtr = new (shmem.ptr()) SharedMutex();
smPtr->lock();
cout << "Press enter to release the lock ";
cin.ignore(1000, '\n');
smPtr->unlock();
break;
}
case 'L':
{
SharedMemory shmem(stoll(argv[2]));
// room for the variables
shmem.seek(sizeof(pthread_mutex_t) + sizeof(int) +
sizeof(pthread_cond_t));
// set up the pointers to the variables
shmem.seek(0);
pthread_mutex_t *mPtr = reinterpret_cast<pthread_mutex_t *>
(shmem.ptr());
pthread_cond_t *cPtr = reinterpret_cast<pthread_cond_t *>
(shmem.ptr() + sizeof(pthread_mutex_t));
int *iPtr = reinterpret_cast<int *>
(shmem.ptr() + sizeof(pthread_mutex_t) +
sizeof(pthread_cond_t));
// initialize the mutex
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mPtr, &mutex_attr);
// initialize the condition
pthread_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
pthread_cond_init(cPtr, &cond_attr);
// initialize the variable
memset(iPtr, 0, sizeof(int));
if (pthread_mutex_lock(mPtr) != 0)
throw Exception() << "Mutex failed to lock";
cout << "Press enter to release the lock ";
cin.ignore(1000, '\n');
// set the variable to check
*iPtr = 1;
// signal
pthread_cond_signal(cPtr);
// unlock
pthread_mutex_unlock(mPtr);
break;
}
case 'W':
{
SharedMemory shmem(stoll(argv[2]));
// room for the variables
shmem.seek(sizeof(pthread_mutex_t) + sizeof(int) +
sizeof(pthread_cond_t));
// set up the pointers to the variables
shmem.seek(0);
pthread_mutex_t *mPtr = reinterpret_cast<pthread_mutex_t *>
(shmem.ptr());
pthread_cond_t *cPtr = reinterpret_cast<pthread_cond_t *>
(shmem.ptr() + sizeof(pthread_mutex_t));
int *iPtr = reinterpret_cast<int *>
(shmem.ptr() + sizeof(pthread_mutex_t) +
sizeof(pthread_cond_t));
// obtain the lock
if (pthread_mutex_lock(mPtr) != 0)
throw Exception() << "Mutex failed to lock";
while (*iPtr == 0)
pthread_cond_wait(cPtr, mPtr);
// unlock
pthread_mutex_unlock(mPtr);
break;
}
case 'k':
{
SharedMemory shmem(stoll(argv[2]));
shmem.kill();
break;
}
case 'w':
{
SharedMemory shmem(stoll(argv[2]));
shmem.seek(0);
SharedMutex *smPtr = reinterpret_cast<SharedMutex *>(shmem.ptr());
smPtr->lock();
cout << "Obtained the lock. Now releasing it again\n";
smPtr->unlock();
break;
}
}
}
catch (exception const &exc)
{
cout << "Exception: " << exc.what() << endl;
}
|