Instead of copying code, I would like to call to another function.
There are two functions, the one function, GetSlaves() returns with a number of slaves found during a scan.
Thing is, I suspect sometimes the returned value is incorrect, while a slave is down or stuck. Therefore I would like to run the GetSlaves function again if I am not happy with the number of slaves found. Please see the code below, questions follow.
SetSlaves(slaves)
{
if (slaves<3 || slaves>6) // I expect 4 or 6 to be found
{
for (tmp2 = 0; tmp2<3; tmp2++) // Try 3 times
{
GetSlaves(); // This function will scan for new slaves and then call SetSlaves(slaves);
}
}
else
{
WriteFlash(VMSSlaves,slaves); // I am happy with what was found, Sets the number of slaves found
}
}
My Question is, when the primary function is called again from the For statement, will it update the slaves variable (for instance a 4 is returned) and exit the IF and thus also the FOR..
Or, will the loop be endless if a slave is down and the two functions will call each other endlessly?
There are some serious control problems here and it may loop forever: when SetSlaves is called with a number of slaves, and the number is not to your liking, GetSlaves is called, which calls SetSlaves. Even if the number is to your liking, it will return, only to be in the loop of tmp2, calling GetSlaves which calls SetSlaves again. If now the number is not to your liking, the whole process repeats and can repeat indefinitly. And note that this is an indirect form of recursion.
My advice would be to have GetSlaves return the number of slaves and that the caller decides whether to call SetSlaves, and not have GetSlaves call SetSlaves.
You are correct. The loop would be endless if the if condition is satisfied and it enters the for loop.
In my opinion, the structure of the code is a bit iffy. I would rather have getslaves just get me number of slaves, and not call setslaves.
Related
I'm trying to understand how curl_multi_perform works.
The documentation says that:
This function performs transfers on all the added handles that need
attention in an non-blocking fashion. The easy handles have previously
been added to the multi handle with curl_multi_add_handle.
When an application has found out there's data available for the
multi_handle or a timeout has elapsed, the application should call
this function to read/write whatever there is to read or write right
now etc.
Question 1: What does the "application should call" mean? How can an application cause something? Did you mean the programmer should call ?
OK, I found two simple usage examples - "curl_multi_perform":
1 - https://everything.curl.dev/libcurl/drive/multi
int transfers_running;
do {
curl_multi_wait ( multi_handle, NULL, 0, 1000, NULL);
curl_multi_perform ( multi_handle, &transfers_running );
} while (transfers_running);
2 - enter link description here
int still_running;
do {
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
if(!mc && still_running)
/* wait for activity, timeout or "nothing" */
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
if(mc) {
fprintf(stderr, "curl_multi_poll() failed, code %d.\n", (int)mc);
break;
}
/* if there are still transfers, loop! */
} while(still_running);
-Firstly:
in the first example curl_multi_perform is called after curl_multi_wait.
in the second example curl_multi_perform is called before curl_multi_wait.
Nothing is clear.
Secondly:
Why do I need to call curl_multi_perform in a loop ?? I do not understand.
Why is one call not enough ?
Question 1: What does the "application should call" mean? How can an application cause something? Did you mean the programmer should call ?
Programmers don't call functions. Programmers write programs that tell the computer what to do. So this means that the programmer should write code that tells the application to call the function.
in the first example curl_multi_perform is called after curl_multi_wait.
in the second example curl_multi_perform is called before curl_multi_wait.
Either order works. As the documentation says:
This function does not require that there actually is any data available for reading or that data can be written, it can be called just in case.
If there's nothing available, it will simply return immediately, updating transfers_running.
Why do I need to call curl_multi_perform in a loop ?? I do not understand.
Because multiple transfers are in progress. curl_multi_wait() returns as soon as data is available on any of them. After you process that data, you need to continue waiting for other transfers.
Also, this doesn't wait for transfers to be complete, it processes partial data as it arrives. So you have to keep calling it until you've sent or received everything.
My Flow has following structure:
StartNode(InjectNode) -> LongRunningFunction(Custom) -> LogNode(File-Write set to Append)
StartNode: just a Inject node that I use to start the flow
LongRunningFunction: the function creates inside a longer for-loop a signal via
node.send(msg)
for(let i = 0; i < 5000000; i++){
node.send({payload: i});
}
this is the full code of the LongRunningNode. Later I want to calculate some message string based on the counter inside the loop, but problem can be reproduced by above code
The file stays empty and the script stops execution after some time. If I connect a debug node as second output to LongRunningFunction the last console output is around 3236831, because the heap-memory is full
Is there a general problem with the structure of my program?
i even tried abusing context by putting
flow.set("pause", true);
while(flow.get("pause")){
}
into the for loop of enter code hereLongRunningFunction and setting "pause" to false again, when a file watch node triggers.
theoretically, this way it should send only 1 signal at a time and wait until the logging finished.
tldr: it never writes anything to the file and heap crashes
Edit: This may possibly be related to the problem:
https://nodejs.org/es/docs/guides/backpressuring-in-streams/
the text is for node.js, so not sure how this is applies to node-red or how to fix it
The problem with your approach of a long running function is that is never yields back to the node.js event loop. That stalls all other activity in the runtime and nothing can make any progress.
The while loop approach is particularly bad; the only thing the runtime can do is sit in that while loop. Nothing else can happen outside of the while loop to change the context value you are testing.
There are lots of different ways to write long running functions using timers and callbacks that allow the node.js event loop to continue processing other events along side. It all depends on what you actually want to do in your flow.
I have been working on this 6502 emulator for a while, and I'm tying to get a simple Enhanced BASIC ROM to work. Although it lacks precise clock timing, the emulator did pass AllSuiteA.asm.
With EhBASIC, I've managed to get some output by printing the value of $F001 when a read is done to that address.
if(lastwrite == 0xF001)
{
printf("%c",CPUMEM[0xF001]);
}
However, I have no idea how to emulate the input process. This post states that whenever EhBASIC wants input, It will poll $F004. But my current code seems to have two problems:
while(1)
{
decodeandexecute();
if(lastread == 0xF004)
{
inputchar = getchar();
CPUMEM[0xF004] = inputchar;
}
if(lastwrite == 0xF001)
{
printf("%c",CPUMEM[0xF001]);
}
}
Input is only possible through individual letters (Expected)
After the program asks for memory size, giving any input will just cause a loop of reading from $F004 (LDA $F004) - i.e. I can't let EhBASIC know when to stop receiving inputs
I want to know an effective method of entering a string of characters, and getting passed "memory size?".
Additionally, if I want to let EhBASIC calculate the memory size automatically, what should I input to $F004?
I'm pretty much a newbie in this area....
I see you use getchar in the code and if I remember correctly that is a blocking call (it will wait until someone presses some key).
In the manual of ehbasic it says:
How to.
The interpreter calls the system routines via RAM based vectors and,
as long as the requirements for each routine are met, these can be changed
on the fly if needs be.
All the routines exit via an RTS.
The routines are ...
Input
This is a non halting scan of the input device. If a character is ready it
should be placed in A and the carry flag set, if there is no character then A,
and the carry flag, should be cleared.
One way to deal with this is to use two threads. One thread that runs the emulation of the 6502 running ehbasic and another thread that polls the keyboard.
Then let the polling thread push any input key strokes into a small buffer from which the ehbasic input routine can use.
Manual: http://www.sunrise-ev.com/photos/6502/EhBASIC-manual.pdf
UPDATE
Reading the question/answer you linked to, I see it is a modified ehbasic.
Your keyboard polling thread should place the keystrokes read in $F004 (and after a while clear F004 again - if I understand the instructions).
UPDATE 2
As a debugging tip: In you first version simply have a string with a fixed input such as 10 print "hello" 20 goto 10 and feed $f004 from there. That way you don't have to worry about any problems with using an actual keyboard.
I have an interrupt function called, interrupt_Foo() {...} which turns on a flag when 1 second has elapsed, and a user-defined function foo_calling() {...} which calls another function foo_called() {...}. I want to stop the process in foo_called() when 1 second has elapsed.
The code snippet below may elaborate further my need:
void interrupt interrupt_foo() {
...
if(1 second has elapsed) {
flag1s = 1;
} else {
flag1s = 0;
}
}
void foo_calling() {
// need something here to stop the process of foo_called()
...
(*fptr_called)(); // ptr to function which points to foo_called
...
}
void foo_called() {
// or something here to stop the process of this function
...
// long code
...
}
This is real time operating system so polling the 1 second flag inside foo_called() at some portion in the code is undesirable. Please help.
If you are willing to write non-portable code, and test the heck out of it before deploying it, and if the processor supports it, there may be a solution.
When the interrupt handler is called, the return address must be stored somewhere. If that is a location your code can query - like a fixed offset down the stack - then you can compare that address to the range occupied by your function to determine if 'foo_called is executing. You can get the address of the function by storing a dummy address, compiling, parsing the map file, then updating the address and recompiling.
Then, if your processor supports it, you can replace the return address with the address of the last instruction(s) of foo_called. (make sure you include the stack cleanup and register restoration code.). Then exit the interrupt as normal, and the interrupt handling logic will return code to the end of your interrupted function.
If the return address is not stored in the stack, but in an unwritable register, you still may be able to force quit your function - if the executable code is in writrable memory. Just store the instruction at the interruupt's return address, then overwrite it with a jump instruction which jumps to the function end. In the caller code, add a detector which restored the overwritten instruction.
I would expect that your RTOS has some kind of timer signal/interrupt that you can use to notify you when one second has passed. For instance if it is a realtime UNIX/Linux then you would set a signal handler for SIGALRM for one second. On a RT variant of Linux this signal will have more granularity and better guarantees than on a non-RT variant. But it is still a good idea to set the signal for slightly less than a second and busy-wait (loop) until you reach one second.
I have a program running two threads - they communicate using message queues.
In one thread, I call ioctl() to access the hardware decryptor. The code goes like:
void Decrypt
{
...
..
...
if(<condition 1>)
{.
...
...
retVal = ioctl(...);
comesInHere1++;
}
if(<condition 2>)
{
...
...
retVal = ioctl(...);
comesInHere2++;
}
comesInHere1 and comesInHere2 are used to count the number of times it goes in that particular if loop.
The entire program takes 80 ms to execute. But if I comment out the test variables (comesInHere1, comesInHere2 within the if loops), the execution time increases by 8 ms to 88 ms!
How is that possible? I cant comment out the variables now since it increases the time taken, cant keep them either - will get killed in code review :)
Kindly let me know
Thanks
Cache? It's possible that by adding a bit more data you're moving code to different cache lines that would somehow be placed together, causing thrashing. You could experiment by running on different systems and by adding padding data between variables that are used exclusively in each thread.
What happens if you serialize the processing onto a single core?