Wait for a VkFence in a thread before it has been submitted by another thread - vulkan

I'm implementing asynchronous VkCommandBuffer recording to improve geometry and texture loading in my rendering engine.
I'm facing validation issue about VkFence being in use in two different threads:
UNASSIGNED-Threading-MultipleThreads(ERROR / SPEC): msgNum: 337425955 - Validation Error: [ UNASSIGNED-Threading-MultipleThreads ] Object 0: handle = 0x90a67000000088d3, type = VK_OBJECT_TYPE_FENCE; | MessageID = 0x141cb623 | THREADING ERROR : vkQueueSubmit(): object of type VkFence is simultaneously used in thread 0x3344 and thread 0x2d3c
I've written a minimal example to reproduce my issue here: https://gist.github.com/siliace/fc2633ee2406d3cbc53a60857bb14776
When on line 18, gSubmitBeforeWaitFence is false, the worker thread will not wait until the main thread submitted the fence to wait for it, causing my validations errors.
When gSubmitBeforeWaitFence is true, everything is fine.
Is it a bug of the validation layer and I should not have to wait for a VkFence to be submitted before waiting for it? Or is it a mistake from me? I would expect vkWaitForFences to be read-only operation so I don't see the point of forbiding this use.
And if my usage is wrong, is it written somewhere in the spec? I could not find it neighter in the documentation of vkQueueSubmut nor vkWaitForFences.
Thanks for your help !

It is not allowed to use a fence while it is being vkQueueSubmited:
Host Synchronization
Host access to queue must be externally synchronized
Host access to fence must be externally synchronized

Related

OpenThread otJoinerStart Never Times Out

I am trying to integrate OpenThread child with an existing application on the TI CC2652R1 and am having issues trying to join/create a Thread network. Currently I have an external event that calls a function to join and start OpenThread. Below is a snip of this function relating to the join:
bool is_commissioned = otDatasetIsCommissioned(OtStack_instance);
otJoinerState joiner_state = otJoinerGetState(OtStack_instance);
if(!is_commissioned && (OT_JOINER_STATE_IDLE == joiner_state)){
otError error = otIp6SetEnabled(OtStack_instance, true);
error = otThreadSetEnabled(OtStack_instance, true);
error = otJoinerStart(OtStack_instance, "PSK", NULL, "Company", "Device", "0.0.0", NULL, joiner_callback, NULL);
}
otJoinerStart never seems to resolve because joiner callback never is called and additional calls to my joining function show that the joiner state is OT_JOINER_STATE_DISCOVER and the OpenThread instance says that it is initialized. Is there a way to set the joiner callback timeout? I have looked through the documentation and could not find out how the join timeout is set.
Thanks
Joining a Thread device to a Thread network assumes that you have a Thread network running and there is an active commissioner with the joiner's EUI64 and PSK. Make sure that these are setup before you try and call this function to join. It is also helpful to have a sniffer running on the Thread network's channel to ensure the commissioner or joiner router is responding properly.
Joining in Thread is done with an active scan on all the available channels in the IEEE 802.15.4 page 0. The time to send a Joiner request and the time the joiner waits on each channel is not immediately configurable. However these active scans usually complete within a few seconds. Your joiner callback should be getting called with a join failed condition if there are no available joiner routers in about 5 seconds.
The examples in the OpenThread github repository are written in a nortos fashion. Any application code is run in a tasklet and the main loop only calls two functions; process tasklets and process drivers. In the TI SDK we use TI-RTOS and you seem to have based your code on these examples. In general the OtStack_Task will handle processing of OpenThread and the platform driver interface; but deadlocks in a multi-threaded system can occur.
You can use ROV in CCS or IAR to check the state of the kernel and RTOS objects. In CCS with an active debug session, select; Tools >> Runtime Object View. Then check if the stack task is blocking on the API semaphore. Or if the application task is hogging up the processor. This can be due to an unpaired lock/unlock on the API semaphore, or the application task may be in a busy wait.
Immediately I don't see anything wrong with the code snippet posted.

Is there a way to register to memory alarm of rabbitmq

My application just got freeze because the memory usage of rabbitmq exceeded its threshold.
I am using pika and pyrabbit as a python wrappers for handling channels and connections.
I wander if there is a way that my process will register to something and get a notification when that event occurs (and hopefully even a bit before it does).
When using rabbitpy you can check if the blocked flag is set. This flag means that the connection is being blocked due to resource constraints (most likely due to low memory).
with rabbitpy.Connection('amqp://guest:guest#localhost:5672/%2f') as conn:
print(conn.blocked)
e.g.
while conn.blocked:
time.sleep(0.1) # wait until connection is unblocked

Need to hold request for a thread until previous request is finished

I am looking for a technique to hold off on requesting a thread (background worker, Task, etc,) from starting while a previous thread is still processing. The thread has an object writer and if it is busy I cannot use it in the next thread until it finishes its write.
Note, that the processing that occurs before each thread request is sufficiently long enough that there should not be an issue, this is just precautionary.
I am guessing that how I request the thread here is critical to having some sort of response back that will allow the next thread to get called. But I could use some help on how to set this up. If anyone has a specific scenario of similar design I would be happy researching the recommended technique. Sort of new to this sort of thread processing.
vb.net
I'm not sure how you plan on implementing this, but you should try and use the TPL vs. using Threads directly. With Tasks, you can wait on them to complete.
See the following example https://msdn.microsoft.com/en-us/library/dd537610(v=vs.100).aspx
And read the following on Threads vs. Tasks if you need more information on the differences.
http://blog.slaks.net/2013-10-11/threads-vs-tasks/
Typically mutexes are used for synchronization.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684266(v=vs.85).aspx
Note that you'll also need handle WAIT_ABANDONED, which is the status when a thread that had the mutex dies instead of finishing.
Examples and more info for .Net here: https://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx

what's different between the Blocked and Busy Waiting?

I known the implement of Busy Waiting. it's a death loop like this:
//main thread
while (true) {
msg = msgQueue.next();
msg.runnable.run();
}
//....msg queue
public Message next() {
while (true) {
if (!queue.isEmpty()) {
return queue.dequeue();
}
}
}
so, the method "next()" just looks like blocked, actually it runs all the time.
this was called "busy waiting" on book.
and what's the "process blocked"? what about its implement details?
is a death loop too? or some others? like signal mechanism?
For instance:
cat xxx | grep "abc"
process "cat" read a file and output them.
process "grep" waiting for input from "cat".
so before the "cat" output data, "grep" should be blocked, waiting for input and go on.
what details about this "blocked", a death loop read the input stream all the time? or really stop running, waiting a signal to wake up it to run?
The difference is basically in what happens to the process:
1. Busy Waiting
A process that is busy waiting is essentially continuously running, asking "Are we there yet? Are we there yet? How about now, are we there yet?" which consumes 100% of CPU cycles with this question:
bool are_we_there = false;
while(!are_we_there)
{
// ask if we're there (without blocking)
are_we_there = ask_if_we_are_there();
}
2. A process that is blocked (or that blocks)
A process that is blocked is suspended by the operating system and will be automatically notified when the data that it is waiting on becomes available. This cannot be accomplished without assistance from the operating system.
And example is a process that is waiting for a long-running I/O operation, or waiting for a timer to expire:
// use a system call to create a waitable timer
var timer = CreateWaitableTime()
// use another system call that waits on a waitable object
WaitFor(timer); // this will block the current thread until the timer is signaled
// .. some time in the future, the timer might expire and it's object will be signaled
// causing the WaitFor(timer) call to resume operation
UPDATE
Waitable objects may be implemented in different ways at the operating system level, but generally it's probably going to be a combination of hardware timers, interrupts and lists of waitable objects that are registered with the operating system by client code. When an interrupt occurs, the operating system's interrupt handler is called which in turn will scan though any waitable objects associated with that event, and invoke certain callback which in turn will eventually signal the waitable objects (put them in a signaled state). This is an over-simplification but if you'd like to learn more you could read up on interrupts and hardware timers.
When you say "a process is blocked" you actually mean "a thread is blocked" because those are the only schedulable entities getting CPU time. When a thread is busy waiting, it wastes CPU time in a loop. When a thread is blocked, the kernel code inside the system call sees that data or lock is not immediately available so it marks the thread as waiting. It then jumps to the scheduler which picks up another thread ready for execution. Such a code in a blocking system call might look like this:
100: if (data_available()) {
101: return;
102: } else {
103: jump_to_scheduler();
104: }
Later on the thread is rescheduled and restarts at line 100 but it immediately gets to the else branch and gets off the CPU again. When data becomes available, the system call finally returns.
Don't take this verbatim, it's my guess based on what I know about operating systems, but you should get the idea.

What happens when a thread makes kernel disable the interrupts and then that thread goes to sleep

I have this kernel code where I disable the interrupt to make this lock acquire operation atomic, but if u see the last else condition i.e. when lock is not available thread goes to sleep and interrupts are enable only after thread comes back from sleep. My question is so interrupts are disabled for whole OS until this thread comes out of sleep?
void Lock::Acquire()
{
IntStatus oldLevel = interrupt->SetLevel(IntOff); // Disabling the interrups to make the following statements atomic
if(lockOwnerThread == currentThread) //Checking if the requesting thread already owns lock
{
//printf("SM:error:%s already owns the lock\n",currentThread->getName());
DEBUG('z', "SM:error:%s already owns the lock\n",currentThread->getName());
(void) interrupt->SetLevel(oldLevel);
return;
}
if(lockOwnerThread==NULL)
{
lockOwnerThread = currentThread; // Lock owner ship is given to current thread
DEBUG('z', "SM:The ownership of the lock %s is given to %s \n",name,currentThread->getName());
}
else
{
DEBUG('z', "SM:Adding thread %s to request queue and putting it to sleep\n",currentThread->getName());
queueForLock->Append((void *)currentThread); // Lock is busy so add the thread to queue;
currentThread->Sleep(); // And go to sleep
}
(void) interrupt->SetLevel(oldLevel); // Enable the interrupts
}
I don't know the NACHOS and I would not make any assumptions on my own. So you have to test it.
The idea is simple. If this interrupt enable/disable functionality is local to the current process context then the following should happen when you call Sleep():
the process is marked as not-running, i.e. it is excluded from the list of processes the scheduler will consider to give a CPU time. Then the Sleep() function enforces the scheduler to do it's regular work - to find a process to run. If the list of running processes is not empty, the scheduler picks up a next available process and makes a context switch to this process. After this the state of interrupt management is restored from this new context.
If there are no processes to run then scheduler enters the Idle loop state and usually enables the interrupts. While the scheduler is in Idle loop it continues to poll the queue of the running processes until it get something to schedule.
Your process will get the control when it will be marked as running again. This could happen if some other process calls WakeUp() (or a like, as I mentioned the API is unknown to me)
When the scheduler will pick up your process to switch to it performs the usual (for your system) context switch that has the interrupts enabled flag set to false, so the execution continues at statement after the Sleep() call with interrupts disabled.
If the assumptions above are incorrect and the interrupts enabled flag is global, then there are two possibilities: either the system hangs as it can't serve the interrupts, or it has some workaround for such a situations.
So, you need to try. The best way is to read the kernel sources of course, if you have the access.))