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
1621using namespace std ;
1722
1823class 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