Yield the CPU VP
To preserve the availability of the CPU VP, a well-behaved C UDR must ensure that it regularly yields the CPU VP to other threads. A C UDR might yield when it calls a DataBlade API function because DataBlade API functions automatically yield the VP when appropriate.
- Smart-large-object I/O with a DataBlade API function such as mi_lo_open(), mi_lo_read(), or mi_lo_write()
- External-file I/O with a DataBlade API file-access function such as mi_file_open(), mi_file_read(), or mi_file_write()
Therefore, you can assume that thread migration might occur during execution of any DataBlade API function.
- A task that is CPU- or I/O-bound
- A task that causes other threads to wait for an undue length of time (usually longer than 0.1 seconds)
For such a C UDR to be well-behaved, it must explicitly yield the CPU VP with the DataBlade API function mi_yield(). The mi_yield() function causes the thread that is executing the UDR to voluntarily yield the CPU VP so that other threads get a chance to execute in the VP. When the original thread is ready to continue execution, execution resumes at the point immediately after the call to the mi_yield() function.
Write your C UDR so that it yields the VP at strategic points in its processing. Possible points include the beginning or end of lengthy loops and before and/or after expensive computations. Judicious use of mi_yield() generally leads to an improved response time overall.
If you cannot code the C UDR to explicitly yield during resource-intensive passages of code, the UDR is considered an ill-behaved routine and must not execute in the CPU VP. To isolate a resource-intensive UDR from the CPU VP, you can assign the routine to a user-defined VP class. To determine which kind of user-defined VP to define, you must also consider whether you need to preserve availability of the user-defined VP. Keep in mind that all VPs of a class share a thread queue. If there are multiple users of your UDR, multiple threads can accumulate in the same thread queue. If your UDR does not yield, it blocks other UDRs that execute in the same VP class. Therefore, the VP might not effectively share between users. One user might have to wait while the UDR in the query of some other user completes.
- To preserve availability of a user-defined VP, execute the routine
in a yielding user-defined VP.
Within your UDR, you can use the mi_yield() function to yield the user-defined VP to other threads that execute in the same VP class. To increase availability, you can define multiple instances of the yielding user-defined VP.
- If you cannot rewrite the routine to yield, add more user-defined
VPs.
A nonyielding user-defined VP is used for code that must maintain ownership of the process until it completes. A nonyielding VP might modify a global variable or use a command resource that cannot be shared.