Skip to content

Commit cc6cc49

Browse files
committed
Implement v1.0.0 of Shared Memory
1 parent 28afb1b commit cc6cc49

1 file changed

Lines changed: 224 additions & 4 deletions

File tree

concore.hpp

Lines changed: 224 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,25 @@
1212
//libraries for platform independent delay. Supports C++11 upwards
1313
#include <chrono>
1414
#include <thread>
15+
#include <sys/ipc.h>
16+
#include <sys/shm.h>
17+
#include <unistd.h>
18+
#include <cstring>
19+
#include <cctype>
1520

1621
using namespace std;
1722

1823
class Concore{
1924

25+
private:
2026
//private variables
2127
string s="",olds="";
2228
string inpath = "./in";
2329
string outpath = "./out";
30+
int shmId_;
31+
char* sharedData_;
32+
// File sharing:- 0, Shared Memory:- 1
33+
int communication_ = 0;
2434

2535
public:
2636
double delay = 1;
@@ -32,9 +42,96 @@ class Concore{
3242
//Constructor to put in iport and oport values in map
3343
Concore(){
3444
iport = mapParser("concore.iport");
35-
oport = mapParser("concore.oport");
45+
oport = mapParser("concore.oport");
46+
std::map<std::string, int>::iterator it_iport = iport.begin();
47+
std::map<std::string, int>::iterator it_oport = oport.begin();
48+
int iport_number = AlphanumericSM(it_iport->first);
49+
int oport_number = AlphanumericSM(it_oport->first);
50+
51+
if(iport_number != -1 || oport_number != -1)
52+
{
53+
communication_ = 1;
54+
if(iport_number > oport_number)
55+
{
56+
this->createSharedMemory();
57+
}
58+
else
59+
{
60+
this->getSharedMemory();
61+
}
62+
}
63+
}
64+
65+
/**
66+
* return number if number is greater than zero
67+
* and alphanumeric
68+
*/
69+
int AlphanumericSM(const std::string& input) {
70+
bool isPureAlphabetic = true;
71+
for (char c : input) {
72+
if (!std::isalpha(c)) {
73+
isPureAlphabetic = false;
74+
break;
75+
}
76+
}
77+
78+
if (isPureAlphabetic) {
79+
return -1;
80+
} else {
81+
if (int(input[0]))
82+
{
83+
return int(input[0]);
84+
}
85+
return -1;
86+
}
3687
}
3788

89+
~Concore()
90+
{
91+
// Detach the shared memory segment from the process
92+
shmdt(sharedData_);
93+
94+
// Remove the shared memory segment
95+
shmctl(shmId_, IPC_RMID, nullptr);
96+
}
97+
98+
99+
void createSharedMemory()
100+
{
101+
std::cout << "create SM" << std::endl;
102+
shmId_ = shmget(1237, 256, IPC_CREAT | 0666);
103+
if (shmId_ == -1) {
104+
std::cerr << "Failed to create shared memory segment." << std::endl;
105+
}
106+
107+
// Attach the shared memory segment to the process's address space
108+
sharedData_ = static_cast<char*>(shmat(shmId_, NULL, 0));
109+
if (sharedData_ == reinterpret_cast<char*>(-1)) {
110+
std::cerr << "Failed to attach shared memory segment." << std::endl;
111+
}
112+
}
113+
114+
void getSharedMemory()
115+
{
116+
std::cout << "get SM" << std::endl;
117+
while (true) {
118+
// Get the shared memory segment created by Writer
119+
shmId_ = shmget(1237, 256, 0666);
120+
121+
// Check if shared memory exists
122+
if (shmId_ != -1) {
123+
break; // Break the loop if shared memory exists
124+
}
125+
126+
std::cout << "Shared memory does not exist. Make sure the writer process is running." << std::endl;
127+
sleep(1); // Sleep for 1 second before checking again
128+
}
129+
130+
// Attach the shared memory segment to the process's address space
131+
sharedData_ = static_cast<char*>(shmat(shmId_, NULL, 0));
132+
}
133+
134+
38135
map<string,int> mapParser(string filename){
39136
map<string,int> ans;
40137

@@ -112,8 +209,18 @@ class Concore{
112209
return temp;
113210
}
114211

212+
vector<double> read(int port, string name, string initstr)
213+
{
214+
if(communication_ == 1)
215+
{
216+
return read_SM(port, name, initstr);
217+
}
218+
219+
return read_FM(port, name, initstr);
220+
}
221+
115222
//accepts the file name as string and returns a string of file content
116-
vector<double> read(int port, string name, string initstr){
223+
vector<double> read_FM(int port, string name, string initstr){
117224
chrono::milliseconds timespan((int)(1000*delay));
118225
this_thread::sleep_for(timespan);
119226
string ins;
@@ -159,6 +266,60 @@ class Concore{
159266
}
160267
s += ins;
161268

269+
vector<double> inval = parser(ins);
270+
simtime = simtime > inval[0] ? simtime : inval[0];
271+
272+
//returning a string with data excluding simtime
273+
inval.erase(inval.begin());
274+
return inval;
275+
276+
}
277+
278+
//accepts the file name as string and returns a string of file content
279+
vector<double> read_SM(int port, string name, string initstr){
280+
chrono::milliseconds timespan((int)(1000*delay));
281+
this_thread::sleep_for(timespan);
282+
string ins = "";
283+
try {
284+
if (shmId_ != -1) {
285+
if (sharedData_ && sharedData_[0] != '\0') {
286+
std::string message(sharedData_, strnlen(sharedData_, 256));
287+
ins = message;
288+
std::cout << "Received message: " << message << " ins " << ins.length() << std::endl;
289+
}
290+
else
291+
{
292+
throw 505;
293+
}
294+
}
295+
else
296+
{
297+
throw 505;
298+
}
299+
} catch (...) {
300+
ins = initstr;
301+
}
302+
303+
while ((int)ins.length()==0){
304+
this_thread::sleep_for(timespan);
305+
try{
306+
if(shmId_ != -1) {
307+
std::cout << "in read while\n";
308+
std::string message(sharedData_, strnlen(sharedData_, 256));
309+
ins = message;
310+
retrycount++;
311+
}
312+
else{
313+
retrycount++;
314+
throw 505;
315+
}
316+
}
317+
//observed retry count in C++ from various tests is approx 80.
318+
catch(...){
319+
cout<<"Read error";
320+
}
321+
}
322+
s += ins;
162323

163324
vector<double> inval = parser(ins);
164325
simtime = simtime > inval[0] ? simtime : inval[0];
@@ -169,8 +330,28 @@ class Concore{
169330

170331
}
171332

333+
void write(int port, string name, vector<double> val, int delta=0)
334+
{
335+
if(communication_ == 1)
336+
{
337+
return write_SM(port, name, val, delta);
338+
}
339+
340+
return write_FM(port, name, val, delta);
341+
}
342+
343+
void write(int port, string name, string val, int delta=0)
344+
{
345+
if(communication_ == 1)
346+
{
347+
return write_SM(port, name, val, delta);
348+
}
349+
350+
return write_FM(port, name, val, delta);
351+
}
352+
172353
//write method, accepts a vector double and writes it to the file
173-
void write(int port, string name, vector<double> val, int delta=0){
354+
void write_FM(int port, string name, vector<double> val, int delta=0){
174355

175356
try {
176357
ofstream outfile;
@@ -194,7 +375,7 @@ class Concore{
194375
}
195376

196377
//write method, accepts a string and writes it to the file
197-
void write(int port, string name, string val, int delta=0){
378+
void write_FM(int port, string name, string val, int delta=0){
198379
chrono::milliseconds timespan((int)(2000*delay));
199380
this_thread::sleep_for(timespan);
200381
try {
@@ -211,6 +392,45 @@ class Concore{
211392
cout<<"skipping +"<<outpath<<port<<" /"<<name;
212393
}
213394
}
395+
396+
//write method, accepts a vector double and writes it to the file
397+
void write_SM(int port, string name, vector<double> val, int delta=0){
398+
399+
try {
400+
std::ostringstream outfile;
401+
if(shmId_ != -1){
402+
val.insert(val.begin(),simtime+delta);
403+
outfile<<'[';
404+
for(int i=0;i<val.size()-1;i++)
405+
outfile<<val[i]<<',';
406+
outfile<<val[val.size()-1]<<']';
407+
std::string result = outfile.str();
408+
std::strncpy(sharedData_, result.c_str(), 256 - 1);
409+
}
410+
else{
411+
throw 505;
412+
}
413+
}
414+
415+
catch(...){
416+
cout<<"skipping +"<<outpath<<port<<" /"<<name;
417+
}
418+
}
419+
420+
//write method, accepts a string and writes it to the file
421+
void write_SM(int port, string name, string val, int delta=0){
422+
chrono::milliseconds timespan((int)(2000*delay));
423+
this_thread::sleep_for(timespan);
424+
try {
425+
if(shmId_ != -1){
426+
std::strncpy(sharedData_, val.c_str(), 256 - 1);
427+
}
428+
else throw 505;
429+
}
430+
catch(...){
431+
cout<<"skipping +"<<outpath<<port<<" /"<<name;
432+
}
433+
}
214434

215435
//Initialising
216436
vector<double> initval(string f){

0 commit comments

Comments
 (0)