pthread_cond_signal on stack variable not working - pthreads

I have two threads A and B. thread A should block until signalled from threadB, The pthread_cond_signal doesnt seem to be working:
struct TR_EVT
{
Dest* pQDest ;
pthread_cond_t evWait ;
pthread_mutex_t mutex_tr ;
};
DataSet dSet ;
threadA()
{
TR_EVT TrEvt ;
dSet->setContext(&TrEvt);
pthread_cond_init(&TrEvt.evWait, NULL);
.
.
cout << "Entering Sleep\n" ;
pthread_mutex_lock(&TrEvt.mutex_tr);
pthread_cond_wait(&TrEvt.evWait, &TrEvt.mutex_tr);
pthread_mutex_unlock(&TrEvt.mutex_tr);
cout << "Out of Sleep\n" ;
}
threadB()
{
.
.
TR_EVT * pTrEvt = NULL ;
pTrEvt = (TR_EVT *)dSet->getContext()
.
.
cout << "Signalling...\n" ;
pthread_mutex_lock(&(pTrEvt->mutex_tr));
pthread_cond_signal(&(pTrEvt->evWait); //wake up thread A
pthread_mutex_unlock(&(pTrEvt->mutex_tr));
.
.
.
}
threadA() never wakes up. What could be the problem ? Appreciate any help

It appears that nothing stops Thread A from entering the wait after Thread B has already signalled the condition variable. This would have the symptom you describe.
Condition variable must always be paired with some condition over shared state (a "predicate") - you can't just use a bare condition variable. The wait for the condition should then always be done within a loop that checks that condition:
while (!condition)
pthread_cond_wait(...);
For example:
struct TR_EVT {
Dest* pQDest;
pthread_cond_t evWait;
pthread_mutex_t mutex_tr;
int thread_A_can_run;
};
threadA()
{
TR_EVT TrEvt ;
pthread_cond_init(&TrEvt.evWait, NULL);
TrEvt.thread_A_can_run = 0;
dSet->setContext(&TrEvt);
/* ... */
cout << "Entering Sleep\n" ;
pthread_mutex_lock(&TrEvt.mutex_tr);
while (!TrEvt.thread_A_can_run)
pthread_cond_wait(&TrEvt.evWait, &TrEvt.mutex_tr);
pthread_mutex_unlock(&TrEvt.mutex_tr);
cout << "Out of Sleep\n" ;
}
threadB()
{
TR_EVT * pTrEvt = NULL ;
pTrEvt = (TR_EVT *)dSet->getContext()
/* ... */
cout << "Signalling...\n" ;
pthread_mutex_lock(&(pTrEvt->mutex_tr));
pTrEvt->thread_A_can_run = 1;
pthread_cond_signal(&(pTrEvt->evWait); //wake up thread A
pthread_mutex_unlock(&(pTrEvt->mutex_tr));
/* ... */
}
This way, if Thread B gets to the point where it wants to wake up Thread A first, Thread A will see the condition set already and not wait. The mutex ensures that this is race-free: Thread B can't set the condition in between Thread A checking it and waiting.
Here I have added a simple flag for the condition, but you might be able to use something else as the predicate instead (for example, checking for a pointer to be non-NULL).
The purpose of the signalling the condition variable is to tell the waiting thread that the condition might have changed, and it should re-check it.

Related

Task does not update testbench sclk

I'm trying to understand why my signal is not updating when it is processed by the task.
As you could see below, the problem is related to the signal that internally on the task are changing correctly but even in a hierarchical call do not change the signal outside the task.
//-------------------------------
timeunit 1ps;
timeprecision 1ps;
`define CLK_HALF_PERIOD 10
`define SCK_HALF_PERIOD 30
module tbench ();
logic clk;
logic sclk;
logic RST;
hwpe_stream_intf_stream MOSI();
hwpe_stream_intf_stream MISO();
logic try;
initial begin
spi_send (.addr({1'b1,3'b111,12'd1,16'd0 }),
.data(1),
.MISO(try),
.MOSI(MOSI.data),
.SCK(sclk));
end
always
begin
# `CLK_HALF_PERIOD clk = 1;
# `CLK_HALF_PERIOD clk = 0;
end
task automatic spi_send (
input logic [31:0] addr,
input logic [31:0] data,
input logic MISO, // not used
ref logic MOSI,
ref logic SCK
);
integer i = 0;
$display ("add=%-32d",addr );
for (i=0; i<32; i=i+1) begin
//$display("add", 31-i , " MOSI ",MOSI);
// MOSI = ;
MOSI = addr[31-i];
tbench.try = MOSI;
#`SCK_HALF_PERIOD
tbench.sclk = 1'b1;
#`SCK_HALF_PERIOD;
tbench.sclk = 1'b0;
$display("add", addr[30-i] , " MOSI ",MOSI);
end
endtask
endmodule
tbench.sclk and MOSI are not changing globally, but only locally.
Here is the interface:
interface hwpe_stream_intf_stream() ;
logic valid;
logic ready;
logic data;
logic [8/8-1:0] strb;
modport source (
output valid, data, strb,
input ready
);
modport sink (
input valid, data, strb,
output ready
);
endinterface
You need to zoom in to the beginning of your waveforms to see sclk toggling. It toggles between 0 and 2000ps, then stops toggling.
You can add this to your testbench to stop the simulation much sooner to make it more obvious:
initial #3ns $finish;

How would you prevent a user from inputting a duplicate value in a linked list?

I've been trying to figure out how to prevent a user from entering a duplicate value and honestly I am struggling so much for an answer that's probably really simple once I see it, but I can't. The function is below along with the struct node. I would really appreciate it if someone could help me out here.
struct node {
int data = -1;
node * current;
node * next;
};
node * start = NULL;
```
void addNode(struct node & n) {
if (n.data == -1) {
cout << "List not created yet." << endl;
} else {
node * temp;
node * temp2;
temp = new node;
cout << "What number would you like to enter:" << endl;
cin >> temp -> data;
cout << endl;
int value;
value = temp -> data;
temp = start;
while (temp != NULL) {
if (temp -> data == value) {
cout << "Duplicate Number!" << endl;
} else {
temp = temp -> next;
}
temp = temp -> next;
}
if (start == NULL) {
start = temp;
} else {
temp2 = start;
while (temp2 -> next != NULL) {
temp2 = temp2 -> next;
}
temp2 -> next = temp;
}
}
}
Here are some remarks on your code:
Don't make start a global variable. Instead make it local to main and pass it as argument to the addNode function
Use nullptr instead of NULL
Don't ask for the user's input inside the addNode function. By the principle of separation of concern, keep the I/O aspects outside that function.
Instead pass the value as argument to addNode
You should treat a node differently when it has the value -1. An empty list is not a list with one node that has the value -1. An empty list is a null pointer.
Even if a list is empty, it should be possible to add the first node with this function
Use more descriptive variable names. n for a node instance is not very clear. Also temp and temp2 are not very clear. One of the two is the newly created node, so it could be named newNode.
After you have created the new node, and assigned its reference to temp, you assign a new value to temp with temp = start, and so you've lost (and leaked) the newly created node.
In your loop, you'll execute temp = temp->next twice when the value does not match. This should of course only be done once per iteration.
Even when your code finds a duplicate and outputs a message, it still continues the process. Instead you should stop the process, and not create the node (or if you already did: dispose it with delete).
It is a pity that you need to traverse the list again from the start to find the last node and append the new node there. You should be able to do that in the first loop where you look for the duplicate.
Here is a correction:
bool addNode(node* &start, int value) {
node * current = start;
if (start != nullptr) {
while (current->data != value && current->next != nullptr) {
current = current->next;
}
if (current->data == value) {
return false; // duplicate!
}
}
node* newNode = new node;
newNode->data = value;
if (start != nullptr) {
current->next = newNode;
} else {
start = newNode;
}
return true;
}
Note that this function returns a boolean: if true then the node was inserted. The other case means there was a duplicate.
Your main function could look like this:
int main() {
// define start as local variable
node * start = nullptr; // Use nullptr instead of NULL
while (true) {
int value;
// Don't do I/O together with list-logic
cout << "What number would you like to enter:" << endl;
cin >> value;
cout << endl;
if (value == -1) break;
if (!addNode(start, value)) {
cout << "Duplicate Number!" << endl;
}
}
}

Flex reentrant start with user-specific state

Flex sets the YY_STATE to INITIAL by default when yyscan_t is called.
I'm trying to make a reentrant scanner that can start with user-specific state instead of INITIAL.
Here is the case
/* comment start //not passed into flex
in comment //first line passed into flex
end of comment*/ //second line passed into flex
For some reasons these 2 lines are separately fed into the reentrant scanner and the YY_STATE the line belongs to are known. What I need is to pass the comment state into reentrant flex and switch YY_STATE to COMMENT before start lexing in comment\n.
My workaround are adding a dummy token in head of a line and passing the state as yyextra into flex. Once the dummy token is recognized, switch to the specific state. Hence flex begins lexing the line with specific YY_STATE. However, adding a dummy token at the beginning of each line is time-consuming.
Here is the way I used to call reentrant flex:
yyscan_t scanner;
YY_BUFFER_STATE buffer;
yylex_init(&scanner);
buffer = yy_scan_string(inputStr, scanner);
yyset_extra(someStructure, scanner);
yylex(scanner);
yy_delete_buffer(buffer, scanner);
yylex_destroy(scanner);
Is it possible to set YY_STATE before yylex(scanner) is called ?
If you are only calling yylex once for each input line, then you could just add an extra argument to yylex which provides the start condition to switch to, and set the start condition at the top of yylex.
But there's no simple way to refer to start conditions from outside of the flex file, nor is there a convenient way to extract the current start condition from the yystate_t object. The fact that you claim to have this information available suggests that you are storing it somewhere when you change start states, so you could restore the start state from that same place when you start up yylex. The simplest place to store the information would be the yyextra object, so that's the basis of this sample code:
File begin.int.h
/* This is the internal header file, which defines the extra data structure
* and, in this case, the tokens.
*/
#ifndef BEGIN_INT_H
#define BEGIN_INT_H
struct Extra {
int start;
};
enum Tokens { WORD = 256 };
#endif
File begin.h
/* This is the external header, which includes the header produced by
* flex. That header cannot itself be included in the flex-generated code,
* and it depends on the internal header. So the order of includes here is
* (sadly) important.
*/
#ifndef BEGIN_H_
#define BEGIN_H_
#include "begin.int.h"
#include "begin.lex.h"
#endif
File: begin.l
/* Very simple lexer, whose only purpose is to drop comments. */
%option noinput nounput noyywrap nodefault 8bit
%option reentrant
%option extra-type="struct Extra*"
%{
#include "begin.int.h"
/* This macro ensures that start condition changes are saved */
#define MY_BEGIN(s) BEGIN(yyextra->start = s)
%}
%x IN_COMMENT
%%
/* See note below */
BEGIN (yyextra->start);
"/*" MY_BEGIN(IN_COMMENT);
[[:alnum:]]+ return WORD;
[[:space:]]+ ;
. return yytext[0];
<IN_COMMENT>{
"*/" MY_BEGIN(INITIAL);
.|[^*]+ ;
}
Note:
Any indented code after the first %% and before the first pattern is inserted at the beginning of yylex; the only thing that executes before it is the one-time initialization of the yystate_t object, if necessary.
File begin.main.c
/* Simple driver which creates and destroys a scanner object for every line
* of input. Note, however, that it reuses the extra data object, which holds
* persistent information (in this case, the current start condition).
*/
#include <stdio.h>
#include "begin.h"
int main ( int argc, char * argv[] ) {
char* buffer = NULL;
size_t buflen = 0;
struct Extra my_extra = {0};
for (;;) {
ssize_t nr = getline(&buffer, &buflen, stdin);
if (nr < 0) break;
if (nr == 0) continue;
yyscan_t scanner;
yylex_init_extra(&my_extra, &scanner);
/* Ensure there are two NUL bytes for yy_scan_buffer */
if (buflen < nr + 2) {
buffer = realloc(buffer, nr + 2);
buflen = nr + 2;
}
buffer[nr + 1] = 0;
YY_BUFFER_STATE b = yy_scan_buffer(buffer, nr + 2, scanner);
for (;;) {
int token = yylex(scanner);
if (token == 0) break;
printf("%d: '%s'\n", token, yyget_text(scanner));
}
yy_delete_buffer(b, scanner);
yylex_destroy(scanner);
}
return 0;
}
Build:
flex -o begin.lex.c --header-file begin.lex.h begin.l
gcc -Wall -ggdb -o begin begin.lex.c begin.main.c

Using WaitForMultipleObjects() with ACE_SOCK_Stream - get event only when there's data

Is it possible to use WaitForMultipleObjects() with ACE_SOCK_Stream, and make it return only when there's data to read from it?
I tried to following:
// set some params
DWORD handlesCount = 1;
DWORD timeoutMs = 5 * 1000;
HANDLE* handles = new HANDLE[handlesCount];
handles[0] = sock_stream.get_handle();
while (true) {
int ret = WaitForMultipleObjects(handlesCount, handles, false, timeoutMs);
std::cout << "Result: " << ret << std::endl;
But the WaitForMultipleObjects() returns immediately the socket stream index, indicating that its ready (it prints 0 in an endless loop).
The socket is accepted via a ACE_SOCK_Acceptor (ACE_SOCK_Acceptor->accept()).
How do I make WaitForMultipleObjects() wait until the socket has data to read?
The socket handle is not suitable for use in WFMO. You should use WSAEventSelect to associate the desired event(s) with an event handle that's registered with WFMO.
Since you are also familiar with ACE, you can check the source code for ace/WFMO_Reactor.cpp, register_handler() method to see a use-case and how it works with WFMO.

Passing a pointer to a linked list in C++

I have a fairly basic program that is intended to sort a list of numbers via a Linked List.
Where I am getting hung up is when the element needs to be inserted at the beginning of the list. Here is the chunk of code in question
Assume that root->x = 15 and assume that the user inputs 12 when prompted:
void addNode(node *root)
{
int check = 0; //To break the loop
node *current = root; //Starts at the head of the linked list
node *temp = new node;
cout << "Enter a value for x" << endl;
cin >> temp->x;
cin.ignore(100,'\n');
if(temp->x < root->x)
{
cout << "first" << endl;
temp->next=root;
root=temp;
cout << root->x << " " << root->next->x; //Displays 12 15, the correct response
}
But if, after running this function, I try
cout << root->x;
Back in main(), it displays 15 again. So the code
root=temp;
is being lost once I leave the function. Now other changes to *root, such as adding another element to the LL and pointing root->next to it, are being carried over.
Suggestions?
This because you are setting the local node *root variable, you are not modifying the original root but just the parameter passed on stack.
To fix it you need to use a reference to pointer, eg:
void addNode(node*& root)
or a pointer to pointer:
void addNode(node **root)

Resources