What is the valid use case to call vkQueueSubmit with VkSubmitInfo command buffers parameters set to 0 count and nullptr pointer?
Example code:
VkFenceCreateInfo fenceInfo{};
VkFence fence;
vkCreateFence(device, &fenceInfo, nullptr, &fence);
std::vector<VkSubmitInfo> submitInfos;
VkSubmitInfo submitInfo{};
...
submitInfo.commandBufferCount = 0;
submitInfo.pCommandBuffers = nullptr;
...
submitInfos.push_back(submitInfo);
vkQueueSubmit(queue, submitInfos.size(), submitInfos.data(), fence);
I can think just about one thing and that is signaling the fence, but it makes no sense for me to do it this way (as it can be reseted or created in signaled state).
Is there any (other) valid use case for doing so?
I'm starter of RTOS and I'm using Xenomai v2.6.3.
I'm trying to get some data using Serial communication.
I did my best on the task following the xenomai's guide and open sources, but it doesn't work well.
the link of the guide --> (https://xenomai.org//serial-16550a-driver/)
I just followed the sequence to use the module xeno_16550A. (with port io = 0x2f8 and irq=3)
I followed open source http://www.acadis.org/pages/captain.at/serial-port-example
It works well in write task, but read task doesn't work well.
It gave me the error sentence with error while RTSER_RTIOC_WAIT_EVENT, code -110 (it means connection timed out)
Moreover I checked the irq number3 by typing command 'cat /proc/xenomai/irq', but the interrupt number doesn't increase.
In my case, I don't need to write data, so I erase the write task code.
The read task proc is follow
void read_task_proc(void *arg) {
int ret;
ssize_t red = 0;
struct rtser_event rx_event;
while (1) {
/* waiting for event */
ret = rt_dev_ioctl(my_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event );
if (ret) {
printf(RTASK_PREFIX "error while RTSER_RTIOC_WAIT_EVENT, code %d\n",ret);
if (ret == -ETIMEDOUT)
continue;
break;
}
unsigned char buf[1];
red = rt_dev_read(my_fd, &buf, 1);
if (red < 0 ) {
printf(RTASK_PREFIX "error while rt_dev_read, code %d\n",red);
} else {
printf(RTASK_PREFIX "only %d byte received , char : %c\n",red,buf[0]);
}
}
exit_read_task:
if (my_state & STATE_FILE_OPENED) {
if (!close_file( my_fd, READ_FILE " (rtser)")) {
my_state &= ~STATE_FILE_OPENED;
}
}
printf(RTASK_PREFIX "exit\n");
}
I could guess the causes of the problem.
buffer size or buffer is already full when new data is received.
rx_interrupt doesn't work....
I want to check whether the two things are wrong or not, but How can I check?
Furthermore, does anybody know the cause of the problem? Please give me comments.
I'm building a DNS client. A child process handles the request through an UDP socket, while the parent handles the reply. I need the parent to know how many bytes were sent, in order to print the URLs. I tried the following approach with pipe()
childPID = fork();
pipe(fd);
if(childPID == 0){
close(fd[0]);
sent_bytes = sendDNS(sock_udp, &serverAddr, argv[2]);
memcpy(in_buf, &sent_bytes, sizeof(sent_bytes));
write(fd[1], in_buf, sizeof(sent_bytes));
exit(0);
}
else{
close(fd[1]);
int inBytes = -1;
struct sockaddr reply_addr;
n = sizeof(reply_addr);
while(inBytes < 0){
inBytes = recvfrom(sock_udp, buffer, DNS_MAX_RESPONSE, 0, &reply_addr, (socklen_t*)&n);
read(fd[0], out_buf, sizeof(sent_bytes));
memcpy(pipe_msg, out_buf, sizeof(sent_bytes));
printDNSmsg((struct dnsReply*)buffer);
}
}
But GDB shows a SIGPIPE received on the child process. What am I missing?
How would you print a DNS reply (variable length buffer)?
You need to call pipe() before fork(), of course. But you're not actually using the information anywhere. Why do you care how many bytes were sent, as long as you got a reply? And why would you do a UDP send in a separate thread, let alone a separate process? It all seems completely pointless.
This is a follow-up to this previous question of mine, for which the conclusion was that the program was erroneous, and therefore the expected behavior was undefined.
What I'm trying to create here is a simple error-handling mechanism, for which I use that Irecv request for the empty message as an "abort handle", attaching it to my normal MPI_Wait call (and turning it into MPI_WaitAny), in order to allow me to unblock process 1 in case an error occurs on process 0 and it can no longer reach the point where it's supposed to post the matching MPI_Recv.
What's happening is that, due to internal message buffering, the MPI_Isend may succeed right away, without the other process being able to post the matching MPI_Recv. So there's no way of canceling it anymore.
I was hoping that once all processes call MPI_Comm_free I can just forget about that message once and for all, but, as it turns out, that's not the case. Instead, it's being delivered to the MPI_Recv in the following communicator.
So my questions are:
Is this also an erroneous program, or is it a bug in the MPI implementation (Intel MPI 4.0.3)?
If I turn my MPI_Isend calls into MPI_Issend, the program works as expected - can I at least in that case rest assured that the program is correct?
Am I reinventing the wheel here? Is there a simpler way to achieve this?
Again, any feedback is much appreciated!
#include "stdio.h"
#include "unistd.h"
#include "mpi.h"
#include "time.h"
#include "stdlib.h"
int main(int argc, char* argv[]) {
int rank, size;
MPI_Group group;
MPI_Comm my_comm;
srand(time(NULL));
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_group(MPI_COMM_WORLD, &group);
MPI_Comm_create(MPI_COMM_WORLD, group, &my_comm);
if (rank == 0) printf("created communicator %d\n", my_comm);
if (rank == 1) {
MPI_Request req[2];
int msg = 123, which;
MPI_Isend(&msg, 1, MPI_INT, 0, 0, my_comm, &req[0]);
MPI_Irecv(NULL, 0, MPI_INT, 0, 0, my_comm, &req[1]);
MPI_Waitany(2, req, &which, MPI_STATUS_IGNORE);
MPI_Barrier(my_comm);
if (which == 0) {
printf("rank 1: send succeed; cancelling abort handle\n");
MPI_Cancel(&req[1]);
MPI_Wait(&req[1], MPI_STATUS_IGNORE);
} else {
printf("rank 1: send aborted; cancelling send request\n");
MPI_Cancel(&req[0]);
MPI_Wait(&req[0], MPI_STATUS_IGNORE);
}
} else {
MPI_Request req;
int msg, r = rand() % 2;
if (r) {
printf("rank 0: receiving message\n");
MPI_Recv(&msg, 1, MPI_INT, 1, 0, my_comm, MPI_STATUS_IGNORE);
} else {
printf("rank 0: sending abort message\n");
MPI_Isend(NULL, 0, MPI_INT, 1, 0, my_comm, &req);
}
MPI_Barrier(my_comm);
if (!r) {
MPI_Cancel(&req);
MPI_Wait(&req, MPI_STATUS_IGNORE);
}
}
if (rank == 0) printf("freeing communicator %d\n", my_comm);
MPI_Comm_free(&my_comm);
sleep(2);
MPI_Comm_create(MPI_COMM_WORLD, group, &my_comm);
if (rank == 0) printf("created communicator %d\n", my_comm);
if (rank == 0) {
MPI_Request req;
MPI_Status status;
int msg, cancelled;
MPI_Irecv(&msg, 1, MPI_INT, 1, 0, my_comm, &req);
sleep(1);
MPI_Cancel(&req);
MPI_Wait(&req, &status);
MPI_Test_cancelled(&status, &cancelled);
if (cancelled) {
printf("rank 0: receive cancelled\n");
} else {
printf("rank 0: OLD MESSAGE RECEIVED!!!\n");
}
}
if (rank == 0) printf("freeing communicator %d\n", my_comm);
MPI_Comm_free(&my_comm);
MPI_Finalize();
return 0;
}
outputs:
created communicator -2080374784
rank 0: sending abort message
rank 1: send succeed; cancelling abort handle
freeing communicator -2080374784
created communicator -2080374784
rank 0: STRAY MESSAGE RECEIVED!!!
freeing communicator -2080374784
As mentioned in one of the above comments by #kraffenetti, this is an erroneous program because the sent messages are not being matched by receives. Even though the messages are cancelled, they still need to have a matching receive on the remote side because it's possible that the cancel might not be successful for sent messages due to the fact that they were already sent before the cancel can be completed (which is the case here).
This question started a thread on this on a ticket for MPICH, which you can find here that has more details.
I tried to build your code using open mpi and it did not work. mpicc complained about status.cancelled
error: ‘MPI_Status’ has no member named ‘cancelled’
I suppose this is a feature of intel mpi. What happens if you switch for :
...
int flag;
MPI_Test_cancelled(&status, &flag);
if (flag) {
...
This gives the expected output using open mpi (and it makes your code less dependant). Is it the case using intel mpi ?
We need an expert to tell us what is status.cancelled in intel mpi, because i don't know anything about it !
Edit : i tested my answer many times and i found that the output was random, sometimes correct, sometimes not. Sorry for that... As if something in status was not set. Part of the answer may be in MPI_Wait(), http://www.mpich.org/static/docs/v3.1/www3/MPI_Wait.html ,
" The MPI_ERROR field of the status return is only set if the return from the MPI routine is MPI_ERR_IN_STATUS. That error class is only returned by the routines that take an array of status arguments (MPI_Testall, MPI_Testsome, MPI_Waitall, and MPI_Waitsome). In all other cases, the value of the MPI_ERROR field in the status is unchanged. See section 3.2.5 in the MPI-1.1 specification for the exact text. " If MPI_Test_cancelled() makes use of the MPI_ERROR, things might get bad.
So here is the trick : use MPI_Waitall(1,&req, &status) ! The output is correct at last !
I have a program where i ssh into a server and gets data. Here is the code... I fork it and the child executes the query and the parent waits for the child for a predetermined amount of time (in function timeout) and then kills the child. I did that part because sometimes, i am not exactly sure why, but the ssh connection stops and doesnot exit. That is there is a "ssh -oConnectTimeout=60 blah blah" in the processes list for a long and the timeout function doesnt seem to work. What am i doing wrong here? The last time this problem occured, there was an ssh in process list for 5 days and still it didnot timeout and the program had stopped because it was waiting for the child. There are those extra wait() functions because previously i was getting a lot of defunct processes a.k.a zombies. So i took the easy way out..
c = fork();
if(c==0) {
close(fd[READ]);
if (dup2(fd[WRITE],STDOUT_FILENO) != -1)
execlp("ssh", "ssh -oConnectTimeout=60", serverDetails.c_str(), NULL);
_exit(1);
}else{
if(timeout(c) == 1){
kill(c,SIGTERM);
waitpid(c, &exitStatus, WNOHANG);
wait(&exitStatus);
return 0;
}
wait(&exitStatus);
}
This is the timeout function.
int timeout(int childPID)
{
int times = 0, max_times = 10, status, rc;
while (times < max_times){
sleep(5);
rc = waitpid(childPID, &status, WNOHANG);
if(rc < 0){
perror("waitpid");
exit(1);
}
if(WIFEXITED(status) || WIFSIGNALED(status)){
/* child exits */
break;
}
times++;
}
if (times >= max_times){
return 1;
}
else return 0;
}
SIGTERM just asks for a polite termination of the process. If it's got stuck, then it won't respond to that, and you'll need to use SIGKILL to kill it. Probably after trying SIGTERM and waiting a little while.
The other possibility is that it's waiting for the output pipe to the parent process to not be full - maybe there's enough output to fill the buffer, and the child is waiting on that rather than the network.