Skip to content

A library for robust cross-process synchronization based on Linux futexes

Notifications You must be signed in to change notification settings

ShawnZhong/libfutex

Repository files navigation

libfutex

References

The following are references about (non-robust) futexes:

The following are references about robust futexes on the side of the Linux kernel:

There aren't many references on the internet about the use of robust futexes (specifically robust_list). The only implementation I found is from glibc. The following is a summary of the information contained in the glibc-2.36 source code.

  • struct robust_list_head is an userspace per-thread data structure used to keep track of futexes that the thread has acquired. It is registered with the Linux kernel via set_robust_list so that when the thread exits (either normally or abnormally), the kernel can iterate through the list and release the futexes that the thread has acquired. struct robust_list_head is defined in linux/futex.h as part of the Linux syscall ABI.

  • In glibc, the struct robust_list_head is stored in the robust_list field of struct pthread, which is the struct pointed to by pthread_t.

  • When a process first starts, robust_head is initialized and registered with the kernel with set_robust_list system call. The relevant code is in __tls_init_tp:

    #0  __tls_init_tp () at ../sysdeps/nptl/dl-tls_init_tp.c:106
    #1  0x00007ffff7fe3e28 in init_tls (naudit=naudit@entry=0) at ./elf/rtld.c:821
    #2  0x00007ffff7fe766c in dl_main (phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>,
    auxv=<optimized out>) at ./elf/rtld.c:2045
    #3  0x00007ffff7fe285c in _dl_sysdep_start (start_argptr=start_argptr@entry=0x7fffffffdd90,
    dl_main=dl_main@entry=0x7ffff7fe4900 <dl_main>) at ../elf/dl-sysdep.c:256
    #4  0x00007ffff7fe45b8 in _dl_start_final (arg=0x7fffffffdd90) at ./elf/rtld.c:507
    #5  _dl_start (arg=0x7fffffffdd90) at ./elf/rtld.c:596
    #6  0x00007ffff7fe32b8 in _start () from /lib64/ld-linux-x86-64.so.2
  • When a new thread is created, tht content of the robust_list is initialized in allocate_stack:

    #0  allocate_stack (stacksize=<synthetic pointer>, stack=<synthetic pointer>, pdp=<synthetic pointer>, attr=0x7fffffffdb50)
    at ./nptl/allocatestack.c:555
    #1  __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>)
    at ./nptl/pthread_create.c:647

    Then set_robust_list is called in start_thread,

    #0  start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:400
    #1  create_thread (pd=pd@entry=0x7ffff7d7e640, attr=attr@entry=0x7fffffffdb50, 
    stopped_start=stopped_start@entry=0x7fffffffdb4e, stackaddr=stackaddr@entry=0x7ffff757e000, stacksize=8388352, 
    thread_ran=thread_ran@entry=0x7fffffffdb4f) at ./nptl/pthread_create.c:285
    #2  0x00007ffff7e17280 in __pthread_create_2_1 (newthread=<optimized out>, attr=<optimized out>, start_routine=<optimized out>,
    arg=<optimized out>) at ./nptl/pthread_create.c:828
  • When a mutex is acquired, it needs to be added to the robust_list of the current thread so the kernel can see it when the thread exits. Similarly, when a mutex is released, it should be removed. The relevant code is in nptl/descr.h

  • In glibc, the code for locking/unlocking robust mutex is in pthread_mutex_lock.c and pthread_mutex_unlock.c

About

A library for robust cross-process synchronization based on Linux futexes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published