How to make a node send a message after wait random second in contiki? - timer

I set etimer_set(&periodic, 60CLOCK_SECOND),etimer_set(&send_time, 300CLOCK_SECOND)
if (etimer_expired(&periodic))
{
etimer_reset(&periodic);
ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL);
}
if (etimer_expired(&send_time))
{
etimer_reset(&send_time);
//wait a few seconds, send a message
}
Every time the send_time runs out, and wait a few seconds I want to send a message to sink.
I try to use PROCESS_WAIT_EVENT_UNTIL(), but when I use it, ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL) will be YIELD. How to make it running when I wait a few seconds.

Related

sleep() in thread causes main to sleep too

I have a gateway server and 2 clients.(made in Oracle VM VirtualBox).
In my gateway server, I have listener.c listening all packets.(in a while(1) loop).
If the client sends a valid token, I have to put it in my authorized MACs list and all packets coming from authorized MACs must be forwarded for 180 secs. (in other words, given internet access for 180 secs).
Before 180 sec., the thing with a single user it was working.
/* authorized MACs list */
char *auth_macs[5];
int client;
pthread_mutex_t lock;
/* after 3 min remove the client from auth list */
void *timer(void *arg){
sleep(180);
pthread_mutex_lock(&lock);
auth_macs[client] = " ";
client--;
pthread_mutex_unlock(&lock);
return NULL;
}
This is how I tried to implement my timer thread. client is a global variable that changes in main function.
if(has_token == 1){
client++;
sprintf(client_ip, "./accept.sh %s", sender);
system(client_ip);
auth_macs[client] = client_mac;
/* start timer thread */
pthread_t tid;
pthread_create(&tid, NULL, timer,NULL);
pthread_join(tid, NULL);
}
This is where I start this thread. accept.sh is a shell script to allow forwarding.
My problem is I thought sleep(180) in timer thread was only going to stop itself. But instead, listener.c stops receiving packets.
How can I fix this? I want timer to wait 180 secs but still be able to receive packets in main function.
sleep() only suspends the calling thread. So, it doesn't affect the main thread.
What's problematic is the pthread_join() call:
pthread_create(&tid, NULL, timer,NULL);
pthread_join(tid, NULL);
This effectively renders the multi-threading pointless. Because there's only thread that's ever going to make progress as the main thread waits until the created thread is completed.
You need to remove pthread_join() call and possibly it outside the while(1) loop if main thread needed to join. Alternatively, you can call pthread_exit(0) outside the thread creation loop so that main completes execution while the rest of the threads, if still alive when main thread
breaks its loop, can continue execution.

C - Debug mode won't acknowledge callback event

I'm trying to write a simple UDP transfer program in Labwindows/CVI.
The idea is it creates 2 UDP channels, uses one to write data to a port, and the other to receive the data and print it out.
Here's the receiving end:
//Called whenever data arrives on port
int CVICALLBACK udpCallback(unsigned channel, int eventType, int errCode, void *callbackData)
{
printf("Callback called\n");
//Gets the data from port
readChannel();
return 0;
}
void createReadChannel()
{
//Channel for given port, receiving from any IP address
CreateUDPChannelConfig(port, UDP_ANY_ADDRESS, 0, NULL, NULL, &readerChannel);
//Attach callback to channel (above)
SetUDPAttribute(readerChannel, ATTR_UDP_CALLBACK, udpCallback);
printf("Read channel created\n");
}
My main problem is just that when I run it in debug mode, the shown callback function is never called, i.e. "Callback called" is not printed, not is any data stored or printed in the resulting readChannel() call.
However, when compiled and executed as an .exe, it works as intended. Every time data is received on that port the callback executes.
What difference could there be between the debug and 'release' version that would cause this to happen?
EDIT: After much testing I believe it has to do with waiting for messages using functions like getchar() which caused the main thread to hang up. Why it worked in release mode I don't know, but it probably has something to do with the difference in output window(?). My solution was to remove the callbacks and run the receiving channel on it's own thread.
This way the thread is always waiting for a message, using:
UDPRead(readerChannel, 0, 0, UDP_WAIT_FOREVER, NULL, NULL)) < 0)
And then my main thread can pick up messages as needed.
If anyone has any additional info let me know.

Implementing a WatchDog timer

I need to implement a timer that checks for conditions every 35 seconds. My program is using IPC schemes to communicate information back and forth between client and server processes. The problem is that I am running msgrcv() function in a loop, which pauses the loop until it finds a message, which is no good because I need the timer to always be checking if a client has stopped sending messages. (if it only checks when it receives a message, this will be useless...)
The problem may seem unclear, but the basics of what I need is a way to implement a Watchdog timer that will check a condition every 35 seconds.
I currently have this code:
time_t start = time(NULL);
//Enter main processing loop
while(running)
{
size_t size = sizeof(StatusMessage) - sizeof(long);
if(msgrcv(messageID, &statusMessage, size, 0, 0) != -1)
{
printf("(SERVER) Message Data (ID #%ld) = %d : %s\n", statusMessage.machineID, statusMessage.status_code, statusMessage.status);
masterList->msgQueueID = messageID;
int numDCs = ++masterList->numberOfDCs;
masterList->dc[numDCs].dcProcessID = (pid_t) statusMessage.machineID;
masterList->dc[numDCs].lastTimeHeardFrom = 1000;
printf("%d\n", masterList->numberOfDCs);
}
printf("%.2f\n", (double) (time(NULL) - start));
}
The only problem is as I stated before, the code to check how much time has passed, won't be reached if there is no message to come in, as the msgrcv function will hold the process.
I hope I am making sense, and that someone will be able to assist me in my problem.
You may want to try the msgctl(msqid, IPC_STAT, struct msqid_ds *msgqdsbuf); If the call is successful, then the current number of messages can be found using msgdsbuf->msg_qnum. The caller needed read permissions, which I think you may have in here.

Signal to print message every 20 seconds (C Multithreaded program)

I am trying to print a message every 20 seconds in a multithreaded program. I have a server that has two threads. One thread waits for incoming connections and makes a new thread for the client when it connects.
I have looked at this: C: SIGALRM - alarm to display message every second but with my code, I'm not sure where I would put the loop. I am not allowed to make a new thread or use sleep() or any variation of sleep().
Code for server acceptor thread:
while((csock = accept(sock, (struct sockaddr *) &theClient, (socklen_t *) &cl)))
{
pthread_t newClient;
new_sock = malloc(sizeof(socket_t));
*new_sock = csock;
pthread_create(&newClient, NULL, getInput, (void *) new_sock)
}
The other thread is just handling the client's input. I tried putting the loop inside the above loop but then it never accepts new connections.
How would I go about doing this? Any help would be appreciated.
Your problem seems to be currently that accept() is blocking the thread until a new connection comes in; therefore you can't print anything.
You could use non-blocking accept() in a loop to check for connections, and in the same loop wait until 20 seconds has passed. Note that this is very inefficient as this loop doesn't stop; it uses 100% of 1 cpu core.
// sock is listening
fcntl(sock,F_SETFD,O_NONBLOCK);
time_t tm = time(); // Unix timestamp, in seconds.
while(true) {
csock = accept(sock, (sockaddr*)&theClient, (socklen_t*)&cl);
if (csock==-1) {
if (errno==EAGAIN || errno==EWOULDBLOCK); // No connection at the
// moment, we need to try
// again later.
else break; // Some other error occurred
}
else { // If it is connected
pthread_t newClient;
new_sock = malloc(sizeof(socket_t));
*new_sock = csock;
pthread_create(&newClient,NULL,getInput,(void*)new_sock);
}
if (time()-tm>=20) { // At least 20 seconds have elapsed since
// last message.
printf("Hello World!!\n");
tm = time(); // Start waiting for another 20 seconds.
}
}
Using select() to wait for a new connection would be far more efficient - you can also set a timeout which expires so that you can print your message
Edit: You don't want to use a signal, because, as it says in the article you linked, you can't use printf from inside a signal handler.
If you use the signal handler to set a flag, you won't be able to read the flag unless you use non-blocking accept() (because otherwise accept() could block for a minute but nothing prints).

Implementing a FCFS scheduler

I am trying to simulate a FCFS scheduler and the way I am doing it is by when a thread comes in it if it isn't in the queue I push it on the queue, but if it is then check to see if the thread is at the head of the queue (first in) and the time remaining for the job is > 0. My problem is how do I put a thread in a wait state until it is the head of the queue? I hear conditional variables might help but not sure how they work.
if (!(is_in_queue(ready_queue, tid))) { //thread is not in the queue
pthread_mutex_lock(&schedule_lock);
ready_queue = enqueue(ready_queue, currentTime, tid, remainingTime, tprio);
pthread_mutex_unlock(&schedule_lock);
}
else{ //thread is in queue
if (tid == head_of_queue(ready_queue) && remainingTime >0) { //need to schedule this thread for full time
return currentTime +1; //schedule on the next unit of "time"
}
else if (tid == head_of_queue(ready_queue) && remainingTime == 0){ //need to go to next task
pthread_mutex_lock(&schedule_lock);
ready_queue = dequeue(ready_queue);
pthread_mutex_unlock(&schedule_lock);
}
else{ //not at the head of the queue
//How do i wait until it is at the head??
}
}
A condition variable allows the OS to suspend the execution of a thread until another thread sends a signal to wake it up. For your else statement you need something like
pthread_cond_wait(&cond_var, &mutex_var);
That will put a thread to sleep. However, you will also need to think about when to wake up the thread. Probably if a thread is not at the head of the queue then you should use pthread_cond_broadcast to wake up all waiting threads. You will also want to have a loop so that each thread checks the condition each time that it is woken up. So your initial if statement should probably be something like a while loop.

Resources