€•a{Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ,/translations/zh_CN/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/zh_TW/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/it_IT/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ja_JP/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/ko_KR/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/pt_BR/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ,/translations/sp_SP/locking/robust-futex-ABI”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒThe robust futex ABI”h]”hŒThe robust futex ABI”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒF/var/lib/git/docbuild/linux/Documentation/locking/robust-futex-ABI.rst”h´KubhŒ field_list”“”)”}”(hhh]”hŒfield”“”)”}”(hhh]”(hŒ field_name”“”)”}”(hŒAuthor”h]”hŒAuthor”…””}”(hh×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÕhhÒh³hÊh´KubhŒ field_body”“”)”}”(hŒ&Started by Paul Jackson ”h]”hŒ paragraph”“”)”}”(hŒ$Started by Paul Jackson ”h]”(hŒStarted by Paul Jackson <”…””}”(hhíh²hh³Nh´NubhŒ reference”“”)”}”(hŒ pj@sgi.com”h]”hŒ pj@sgi.com”…””}”(hh÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”Œmailto:pj@sgi.com”uh1hõhhíubhŒ>”…””}”(hhíh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khhçubah}”(h]”h ]”h"]”h$]”h&]”uh1håhhÒubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÐh³hÊh´KhhÍh²hubah}”(h]”h ]”h"]”h$]”h&]”uh1hËhh·h²hh³hÊh´Kubhì)”}”(hŒ‡Robust_futexes provide a mechanism that is used in addition to normal futexes, for kernel assist of cleanup of held locks on task exit.”h]”hŒ‡Robust_futexes provide a mechanism that is used in addition to normal futexes, for kernel assist of cleanup of held locks on task exit.”…””}”(hj#h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khh·h²hubhì)”}”(hX;The interesting data as to what futexes a thread is holding is kept on a linked list in user space, where it can be updated efficiently as locks are taken and dropped, without kernel intervention. The only additional kernel intervention required for robust_futexes above and beyond what is required for futexes is:”h]”hX;The interesting data as to what futexes a thread is holding is kept on a linked list in user space, where it can be updated efficiently as locks are taken and dropped, without kernel intervention. The only additional kernel intervention required for robust_futexes above and beyond what is required for futexes is:”…””}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K hh·h²hubhŒ block_quote”“”)”}”(hŒÃ1) a one time call, per thread, to tell the kernel where its list of held robust_futexes begins, and 2) internal kernel code at exit, to handle any listed locks held by the exiting thread. ”h]”hŒenumerated_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒaa one time call, per thread, to tell the kernel where its list of held robust_futexes begins, and”h]”hì)”}”(hŒaa one time call, per thread, to tell the kernel where its list of held robust_futexes begins, and”h]”hŒaa one time call, per thread, to tell the kernel where its list of held robust_futexes begins, and”…””}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´KhjLubah}”(h]”h ]”h"]”h$]”h&]”uh1jJhjGubjK)”}”(hŒUinternal kernel code at exit, to handle any listed locks held by the exiting thread. ”h]”hì)”}”(hŒTinternal kernel code at exit, to handle any listed locks held by the exiting thread.”h]”hŒTinternal kernel code at exit, to handle any listed locks held by the exiting thread.”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khjdubah}”(h]”h ]”h"]”h$]”h&]”uh1jJhjGubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ)”uh1jEhjAubah}”(h]”h ]”h"]”h$]”h&]”uh1j?h³hÊh´Khh·h²hubhì)”}”(hXmThe existing normal futexes already provide a "Fast Userspace Locking" mechanism, which handles uncontested locking without needing a system call, and handles contested locking by maintaining a list of waiting threads in the kernel. Options on the sys_futex(2) system call support waiting on a particular futex, and waking up the next waiter on a particular futex.”h]”hXqThe existing normal futexes already provide a “Fast Userspace Locking†mechanism, which handles uncontested locking without needing a system call, and handles contested locking by maintaining a list of waiting threads in the kernel. Options on the sys_futex(2) system call support waiting on a particular futex, and waking up the next waiter on a particular futex.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khh·h²hubhì)”}”(hXxFor robust_futexes to work, the user code (typically in a library such as glibc linked with the application) has to manage and place the necessary list elements exactly as the kernel expects them. If it fails to do so, then improperly listed locks will not be cleaned up on exit, probably causing deadlock or other such failure of the other threads waiting on the same locks.”h]”hXxFor robust_futexes to work, the user code (typically in a library such as glibc linked with the application) has to manage and place the necessary list elements exactly as the kernel expects them. If it fails to do so, then improperly listed locks will not be cleaned up on exit, probably causing deadlock or other such failure of the other threads waiting on the same locks.”…””}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Khh·h²hubhì)”}”(hŒ\A thread that anticipates possibly using robust_futexes should first issue the system call::”h]”hŒ[A thread that anticipates possibly using robust_futexes should first issue the system call:”…””}”(hj©h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K$hh·h²hubhŒ literal_block”“”)”}”(hŒVasmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len);”h]”hŒVasmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len);”…””}”hj¹sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j·h³hÊh´K'hh·h²hubhì)”}”(hŒóThe pointer 'head' points to a structure in the threads address space consisting of three words. Each word is 32 bits on 32 bit arch's, or 64 bits on 64 bit arch's, and local byte order. Each thread should have its own thread private 'head'.”h]”hŒÿThe pointer ‘head’ points to a structure in the threads address space consisting of three words. Each word is 32 bits on 32 bit arch’s, or 64 bits on 64 bit arch’s, and local byte order. Each thread should have its own thread private ‘head’.”…””}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K*hh·h²hubhì)”}”(hX¼If a thread is running in 32 bit compatibility mode on a 64 native arch kernel, then it can actually have two such structures - one using 32 bit words for 32 bit compatibility mode, and one using 64 bit words for 64 bit native mode. The kernel, if it is a 64 bit kernel supporting 32 bit compatibility mode, will attempt to process both lists on each task exit, if the corresponding sys_set_robust_list() call has been made to setup that list.”h]”hX¼If a thread is running in 32 bit compatibility mode on a 64 native arch kernel, then it can actually have two such structures - one using 32 bit words for 32 bit compatibility mode, and one using 64 bit words for 64 bit native mode. The kernel, if it is a 64 bit kernel supporting 32 bit compatibility mode, will attempt to process both lists on each task exit, if the corresponding sys_set_robust_list() call has been made to setup that list.”…””}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K/hh·h²hubj@)”}”(hXÂThe first word in the memory structure at 'head' contains a pointer to a single linked list of 'lock entries', one per lock, as described below. If the list is empty, the pointer will point to itself, 'head'. The last 'lock entry' points back to the 'head'. The second word, called 'offset', specifies the offset from the address of the associated 'lock entry', plus or minus, of what will be called the 'lock word', from that 'lock entry'. The 'lock word' is always a 32 bit word, unlike the other words above. The 'lock word' holds 2 flag bits in the upper 2 bits, and the thread id (TID) of the thread holding the lock in the bottom 30 bits. See further below for a description of the flag bits. The third word, called 'list_op_pending', contains transient copy of the address of the 'lock entry', during list insertion and removal, and is needed to correctly resolve races should a thread exit while in the middle of a locking or unlocking operation. ”h]”(hì)”}”(hXThe first word in the memory structure at 'head' contains a pointer to a single linked list of 'lock entries', one per lock, as described below. If the list is empty, the pointer will point to itself, 'head'. The last 'lock entry' points back to the 'head'.”h]”hXThe first word in the memory structure at ‘head’ contains a pointer to a single linked list of ‘lock entries’, one per lock, as described below. If the list is empty, the pointer will point to itself, ‘head’. The last ‘lock entry’ points back to the ‘head’.”…””}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K7hjåubhì)”}”(hX»The second word, called 'offset', specifies the offset from the address of the associated 'lock entry', plus or minus, of what will be called the 'lock word', from that 'lock entry'. The 'lock word' is always a 32 bit word, unlike the other words above. The 'lock word' holds 2 flag bits in the upper 2 bits, and the thread id (TID) of the thread holding the lock in the bottom 30 bits. See further below for a description of the flag bits.”h]”hXÓThe second word, called ‘offset’, specifies the offset from the address of the associated ‘lock entry’, plus or minus, of what will be called the ‘lock word’, from that ‘lock entry’. The ‘lock word’ is always a 32 bit word, unlike the other words above. The ‘lock word’ holds 2 flag bits in the upper 2 bits, and the thread id (TID) of the thread holding the lock in the bottom 30 bits. See further below for a description of the flag bits.”…””}”(hj÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´Kubah}”(h]”h ]”h"]”h$]”h&]”uh1jJhj#ubjK)”}”(hŒdif the list contains more than 1 million (subject to future kernel configuration changes) elements. ”h]”hì)”}”(hŒcif the list contains more than 1 million (subject to future kernel configuration changes) elements.”h]”hŒcif the list contains more than 1 million (subject to future kernel configuration changes) elements.”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K³hjVubah}”(h]”h ]”h"]”h$]”h&]”uh1jJhj#ubeh}”(h]”h ]”h"]”h$]”h&]”j‚jƒj„hj…j†uh1jEhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j?h³hÊh´K®hh·h²hubhì)”}”(hŒ®When the kernel sees a list entry whose 'lock word' doesn't have the current threads TID in the lower 30 bits, it does nothing with that entry, and goes on to the next entry.”h]”hŒ´When the kernel sees a list entry whose ‘lock word’ doesn’t have the current threads TID in the lower 30 bits, it does nothing with that entry, and goes on to the next entry.”…””}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hëh³hÊh´K¶hh·h²hubeh}”(h]”Œthe-robust-futex-abi”ah ]”h"]”Œthe robust futex abi”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j³Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”jjŠsŒ nametypes”}”j‰sh}”jŠh·sŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.