United States-English |
|
|
HP-UX Reference > Hhg(3)Mercury LibraryHP-UX 11i Version 3: February 2007 |
|
NAMEhg: hg_busywait(), hg_context_switch_involuntary(), hg_context_switch_tries(), hg_context_switch_voluntary(), hg_gethrcycles(), hg_gethrtime(), hg_getspu(), hg_nano_to_cycle_ratio(), hg_public_init(), hg_public_is_onRunQ(), hg_public_is_reporting(), hg_public_is_running(), hg_public_nMailboxes(), hg_public_nMailboxesInUse(), hg_public_remove(), hg_setcrit() — Mercury Library Interfaces to transfer data between user and kernel space in a lightweight manner SYNOPSIS#include<sys/mercury.h> cc flags filename -lhg Mercury Public Interfacesuint64_t hg_public_init(void); uint64_t hg_public_remove(void); uint64_t hg_public_is_reporting(uint64_t hg_public_handle); uint64_t hg_public_is_running(uint64_t hg_public_handle); uint64_t hg_public_is_onRunQ(uint64_t hg_public_handle); uint64_t hg_public_nMailboxes(void); uint64_t hg_public_nMailboxesInUse(void); Mercury Private Interfacesuint64_t hg_gethrcycles(void); uint64_t hg_gethrtime(void); double hg_nano_to_cycle_ratio(void); uint64_t hg_busywait(double seconds); spu_t hg_getspu(void); uint64_t hg_context_switch_tries(void); uint64_t hg_context_switch_involuntary(void); uint64_t hg_context_switch_voluntary(void); uint64_t hg_setcrit(unsigned long on_or_off, int willing_to_block); DESCRIPTIONThe Mercury Library Interface (HG) provides a high performance interface between user programs and the kernel, making it possible to transfer key pieces of information back and forth at high speed. Communication between the user space and kernel is relatively slow due to the overhead of making a system call. The Mercury APIs help by avoiding most or all of this overhead. The information exchanged can be divided into two broad categories:
A thread needs to register before any other thread can view its public information. There is no need to register to view the information of other threads. If a thread does register itself, it is provided a handle, which may be communicated to other threads. Mercury Library provides APIs that query the handle for the underlying thread's run state. Hence the thread is recognized by the handle assigned to it. The run state information of any thread is stored in a publicly available user-mapped mailbox. The kernel continually posts and updates the run state of the calling kernel thread in the mailbox, when possible. Keep in mind that all information is to be regarded as hints about the state and that no guarantees are implied, from any of the APIs providing the run state information on threads, although a good faith effort is made to keep it accurate. If you are using MxN threads, the use of the Mercury library public interface is not recommended. This is because the state shown by the interface is always that of the underlying kernel thread. Therefore a thread of scope PTHREAD_FORCE_SCOPE_PROCESS, which moves from kernel thread to kernel thread, would have confusing information reported about it. Always use PTHREAD_FORCE_SCOPE_SYSTEM for all threads if you are using the Mercury public interface. The default scope of threads on systems which can use Mercury is PTHREAD_FORCE_SCOPE_SYSTEM. So one can use Mercury on such systems without having to change the scope. For more information, see pthread_attr_setscope(3T). A context switch is the act of a thread ceasing to run on a cpu for some reason and then later starting to run again; this pair of actions is one context switch ("switching out" then "switching in"). A "voluntary" context switch is one that is caused by something the thread does that requires it to stop running. For example, a thread calling sched_yield() or a thread blocking for a page fault. An "involuntary" context switch is one that is imposed on the thread by the operating system for policy reasons. For example, the operating system switching a thread out to run a higher priority thread. libhg Public InterfacesThese are the public interface provided by libhg:
libhg Priviate InterfacesThese are the private interface provided by libhg:
RETURN VALUEShg_public_init() returns the address of the mailbox if the call is successful, NULL otherwise. hg_public_remove() returns the value 1, in case of success. hg_public_is_reporting() will return zero if not reporting and non-zero if reporting hg_public_is_running() will return zero if not running and non-zero if running. hg_public_is_onRunQ() will return 0 if not on run queue and non-zero if on run queue. hg_public_nMailboxes() returns the total number of mailboxes available for attachment. hg_public_nMailboxesInUse() returns the number of mailboxes available for attachment at the time of calling. hg_gethrcycles() returns the number of machine cycles since the machine was booted. hg_gethrtime() returns the number of nanoseconds since the machine was booted. hg_nano_to_cycle_ratio() returns the number of nanoseconds/machine cycle for that processor in specific. hg_busywait() returns 0 on successful completion. hg_getspu() returns the number of the processor the thread is running on. hg_context_switch_tries() returns the total number of times the kernel thread has switched out (or at least attempted to switch out). hg_context_switch_involuntary() returns the number of times the kernel thread has involuntarily switched out. hg_context_switch_voluntary() returns the number of times the kernel thread has voluntarily switched out. hg_setcrit() returns the number of times the thread has yielded the processor. ERRORSThe only error returned by the libhg APIs is HG_ERROR. This will be returned if any of the following calls fail: hg_public_init(), hg_public_nMailboxes(), hg_public_nMailboxesInUse(), and hg_busywait(). EXAMPLESBelow is a scenario on how an application may use Mercury APIs achieve performance. Since threads may remove mailboxes at any point of time, hg_public_is_reporting() can help us find that. If the mailbox is still in use, the run state of the thread associated with it can be obtained. This can be important at times because if a thread has detached the mailbox, but since the mailbox still remains mapped, the probing thread may obtain incorrect information about the thread being probed. Another situation could be that even if the mailbox is in use, it may have been given up by the previous thread and reassigned to a completely new thread. The kernel is less likely to preempt a thread when it's running in a critical region than when it's not. Therefore, code regions where locks are held are good places to mark as critical since application throughput can drop dramatically if a thread holding critical resources stops running while other threads are waiting to acquire those resources. Since hg_setcrit() does not enter the kernel, it is very fast and does not significantly increase the length of critical paths. If setting willing_to_block to 1 (instead of 0), hg_setcrit() will yield the processor, if necessary, prior to beginning the critical region to reduce the likelihood of being preempted within the critical region. Here is one recommended sequence: hg_setcrit(lock_address, WILLING_TO_BLOCK); acquire lock critical region release lock hg_setcrit(CRIT_OFF, UNWILLING_TO_BLOCK); Alternately, hg_setcrit(lock_address, UNWILLING_TO_BLOCK); acquire lock critical region release lock hg_setcrit(CRIT_OFF, WILLING_TO_BLOCK); Or ... hg_setcrit(lock_address, WILLING_TO_BLOCK); acquire lock critical region release lock hg_setcrit(CRIT_OFF, WILLING_TO_BLOCK); It is never absolutely necessary to set WILLING_TO_BLOCK, but it reduces your chances of being switched out during the critical region. Remember that WILLING_TO_BLOCK means that you are willing to block during the hg_setcrit() call, not during the critical region. NoteAll information returned by the initiative should be considered hints. By their very nature, and the nature of scheduling user processes and threads, much of this information can theoretically be stale immediately after its delivery to the user, or at any time after that. User code must take this into account in its design. The libpthread library links with the Mercury Library in order to decide on the scheduling of threads at any point of time. Hence, applications which are using both, libpthread and libhg need to take care that libpthread is already using libhg for scheduling decisions. The applications may still however use the Mercury APIs if they feel the need to do so. |
Printable version | ||
|