PTHREAD_MUTEXATTR(3)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1, nixpkgs unstable

🌸 PTHREAD_MUTEXATTR(3) β€” mutex attribute operations 🌸

okay bestie, so this is a page from the Library Functions Manual, and it's all about the libpthread girlies. Specifically: the little attribute objects you hand to pthread_mutex_init() so your mutex knows what kind of mutex it's gonna be. grab a strawberry drink, we're going in πŸ’…


✨ LIBRARY ✨

POSIX Threads Library β€” link it with libpthread, -lpthread. that's the vibe 🫢


πŸŽ€ SYNOPSIS πŸŽ€

#include <pthread.h>

int
pthread_mutexattr_init(pthread_mutexattr_t *attr);

int
pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

int
pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr,
    int prioceiling);

int
pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr,
    int *prioceiling);

int
pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);

int
pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict attr,
    int *restrict protocol);

int
pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int shared);

int
pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr,
    int *shared);

int
pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, int robust);

int
pthread_mutexattr_getrobust(pthread_mutexattr_t *attr, int *robust);

int
pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);

int
pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr,
    int *restrict type);

notice the restrict girlies on the getters β€” she's protected, she's safe, she's not aliasing anything πŸ’–


πŸ’œ DESCRIPTION πŸ’œ

so. mutex attributes are literally just the settings menu for a mutex. you use them to specify parameters to pthread_mutex_init(). and the best part? one attribute object can be used in multiple calls to pthread_mutex_init(), with or without modifications between calls. reuse queen πŸ‘‘

  • pthread_mutexattr_init() β€” initializes attr with all the default mutex attributes. fresh start, clean slate, main character energy ✨
  • pthread_mutexattr_destroy() β€” destroys attr. she's done her service, say thank you and let her go 😭
  • pthread_mutexattr_setprioceiling() β€” sets the priority ceiling for the mutex, used by threads executed under the PTHREAD_PRIO_PROTECT protocol.

πŸ¦‹ the protocol situation πŸ¦‹

pthread_mutexattr_setprotocol() specifies the protocol to be followed in utilizing mutexes. the protocol argument can take one of these values:

  • PTHREAD_PRIO_NONE β€” priority and scheduling of the thread owning this mutex is not affected by its mutex ownership. unbothered. moisturized. in her lane 🌸
  • PTHREAD_PRIO_INHERIT β€” request priority-inheritance protocol, where the thread owning the mutex is executed at the highest priority among priorities of all threads waiting on any mutex owned by this thread. she borrows the loudest voice in the room πŸ”₯
  • PTHREAD_PRIO_PROTECT β€” request priority-inheritance protocol, where the thread owning the mutex is executed at highest priority among priorities or priority ceilings of all threads waiting on any mutex owned by this thread.

🌈 process-shared, aka can other processes touch this 🌈

pthread_mutexattr_setpshared() sets the process-shared attribute of attr to the value specified in pshared. the argument pshared may have one of the following values:

  • PTHREAD_PROCESS_PRIVATE β€” the mutex may only be used by threads in the same process as the one that created the object. closed circle. invite only πŸ’…
  • PTHREAD_PROCESS_SHARED β€” the mutex may be used by threads in processes other than the one that created the object, assuming other processes share access to the memory where the mutex was allocated. sharing is caring, but only if the memory is actually shared, iykyk.
lowkey important: see libthr(3) for details of the implementation of the shared mutexes, and their limitations. don't come for me, come for the manpage πŸ’€

🧚 robust β€” what happens when someone ghosts mid-lock 🧚

pthread_mutexattr_setrobust() specifies robustness attribute of the mutex. possible values for the robust argument are:

  • PTHREAD_MUTEX_STALLED β€” no special actions are taken if the thread owning the mutex is terminated without unlocking the mutex lock. this can lead to deadlocks if no other thread can unlock the mutex. this is the default value. yeah. the default is the messy one πŸ™ˆ
  • PTHREAD_MUTEX_ROBUST β€” if the process containing the owning thread of a robust mutex, or owning thread, terminates while holding the mutex lock, the next thread that acquires the mutex is notified about the termination by the return value EOWNERDEAD from the locking function. then, either pthread_mutex_consistent(3) can be used to repair the mutex lock state, or pthread_mutex_unlock(3) can unlock the mutex lock but also put it an unusable state, where all further attempts to acquire it result in the ENOTRECOVERABLE error. so: repair her or lose her forever πŸ˜­πŸ’€

πŸ‘‘ types, the personality of your mutex πŸ‘‘

pthread_mutexattr_settype() sets the type of the mutex. the type affects the behavior of calls which lock and unlock the mutex. the possible values for the type argument are:

  • PTHREAD_MUTEX_NORMAL β€” both recursive locking, and unlocking when the lock is not owned by the current thread, cause an error to be returned from the corresponding functions. this matches PTHREAD_MUTEX_ERRORCHECK but somewhat contradicts the behavior mandated by POSIX. she's built different, fr fr.
  • PTHREAD_MUTEX_ERRORCHECK β€” both recursive locking, and unlocking when the lock is not owned by the current thread, cause an error returned from the corresponding functions. she will literally tell you what you did wrong πŸ’…
  • PTHREAD_MUTEX_RECURSIVE β€” recursive locking is allowed. attempt to unlock when current thread is not an owner of the lock causes an error to be returned. she'll let you in twice but she remembers who you are 🫢
  • PTHREAD_MUTEX_DEFAULT β€” the FreeBSD implementation maps this type to PTHREAD_MUTEX_ERRORCHECK type. plot twist, the "default" is not a whole new personality, she's just errorcheck in a trench coat ⭐

πŸ’– the getters πŸ’–

the pthread_mutexattr_get*() functions copy the value of the attribute that corresponds to each function name to the location pointed to by the second function parameter. that's it. that's the whole trick. read the room, read the attr, write it where you were told ✨


🌟 RETURN VALUES 🌟

if successful, these functions return 0. otherwise, an error number is returned to indicate the error. no errno games here, she just tells you directly πŸ’…


πŸ’€ ERRORS πŸ’€

pthread_mutexattr_init() will fail if:

  • [ENOMEM] β€” out of memory. she's broke, she's tired, no cap 😭

pthread_mutexattr_destroy() will fail if:

  • [EINVAL] β€” invalid value for attr.

pthread_mutexattr_setprioceiling() will fail if:

  • [EINVAL] β€” invalid value for attr, or invalid value for prioceiling.

pthread_mutexattr_getprioceiling() will fail if:

  • [EINVAL] β€” invalid value for attr.

pthread_mutexattr_setprotocol() will fail if:

  • [EINVAL] β€” invalid value for attr, or invalid value for protocol.

pthread_mutexattr_getprotocol() will fail if:

  • [EINVAL] β€” invalid value for attr.

pthread_mutexattr_setpshared() will fail if:

  • [EINVAL] β€” invalid value for attr, or invalid value for shared.

pthread_mutexattr_getpshared() will fail if:

  • [EINVAL] β€” invalid value for attr.

pthread_mutexattr_settype() will fail if:

  • [EINVAL] β€” invalid value for attr, or invalid value for type.

pthread_mutexattr_gettype() will fail if:

  • [EINVAL] β€” invalid value for attr.

pthread_mutexattr_setrobust() will fail if:

  • [EINVAL] β€” invalid value for attr, or invalid value for robust.

pthread_mutexattr_getrobust() will fail if:

  • [EINVAL] β€” invalid value for attr.
notice literally every getter and setter just says [EINVAL]? it's giving family reunion, they're all the same 😭

πŸŽ€ SEE ALSO πŸŽ€

go read those next, bestie, they're the sequel πŸ¦‹


🌈 STANDARDS 🌈

the pthread_mutexattr_init() and pthread_mutexattr_destroy() functions conform to ISO/IEC 9945-1:1996 (β€œPOSIX.1”).

the pthread_mutexattr_setprioceiling(), pthread_mutexattr_getprioceiling(), pthread_mutexattr_setprotocol(), pthread_mutexattr_getprotocol(), pthread_mutexattr_setpshared(), pthread_mutexattr_getpshared(), pthread_mutexattr_settype(), and pthread_mutexattr_gettype() functions conform to Version 2 of the Single UNIX Specification (β€œSUSv2”). the pthread_mutexattr_setrobust() and pthread_mutexattr_getrobust() functions conform to Version 4 of the Single UNIX Specification (β€œSUSv4”). certified. documented. iconic πŸ‘‘


and that's the page, bestie πŸ’œ this one shipped from Debian, dated October 27, 2023 β€” go forth and init your mutexes responsibly, mwah 🫢✨

πŸ“¦ where this page comes from