Error: "sync variables cannot currently be written" - chapel

One of my students is having a severe problem with their project (assignment is: http://turing.plymouth.edu/~kgb1013/?course=4310&project=0). They (and I) are getting a weird error when compiling with my test file, testSemaphore.chpl, available at: http://turing.plymouth.edu/~kgb1013/4310/semaphoreProject/testSemaphore.chpl . The error is this:
$CHPL_HOME/modules/standard/IO.chpl:3038: error: sync variables cannot currently be written - apply readFE/readFF() to those variables first
I've had them remove the body of all of their methods, but they're still getting the error. Here is the body of their code:
use Time;
class Semaphore {
var gate1$ : sync int;
//Constructor
proc Semaphore(){
}
//secondary Constructor
proc Semaphore(givenTokens : int){
}
//returns the number of tokens available
proc getNumTokens() : int {
return 1;
}
//gives out a token
proc p() {
}
//returns a token
proc v() {
}
}
Why are they getting this error?

Sorry you're having trouble! It turns out that some of this would be better as a GitHub issue on the Chapel project, but let me first explain what's happening.
The class Semaphore includes a sync variable field. Meanwhile, the default implementation for writing a class is to write each field. So the error message in IO.chpl is trying to say that it doesn't have a reasonable way of outputting a sync variable. E.g.
var x: sync int;
writeln(x);
gives the same error. I think it would be reasonable to open up a GitHub issue on the Chapel project about how inscrutable this error is (and how it doesn't report a line number that is useful to you). Note that I personally used chpl testSemaphore.chpl --print-callstack-on-error to better understand the error - it often helps to add --print-callstack-on-error when you get an error referring to an internal/standard module.
Now, as for the assignment, there are two ways to resolve it:
Adjust testSemaphore.chpl to not print out the semaphore representation in 'writeln' calls. I commented out both writelns starting with "Testing that" and got it to compile.
Adjust the class Semaphore to include a writeThis to replace the compiler-generated write-each-field default, as below:
Here is an example of such a writeThis (see also The readThis, writeThis, and readWriteThis methods )
class Semaphore {
var gate1$ : sync int;
// Other methods as before
proc writeThis(f) {
f <~> "sync semaphore";
}
}

Related

C++ proto2 "expression is not assignable" error

I am trying to figure out how to assign a message field in protobuf2 in C++. Here is a small snippet of the code.
message Sub {
optional double x = 1 [[default = 46.0];
}
message Master {
optional Sub sub_message;
}
Now when I try to initialize a Master message, I got the following error:
Master msg;
msg.mutable_sub_message() = new Sub();
error: expression is not assignable
However, the following code works, and the sub_message is set to default values:
Master msg;
msg.set_sub_message(new Sub());
Can anyone kindly explain why mutable_sub_message() can not be used for assignment?
msg.mutable_sub_message() returns a pointer to the field, i.e. a Sub*. The idea is that you use that pointer to manipulate the field as you need.
Assigning a different pointer to it wouldn't change the value inside the class, it would at most change the temporary pointer that was returned, which doesn't make sense. I guess it could be made to work if mutable_sub_message returned something like a Sub*& (not even sure that syntax is right), but that's not how the library was written.
In a more practical note, calling mutable_sub_message will initialize the subfield, you don't need to do that explicitly. That means you'd usually set a nested field using
Master msg;
msg.mutable_sub_message()->set_x(4.0);
Also, it's always safe to call getters even if a field isn't set, in that case they will always return a default instance. In other words:
double use_field(const Master& msg) {
// This is always safe, and will return the default even if
// sub_message isn't set.
return msg.sub_message().x();
}

SystemC- sensitivity list

I have recently started learning SystemC and I have got an error with sensitivity list in "SC_METHOD". I am trying to implement a fifo and the error corresponds to following part of the code:
SC_MODULE(fifo){
...
int rd_addr, wr_addr;
...
void buffer_full();
...
SC_CTOR(fifo){
SC_METHOD(buffer_full);
sensitive << rd_addr << wr_addr;
}
};
I get error when compiling the code and it complains about sensitivity list. The error is
fifo_simple.h:32:22: error: invalid user-defined conversion from 'int' to 'const sc_core::sc_event&' [-fpermissive]
I would appreciate if someone could let me know what is wrong with the sensitivity list. how should I make "buffer_full" process sensitive to the changes in rd_addr and wr_addr.
I also tried following syntax to see if it works with single bit sensitivity but still no success
sensitive << rd_addr[0]
Many thanks
You cannot be sensitive to plain integers, only to (events of) ports or plain events.
As suggested by #jakub_d in the comments above, try changing the int variables to signal ports (although I'd suggest using inputs rather than output ports):
SC_MODULE(fifo)
{
...
// use ports instead of plain integers
sc_in<int> rd_addr, wr_addr;
...
void buffer_full();
...
SC_CTOR(fifo)
: rd_addr("rd_addr") // name your ports
, wr_addr("wr_addr")
{
SC_METHOD(buffer_full);
sensitive << rd_addr << wr_addr; // sensitivity works now
}
};
When using your FIFO, you then need to bind matching sc_signal<int> instances to these address ports:
int sc_main(int, char*[]) {
sc_signal<int> rd_addr_s("rd_addr_s"), wr_addr_s("wr_addr_s");
fifo fifo_i("fifo_i");
// bind signals to ports
fifo_i.rd_addr(rd_addr_s);
fifo_i.wr_addr(wr_addr_s);
// ...
return 0;
}

Can the code of some C++ class accidentally overwrite a private static variable of another class?

I mean a scenario like this: There is some class (I call it victim) with a private data member and another class (named attacker) with some method, which, of course, normally does not have access to private members of other classes and does not even hold a reference to an instance of victim:
extern "C" {
#include <pigpiod_if2.h>
}
class victim {
private:
static bool is_ready;
static bool is_on;
public:
static void init ()
{
is_ready = true;
is_on = true;
}
/* Some other public methods go here. */
}
class attacker {
private:
static int last_read_pin;
public:
static void run ()
{
while (true) {
/* Some sensible code goes here. */
last_read_pin = -1;
time_sleep (0.01); // Using nanosleep () does not change behavior.
}
}
}
This is just a code snippet to illustrate the following question: Is it possible, not just in theory, but also practically, that attacker::run () can modify the values of the two private static vars of victim unintentionally, without addressing any public member of victim, maybe due to undefined behavior or even a compiler bug? Thank you.
UPDATE: After a hint from another user, I did rebuild the complete app using make clean and make. Also, I added the endless loop into my example. The change in is_ready occurs during the sixth run of the loop. Changing the sleep interval does not change behavior, though.
UPDATE #2: I ran my code through gdb with a watch on the is_ready variable, and I got an alert when last_read_pin was set to –1:
Hardware watchpoint 1: is_ready
Old value = true
New value = false
attacker::Run ()
last_read_pin = -1;
UPDATE #3: Moving last_read_pin into the Run () method itself, thereby making it an internal variable, does not help either.
UPDATE #4: After simply commenting out the line of code, which makes so much trouble, the issue still persisten, apparently being caused by one line above, which reads like this:
keypad::last_levels [h] [k] = 0;
I had to comment out this line, too, to get rid of the problem with is_ready being changed.
Could the use of pigpiod cause this issue? I an earlier version, I was using pigpio directly and did not encounter this problem.
Compiled with gcc 4.9.2.
After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:
last_levels [h] [l] = 0;
Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!
This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!

C++ Set values for members of a struct**

I've defined in my foo.h the following variables
#define APILONG long
#define APIDOUBLE double
#define APISTRING const char*
And also the following struct
struct SetupData
{
APISTRING customerName;
APIDOUBLE quantity;
APILONG startDate;
};
Now, in my foo.cpp i have the following method where I need to assign values to the members of the struct that are being pulled from a .config file.
APILONG doSomething(APISTRING* setupOrder, APILONG* setupActive, struct SetupData** setupData)
{
//load config file
Config config("rommel.config");
//assign a string value to APISTRING* (No issue here.)
*setupOrder= config.pString("setupOrder").c_str();
//assign a value (No issue here, atleast not that I know of..)
*setupActive = config.pDouble("setupActive");
//assign values to members of struct**
(*setupData)->customerName = config.pString("setupDataCustomerName").c_str();
(*setupData)->quantity = config.pDouble("setupDataQuantity");
(*setupData)->startDate = config.pDouble("setupDataStartDate");
//do other stuff..
}
When I compile and rebuild it does not give me any error messages. But when I try to run the actual program it crashes. (Am using Dev-C++, Visual Studio was causing problems..)
I do however get a chance to see the values assigned before it crashes and it looks like the values are not being assigned (Null or strange characters).
I've tried variations of the
(*setupData)->startDate ..
line and also I have tried declaring the struct in the method like the following, but to no avail.
struct SetupData stpData;
*setupData = &stpData;
Any help would be greatly appreciated. I previously posted another question which is related to this, it contains some pretty useful information aswell. I'll leave the link in case it helps. "C++ Set value for a char**"
The config object is local to the doSomething function.
The setupOrder pointer points to what appears to be a
member of the config object.
The config object will go out of scope at the end of the doSomething function and can be de-allocated at that point.
At that point, what the setupOrder pointer "points" to
might no longer be valid.
It is a good idea to make sure that after the call to doSomething ends,
that all the pointers still point to objects that still exist.
You may have already done this, but I just wanted to check.

C++ MySQL++ Delete query statement brain killer question

I'm relatively new to the MySQL++ connector in C++, and have an really annoying issue with it already!
I've managed to get stored procedures working, however i'm having issues with the delete statements. I've looked high and low and have found no documentation with examples.
First I thought maybe the code needs to free the query/connection results after calling the stored procedure, but of course MySQL++ doesn't have a free_result method... or does it?
Anyways, here's what I've got:
#include <iostream>
#include <stdio.h>
#include <queue>
#include <deque>
#include <sys/stat.h>
#include <mysql++/mysql++.h>
#include <boost/thread/thread.hpp>
#include "RepositoryQueue.h"
using namespace boost;
using namespace mysqlpp;
class RepositoryChecker
{
private:
bool _isRunning;
Connection _con;
public:
RepositoryChecker()
{
try
{
this->_con = Connection(false);
this->_con.set_option(new MultiStatementsOption(true));
this->_con.set_option(new ReconnectOption(true));
this->_con.connect("**", "***", "***", "***");
this->ChangeRunningState(true);
}
catch(const Exception& e)
{
this->ChangeRunningState(false);
}
}
/**
* Thread method which runs and creates the repositories
*/
void CheckRepositoryQueues()
{
//while(this->IsRunning())
//{
std::queue<RepositoryQueue> queues = this->GetQueue();
if(queues.size() > 0)
{
while(!queues.empty())
{
RepositoryQueue &q = queues.front();
char cmd[256];
sprintf(cmd, "svnadmin create /home/svn/%s/%s/%s", q.GetPublicStatus().c_str(),
q.GetUsername().c_str(), q.GetRepositoryName().c_str());
if(this->DeleteQueuedRepository(q.GetQueueId()))
{
printf("query deleted?\n");
}
printf("Repository created!\n");
queues.pop();
}
}
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
//}
}
protected:
/**
* Gets the latest queue of repositories from the database
* and returns them inside a cool queue defined with the
* RepositoryQueue class.
*/
std::queue<RepositoryQueue> GetQueue()
{
std::queue<RepositoryQueue> queues;
Query query = this->_con.query("CALL sp_GetRepositoryQueue();");
StoreQueryResult result = query.store();
RepositoryQueue rQ;
if(result.num_rows() > 0)
{
for(unsigned int i = 0;i < result.num_rows(); ++i)
{
rQ = RepositoryQueue((unsigned int)result[i][0],
(unsigned int)result[i][1],
(String)result[i][2],
(String)result[i][3],
(String)result[i][4],
(bool)result[i][5]);
queues.push(rQ);
}
}
return queues;
}
/**
* Allows the thread to be shut off.
*/
void ChangeRunningState(bool isRunning)
{
this->_isRunning = isRunning;
}
/**
* Returns the running value of the active thread.
*/
bool IsRunning()
{
return this->_isRunning;
}
/**
* Deletes the repository from the mysql queue table. This is
* only called once it has been created.
*/
bool DeleteQueuedRepository(unsigned int id)
{
char cmd[256];
sprintf(cmd, "DELETE FROM RepositoryQueue WHERE Id = %d LIMIT 1;", id);
Query query = this->_con.query(cmd);
return (query.exec());
}
};
I've removed all the other methods as they're not needed...
Basically it's the DeleteQueuedRepository method which isn't working, the GetQueue works fine.
PS: This is on a Linux OS (Ubuntu server)
Many thanks,
Shaun
MySQL++ doesn't have a free_result method... or does it?
It doesn't need one. When the result object goes out of scope at the end of GetQueue(), all memory associated with it is automatically freed.
this->_con = Connection(false);
Three problems here:
When you create the RepositoryChecker object, you already have created a Connection object. If you need to pass different parameters to its constructor, you'd do that in the initialization list of the RepositoryChecker constructor, not in its body. Read your C++ book.
What you've done here instead is a) create a default Connection object, then b) create a different Connection object with exceptions turned off, then c) overwrite the first with the second. If that works, it's highly inefficient. MySQL++ Connection objects have had problems with their copy ctors in the past, so if you're using an old version of the library, it could explain your problems.
You're telling the Connection object (and every object it creates, even indirectly, which means pretty much everything in MySQL++) you don't want it to throw exceptions, but then you wrap it in a big try block. Pick one.
I'd suggest using exceptions — the default in MySQL++ — given the way your code is currently structured. If there is a query error way down in DeleteQueuedRepository(), there's no way to see what happened because you'd just pass false up to the caller, which is ignored because there is no else clause on the call. If you do this, log the e.what() message in your catch block. You're just throwing that information away right now.
There are several places where you're using constructs that look more like Python (or perhaps JavaScript) than C++. This makes me wonder if your problem isn't damage caused by some other misuse of C++.
On this line in particular, you're using the this pointer explicitly, for which there is no need in C++. This code does exactly the same thing:
_con = Connection(false);
Though again, the line should be replaced entirely, using the RepositoryChecker ctor initializer list instead.
Moving on...
sprintf(cmd, "DELETE FROM RepositoryQueue WHERE Id = %d LIMIT 1;", id);
As others have commented, you'd be better off using the Query stream interface:
Query q = _con.query();
q << "DELETE FROM RepositoryQueue WHERE Id = " << id << " LIMIT 1";
This has several advantages:
Fixes the type safety problem implied by the one who suggested changing your %d to %u. C++ IOStreams take care of that for you.
Automatic quoting of data inserted into the stream, if needed. (Which it isn't, in this case.)
Prevents any possibility of running off the end of the buffer. You could use the nonportable snprintf() instead here, but why?
If you're really happy with printf(), there's the template query interface instead.
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
Have you read the threads chapter in the user manual? You don't get thread safety for free in MySQL++. Your problem could be due to memory corruption.
Warren Young, MySQL++ Maintainer
Try changing "%d" to "%u" in sprintf.