Man page - futex(2)
Packages contains this manual
- __malloc_initialize_hook(3)
- getpwuid(3)
- frexpl(3)
- fchown(2)
- setttyent(3)
- pthread_attr_setstacksize(3)
- calloc(3)
- clog(3)
- seteuid(2)
- res_nquerydomain(3)
- y0l(3)
- catanl(3)
- catanh(3)
- inet_addr(3)
- getcwd(2)
- epoll_create1(2)
- atol(3)
- pciconfig_write(2)
- htonl(3)
- timer_settime(2)
- munmap(2)
- cexpl(3)
- rt_sigsuspend(2)
- msgctl(2)
- tan(3)
- get_mempolicy(2)
- roundf(3)
- towctrans(3)
- xdr_opaque(3)
- psignal(3)
- error_at_line(3)
- xdrmem_create(3)
- select(2)
- getdate_r(3)
- getprotobyname_r(3)
- nrand48_r(3)
- inet_netof(3)
- inet_ntoa(3)
- nextafterl(3)
- innetgr(3)
- on_exit(3)
- expm1l(3)
- strfmon(3)
- strdup(3)
- getservbyport(3)
- arch_prctl(2)
- j0(3)
- wait4(2)
- personality(2)
- bpf(2)
- pvalloc(3)
- getresuid32(2)
- des_setparity(3)
- prctl(2)
- clog10(3)
- aio_init(3)
- pthread_getconcurrency(3)
- csinl(3)
- linkat(2)
- vsscanf(3)
- isascii(3)
- xdr_union(3)
- nan(3)
- utimensat(2)
- ioctl_vt(2)
- _newselect(2)
- ldexpl(3)
- fabsf(3)
- chown(2)
- mkstemps(3)
- pthread_attr_getstacksize(3)
- listxattr(2)
- getpgrp(2)
- xdr_short(3)
- tcflush(3)
- pthread_cond_wait(3)
- argz_add(3)
- wcpncpy(3)
- reallocarray(3)
- llrintf(3)
- outsl(2)
- qsort(3)
- authnone_create(3)
- tzname(3)
- setresuid32(2)
- isspace(3)
- open_by_handle_at(2)
- drem(3)
- conjf(3)
- nanosleep(2)
- pthread_kill(3)
- putc(3)
- pthread_condattr_destroy(3)
- getpwuid_r(3)
- strverscmp(3)
- res_init(3)
- cacosl(3)
- qecvt_r(3)
- iswgraph(3)
- gethostbyname(3)
- ntohl(3)
- acct(2)
- asinl(3)
- envz_merge(3)
- strdupa(3)
- idle(2)
- getopt_long_only(3)
- hstrerror(3)
- fanotify_init(2)
- fputs_unlocked(3)
- sleep(3)
- vfprintf(3)
- scalb(3)
- nanl(3)
- lchown32(2)
- getnetent_r(3)
- fcntl(2)
- inw(2)
- rintl(3)
- arc4random(3)
- getsockopt(2)
- ilogbl(3)
- clog2(3)
- encrypt(3)
- sqrtf(3)
- isspace_l(3)
- tanl(3)
- cfmakeraw(3)
- assert(3)
- strtoull(3)
- xdrstdio_create(3)
- optopt(3)
- setrlimit(2)
- lround(3)
- xdr_accepted_reply(3)
- fmin(3)
- mq_notify(3)
- svcerr_auth(3)
- sbrk(2)
- recv(2)
- mq_unlink(2)
- strxfrm(3)
- ctan(3)
- atoi(3)
- xcrypt(3)
- sgetspent(3)
- fread(3)
- isless(3)
- ceil(3)
- pthread_cond_broadcast(3)
- oldfstat(2)
- outl(2)
- times(2)
- wcslen(3)
- popen(3)
- wprintf(3)
- labs(3)
- getrpcbynumber(3)
- shmat(2)
- clock_gettime(2)
- btree(3)
- s390_sthyi(2)
- siggetmask(3)
- getgid32(2)
- puts(3)
- scalblnl(3)
- strpbrk(3)
- catanhl(3)
- vlimit(3)
- getrpcent(3)
- tgammal(3)
- strtoll(3)
- funlockfile(3)
- xdecrypt(3)
- pthread_key_delete(3)
- setgrent(3)
- wmemmove(3)
- gnu_dev_major(3)
- regexec(3)
- lrintl(3)
- __ppc_set_ppr_med(3)
- rmdir(2)
- io_getevents(2)
- request_key(2)
- ecvt(3)
- __ppc_mdoom(3)
- mktemp(3)
- key_gendes(3)
- le64toh(3)
- statvfs(3)
- rpc(3)
- getdate_err(3)
- munlockall(2)
- close(2)
- xdr_rejected_reply(3)
- dlerror(3)
- le32toh(3)
- feclearexcept(3)
- insque(3)
- clntraw_create(3)
- getutid(3)
- strtof(3)
- settimeofday(2)
- mkdir(2)
- rewind(3)
- logf(3)
- tmpnam(3)
- iswpunct(3)
- wcrtomb(3)
- epoll_pwait(2)
- getitimer(2)
- wordexp(3)
- clog2f(3)
- capset(2)
- strrchr(3)
- outsb(2)
- freeifaddrs(3)
- getwc_unlocked(3)
- ustat(2)
- bswap_16(3)
- program_invocation_short_name(3)
- ldiv(3)
- exp10f(3)
- vprintf(3)
- wcsncpy(3)
- iscntrl(3)
- readlink(2)
- semget(2)
- connect(2)
- psiginfo(3)
- epoll_ctl(2)
- removexattr(2)
- envz_strip(3)
- fgetxattr(2)
- atexit(3)
- putgrent(3)
- bswap(3)
- getegid32(2)
- qecvt(3)
- asinh(3)
- isfdtype(3)
- setenv(3)
- readdir(3)
- rtime(3)
- nearbyint(3)
- getgroups32(2)
- statx(2)
- modify_ldt(2)
- cpow(3)
- eventfd_read(3)
- sendfile64(2)
- getnetbyname(3)
- fremovexattr(2)
- uselib(2)
- inet(3)
- endutxent(3)
- clnt_spcreateerror(3)
- pututline(3)
- nexttowardl(3)
- getipnodebyaddr(3)
- fts_set(3)
- memmem(3)
- fmodl(3)
- setfsuid32(2)
- wordfree(3)
- fadvise64(2)
- getppid(2)
- qsort_r(3)
- toupper(3)
- getwc(3)
- fputws(3)
- mrand48(3)
- preadv(2)
- sincosf(3)
- fstatat64(2)
- dirfd(3)
- jnf(3)
- static_assert(3)
- wctype(3)
- vwarn(3)
- setfsent(3)
- listen(2)
- wcstok(3)
- argz_insert(3)
- select_tut(2)
- ctanl(3)
- getunwind(2)
- difftime(3)
- daylight(3)
- sigpause(3)
- wcscat(3)
- dlclose(3)
- __ppc_set_ppr_med_low(3)
- pread(2)
- fstatvfs(3)
- cbrtf(3)
- strnlen(3)
- sinhl(3)
- inl_p(2)
- setregid32(2)
- putwc(3)
- register_printf_type(3)
- nextafterf(3)
- opendir(3)
- strtod(3)
- tgamma(3)
- malloc_get_state(3)
- aio_write(3)
- timezone(3)
- xdr_pmaplist(3)
- sysfs(2)
- index(3)
- svcerr_noproc(3)
- envz(3)
- klogctl(3)
- pselect(2)
- get_current_dir_name(3)
- xdr_char(3)
- asinhf(3)
- preadv2(2)
- inotify_init1(2)
- pthread_attr_setstackaddr(3)
- getline(3)
- tanhf(3)
- rtnetlink(3)
- pkey_alloc(2)
- edata(3)
- stailq(3)
- isastream(2)
- setregid(2)
- copy_file_range(2)
- rcmd_af(3)
- futex(2)
- prof(2)
- siglongjmp(3)
- hdestroy(3)
- catan(3)
- pthread_cond_signal(3)
- mkfifoat(3)
- clntudp_create(3)
- getentropy(3)
- vsprintf(3)
- fabs(3)
- lseek64(3)
- pthread_setname_np(3)
- conjl(3)
- chroot(2)
- ccoshf(3)
- erand48_r(3)
- wcsnrtombs(3)
- rindex(3)
- fputc_unlocked(3)
- setresgid32(2)
- gettimeofday(2)
- cexp(3)
- inotify_add_watch(2)
- set_robust_list(2)
- nice(2)
- strtold(3)
- mq_getattr(3)
- xdr(3)
- getxattr(2)
- getrandom(2)
- splice(2)
- strerror(3)
- fcntl64(2)
- fnmatch(3)
- ungetwc(3)
- getspnam_r(3)
- clearenv(3)
- atan2(3)
- get_myaddress(3)
- open(2)
- pthread_setcancelstate(3)
- newlocale(3)
- open_memstream(3)
- setprotoent(3)
- logbf(3)
- ilogb(3)
- wmemcpy(3)
- tcsendbreak(3)
- be16toh(3)
- perfmonctl(2)
- strtoq(3)
- getgrgid_r(3)
- pthread_timedjoin_np(3)
- memfd_create(2)
- getttynam(3)
- mcheck_pedantic(3)
- _llseek(2)
- renameat2(2)
- ioperm(2)
- ecb_crypt(3)
- pthread_condattr_init(3)
- fminl(3)
- lio_listio(3)
- envz_add(3)
- setbuf(3)
- setkey(3)
- expm1(3)
- strtoul(3)
- getcwd(3)
- setutxent(3)
- getrpcent_r(3)
- unimplemented(2)
- fclose(3)
- epoll_create(2)
- getfsent(3)
- key_secretkey_is_set(3)
- vserver(2)
- vswprintf(3)
- sigsuspend(2)
- pututxline(3)
- clnt_freeres(3)
- cacheflush(2)
- ioprio_set(2)
- alarm(2)
- fgetc(3)
- __fpurge(3)
- getlogin_r(3)
- vfork(2)
- bstring(3)
- div(3)
- getrusage(2)
- gettid(2)
- dprintf(3)
- strtoumax(3)
- jrand48(3)
- iswcntrl(3)
- vwarnx(3)
- cacos(3)
- ccoshl(3)
- fesetexceptflag(3)
- res_nclose(3)
- shmop(2)
- mcheck_check_all(3)
- vscanf(3)
- tolower(3)
- landlock_add_rule(2)
- argz_next(3)
- lroundl(3)
- ruserok(3)
- glob(3)
- brk(2)
- rename(2)
- strcspn(3)
- sched_getscheduler(2)
- wcstoumax(3)
- dbopen(3)
- xdr_bytes(3)
- fegetenv(3)
- scalbf(3)
- pkey_free(2)
- fgetgrent(3)
- strchrnul(3)
- fork(2)
- log1pf(3)
- strtoimax(3)
- fputs(3)
- putspent(3)
- ttyname_r(3)
- iswlower(3)
- epoll_wait(2)
- minor(3)
- wcsspn(3)
- sendmmsg(2)
- pthread_attr_getsigmask_np(3)
- erand48(3)
- setpgrp(2)
- db(3)
- readv(2)
- cimagf(3)
- pthread_sigmask(3)
- getresuid(2)
- gamma(3)
- logwtmp(3)
- imaxabs(3)
- y1(3)
- swapoff(2)
- svcerr_weakauth(3)
- mbtowc(3)
- madvise(2)
- __fbufsize(3)
- swapon(2)
- towlower(3)
- asin(3)
- initgroups(3)
- svc_getreqset(3)
- pthread_attr_destroy(3)
- scalblnf(3)
- ispunct(3)
- casin(3)
- xdr_pmap(3)
- sigvec(3)
- dlmopen(3)
- localeconv(3)
- tcgetattr(3)
- mempcpy(3)
- clnt_perrno(3)
- clock_getcpuclockid(3)
- setaliasent(3)
- clock(3)
- ftok(3)
- svc_run(3)
- getsubopt(3)
- coshf(3)
- pow(3)
- getpwent(3)
- ntp_gettime(3)
- xdrrec_skiprecord(3)
- symlink(2)
- shmctl(2)
- mq_timedreceive(2)
- malloc(3)
- tgkill(2)
- l64a(3)
- unlockpt(3)
- mallopt(3)
- creal(3)
- syscalls(2)
- set_tid_address(2)
- exp2f(3)
- fstatfs(2)
- statfs(2)
- dreml(3)
- feenableexcept(3)
- ftw(3)
- fanotify_mark(2)
- clnt_sperror(3)
- realpath(3)
- sysconf(3)
- _syscall(2)
- set_mempolicy(2)
- mq_unlink(3)
- freehostent(3)
- rresvport_af(3)
- nl_langinfo_l(3)
- fmaxl(3)
- iscntrl_l(3)
- copysignf(3)
- llseek(2)
- bzero(3)
- ioctl_fsmap(2)
- remquof(3)
- malloc_trim(3)
- pthread_getattr_default_np(3)
- isalnum_l(3)
- mlock(2)
- nearbyintf(3)
- confstr(3)
- sinf(3)
- ioctl_eventpoll(2)
- sigstack(3)
- seed48_r(3)
- utmpname(3)
- malloc_stats(3)
- stpncpy(3)
- getservbyport_r(3)
- cabsl(3)
- isblank(3)
- sigprocmask(2)
- isinfl(3)
- isinff(3)
- pathconf(3)
- xdr_u_short(3)
- acos(3)
- timerfd_create(2)
- key_encryptsession(3)
- log2f(3)
- oldlstat(2)
- res_querydomain(3)
- memcmp(3)
- gethostbyaddr(3)
- sighold(3)
- gtty(2)
- xdr_void(3)
- getmsg(2)
- io_setup(2)
- ttyslot(3)
- recno(3)
- cuserid(3)
- nanf(3)
- pthread_getaffinity_np(3)
- if_indextoname(3)
- remainderf(3)
- putpwent(3)
- pow10f(3)
- pwritev(2)
- swapcontext(3)
- cfsetospeed(3)
- envz_remove(3)
- cosh(3)
- a64l(3)
- uselocale(3)
- yn(3)
- msgget(2)
- pthread_equal(3)
- prlimit(2)
- setspent(3)
- newfstatat(2)
- renameat(2)
- truncf(3)
- pthread_yield(3)
- tkill(2)
- islessequal(3)
- isnanf(3)
- sethostent(3)
- setvbuf(3)
- gnu_get_libc_release(3)
- atoll(3)
- getgrnam(3)
- get_robust_list(2)
- __ppc_yield(3)
- __memalign_hook(3)
- eventfd2(2)
- mq_setattr(3)
- tmpnam_r(3)
- pmap_getport(3)
- svcfd_create(3)
- getfsspec(3)
- setgid(2)
- getlogin(3)
- get_nprocs(3)
- canonicalize_file_name(3)
- pthread_mutexattr_getrobust(3)
- strerrorname_np(3)
- csinh(3)
- malloc_set_state(3)
- tcgetsid(3)
- ssignal(3)
- secure_getenv(3)
- significandl(3)
- wcschr(3)
- isgraph(3)
- pthread_mutexattr_gettype(3)
- creat(2)
- cabsf(3)
- __ppc_set_ppr_med_high(3)
- fchdir(2)
- backtrace_symbols(3)
- exp10l(3)
- euidaccess(3)
- sync_file_range(2)
- getutxline(3)
- isdigit(3)
- sinhf(3)
- lgetxattr(2)
- getaliasent(3)
- memrchr(3)
- io_submit(2)
- clnt_create(3)
- __setfpucw(3)
- _flushlbf(3)
- lcong48_r(3)
- clog10l(3)
- pmap_getmaps(3)
- memalign(3)
- xdr_authunix_parms(3)
- execl(3)
- getdate(3)
- cfsetispeed(3)
- tanhl(3)
- wmempcpy(3)
- outw_p(2)
- faccessat(2)
- rresvport(3)
- nextup(3)
- fgetgrent_r(3)
- getopt(3)
- xdr_vector(3)
- aio_error(3)
- frexpf(3)
- getpw(3)
- sscanf(3)
- mprotect(2)
- exp(3)
- sched_getaffinity(2)
- accept4(2)
- remainderl(3)
- pthread_key_create(3)
- endian(3)
- setmntent(3)
- get_phys_pages(3)
- argz(3)
- _exit(2)
- towupper_l(3)
- lrand48(3)
- csqrt(3)
- hdestroy_r(3)
- remquo(3)
- feof_unlocked(3)
- isprint(3)
- pivot_root(2)
- arc4random_uniform(3)
- strfroml(3)
- getdomainname(2)
- va_end(3)
- getresgid(2)
- cosf(3)
- endhostent(3)
- setgid32(2)
- ioctl_fs(2)
- getaddrinfo(3)
- fgetwc(3)
- lock(2)
- getservbyname_r(3)
- sys_nerr(3)
- insb(2)
- usleep(3)
- security(2)
- cfree(3)
- tanf(3)
- fprintf(3)
- pthread_mutexattr_setpshared(3)
- xprt_unregister(3)
- alphasort(3)
- getgrent(3)
- scandirat(3)
- iruserok(3)
- ttyname(3)
- tdestroy(3)
- strcasecmp(3)
- getpgid(2)
- drand48_r(3)
- mmap(2)
- sigtimedwait(2)
- pthread_once(3)
- mq_receive(3)
- pthread_mutexattr_setkind_np(3)
- iopl(2)
- s390_runtime_instr(2)
- lckpwdf(3)
- memmove(3)
- __fpending(3)
- mbsrtowcs(3)
- restart_syscall(2)
- memset(3)
- significandf(3)
- openat2(2)
- timeradd(3)
- conj(3)
- flockfile(3)
- madvise1(2)
- inet_aton(3)
- fstatfs64(2)
- fmax(3)
- fmemopen(3)
- fmaf(3)
- lseek(2)
- registerrpc(3)
- kexec_file_load(2)
- gammal(3)
- feof(3)
- pidfd_open(2)
- crealf(3)
- clogl(3)
- getutmp(3)
- umount(2)
- inet_pton(3)
- flistxattr(2)
- xdr_wrapstring(3)
- socketcall(2)
- setrpcent(3)
- rint(3)
- vm86(2)
- sincosl(3)
- getprotoent_r(3)
- mknod(2)
- getdents64(2)
- gai_cancel(3)
- srandom_r(3)
- getnetbyname_r(3)
- sigaddset(3)
- htole16(3)
- endnetent(3)
- nextafter(3)
- timerisset(3)
- getgrent_r(3)
- freeaddrinfo(3)
- endprotoent(3)
- mbind(2)
- sigorset(3)
- pthread_rwlockattr_setkind_np(3)
- cimag(3)
- waitid(2)
- abs(3)
- unlink(2)
- recvmsg(2)
- getaliasbyname(3)
- wctrans(3)
- kill(2)
- strtol(3)
- __ppc_set_ppr_very_low(3)
- membarrier(2)
- getnetbyaddr_r(3)
- writev(2)
- errx(3)
- tfind(3)
- clone3(2)
- __freading(3)
- outw(2)
- regfree(3)
- accept(2)
- timer_getoverrun(2)
- shmdt(2)
- svcerr_decode(3)
- getnameinfo(3)
- endusershell(3)
- execvpe(3)
- cbc_crypt(3)
- res_send(3)
- xdr_destroy(3)
- getcontext(3)
- pkey_mprotect(2)
- twalk_r(3)
- isalnum(3)
- timercmp(3)
- setxattr(2)
- pthread_cleanup_pop_restore_np(3)
- stat(2)
- isupper(3)
- vsyslog(3)
- strlen(3)
- pthread_attr_setinheritsched(3)
- xdr_inline(3)
- strtouq(3)
- raise(3)
- getpeername(2)
- capget(2)
- atanl(3)
- ferror_unlocked(3)
- isxdigit_l(3)
- modfl(3)
- pthread_mutexattr_init(3)
- pthread_mutexattr_getkind_np(3)
- phys(2)
- llabs(3)
- sched_rr_get_interval(2)
- asprintf(3)
- explicit_bzero(3)
- asctime(3)
- clone(2)
- munlock(2)
- __realloc_hook(3)
- atof(3)
- rt_tgsigqueueinfo(2)
- syslog(2)
- inet_makeaddr(3)
- epoll_pwait2(2)
- iswalpha(3)
- netlink(3)
- sched_setattr(2)
- sigdescr_np(3)
- access(2)
- getc_unlocked(3)
- dysize(3)
- inet_net_pton(3)
- sched_setparam(2)
- timerfd_settime(2)
- nexttowardf(3)
- expf(3)
- svcerr_progvers(3)
- getwchar(3)
- ftime(3)
- if_nametoindex(3)
- argz_add_sep(3)
- vasprintf(3)
- unlinkat(2)
- putenv(3)
- pthread_mutexattr_setrobust_np(3)
- error_message_count(3)
- setfsgid(2)
- cmsg(3)
- setpwent(3)
- cfgetospeed(3)
- end(3)
- pidfd_send_signal(2)
- scalbn(3)
- closelog(3)
- srandom(3)
- argz_replace(3)
- ioctl_tty(2)
- va_arg(3)
- towlower_l(3)
- isblank_l(3)
- remove(3)
- expl(3)
- fscanf(3)
- versionsort(3)
- pow10(3)
- hsearch(3)
- gethostid(3)
- fchownat(2)
- group_member(3)
- getchar_unlocked(3)
- getservbyname(3)
- pthread_mutexattr_destroy(3)
- setpgid(2)
- acosf(3)
- ctanhf(3)
- shm_open(3)
- towupper(3)
- getdents(2)
- chown32(2)
- hypotf(3)
- undocumented(3)
- drand48(3)
- csinf(3)
- ctime_r(3)
- setlinebuf(3)
- ulimit(3)
- spu_create(2)
- fcvt_r(3)
- ipc(2)
- ftruncate64(2)
- fdopen(3)
- svcerr_noprog(3)
- getrpcport(3)
- csin(3)
- sinh(3)
- nrand48(3)
- openpty(3)
- xdr_double(3)
- pthread_attr_getscope(3)
- vfscanf(3)
- catanhf(3)
- inb(2)
- wcpcpy(3)
- ldexp(3)
- getopt_long(3)
- strerrordesc_np(3)
- mbsinit(3)
- argz_stringify(3)
- setbuffer(3)
- byteorder(3)
- expm1f(3)
- pthread_attr_setscope(3)
- gnu_dev_makedev(3)
- pipe(2)
- updwtmp(3)
- fts_read(3)
- ioctl_fat(2)
- h_errno(3)
- sem_getvalue(3)
- iswupper(3)
- lrint(3)
- perror(3)
- xdr_u_int(3)
- timer_create(2)
- iswdigit(3)
- fgetspent(3)
- fwrite_unlocked(3)
- reboot(2)
- ftruncate(2)
- getutmpx(3)
- pwrite64(2)
- getauxval(3)
- xdr_pointer(3)
- getprotobynumber(3)
- svc_destroy(3)
- vmsplice(2)
- inet_network(3)
- readdir_r(3)
- setsockopt(2)
- rexec(3)
- flock(2)
- getw(3)
- mmap2(2)
- j1f(3)
- cprojf(3)
- mkstemp(3)
- symlinkat(2)
- tempnam(3)
- pthread_attr_getaffinity_np(3)
- gethostbyname_r(3)
- signalfd4(2)
- sys_siglist(3)
- erfc(3)
- truncate64(2)
- verr(3)
- pthread_kill_other_threads_np(3)
- eaccess(3)
- fsetpos(3)
- slist(3)
- pmap_unset(3)
- modf(3)
- ioctl_pipe(2)
- vfwprintf(3)
- getresgid32(2)
- statfs64(2)
- cexp2(3)
- stdio_ext(3)
- login_tty(3)
- xdr_long(3)
- dlsym(3)
- clog2l(3)
- malloc_usable_size(3)
- fegetexceptflag(3)
- basename(3)
- fwrite(3)
- vhangup(2)
- printf(3)
- setnetent(3)
- gethostbyname2(3)
- mallinfo2(3)
- signbit(3)
- clnt_broadcast(3)
- sched_yield(2)
- sem_open(3)
- sigsetjmp(3)
- cacoshl(3)
- sem_unlink(3)
- setresuid(2)
- signgam(3)
- putw(3)
- imaxdiv(3)
- regex(3)
- alloc_hugepages(2)
- modff(3)
- exp10(3)
- cprojl(3)
- utime(2)
- clogf(3)
- pthread_mutex_unlock(3)
- erff(3)
- ioctl_userfaultfd(2)
- iswprint(3)
- roundl(3)
- sqrtl(3)
- fpurge(3)
- getusershell(3)
- fcloseall(3)
- xdr_opaque_auth(3)
- gethostent_r(3)
- fgetwc_unlocked(3)
- fchmod(2)
- strptime(3)
- lutimes(3)
- htole64(3)
- putchar_unlocked(3)
- create_module(2)
- isascii_l(3)
- sigaction(2)
- stdout(3)
- geteuid32(2)
- xprt_register(3)
- freopen(3)
- ccosl(3)
- pthread_setschedprio(3)
- rt_sigaction(2)
- getmntent(3)
- putwchar_unlocked(3)
- logl(3)
- remque(3)
- unsetenv(3)
- sigwaitinfo(2)
- pthread_mutexattr_getrobust_np(3)
- initstate_r(3)
- getfsfile(3)
- exp2l(3)
- isatty(3)
- lgamma_r(3)
- lrintf(3)
- outb(2)
- __clone2(2)
- strcpy(3)
- clnt_call(3)
- hypot(3)
- fegetexcept(3)
- tcsetpgrp(3)
- gets(3)
- malloc_info(3)
- nextupf(3)
- pthread_attr_getdetachstate(3)
- getaliasent_r(3)
- fstat64(2)
- futimesat(2)
- dl_iterate_phdr(3)
- posix_madvise(3)
- endnetgrent(3)
- tolower_l(3)
- pthread_attr_setstack(3)
- pread64(2)
- sigsetops(3)
- stty(2)
- process_vm_readv(2)
- isfinite(3)
- gethostbyaddr_r(3)
- cproj(3)
- gai_strerror(3)
- key_decryptsession(3)
- inet_ntop(3)
- __ppc_mdoio(3)
- btowc(3)
- setstate_r(3)
- if_nameindex(3)
- fdetach(2)
- random_r(3)
- iruserok_af(3)
- truncl(3)
- clearerr(3)
- lgammaf(3)
- lfind(3)
- ctanf(3)
- strcat(3)
- pthread_attr_getschedpolicy(3)
- pthread_rwlockattr_getkind_np(3)
- sigrelse(3)
- daemon(3)
- pthread_setcanceltype(3)
- sigevent(7)
- iswalnum(3)
- pmap_set(3)
- stdin(3)
- ceilf(3)
- asctime_r(3)
- poll(2)
- svc_unregister(3)
- isnanl(3)
- carg(3)
- getprotobyname(3)
- arm_fadvise(2)
- optind(3)
- mount_setattr(2)
- dlvsym(3)
- ntp_adjtime(3)
- abort(3)
- pthread_getname_np(3)
- execlp(3)
- bind(2)
- bsearch(3)
- endspent(3)
- register_printf_specifier(3)
- landlock_create_ruleset(2)
- mkostemp(3)
- setgroups(2)
- toupper_l(3)
- argz_extract(3)
- sigblock(3)
- j0l(3)
- argz_delete(3)
- setusershell(3)
- getspnam(3)
- optarg(3)
- vm86old(2)
- sigandset(3)
- getdtablesize(3)
- getsockname(2)
- pthread_sigqueue(3)
- ptsname(3)
- j1(3)
- lgamma(3)
- getpagesize(2)
- pthread_mutex_lock(3)
- setsid(2)
- strncat(3)
- ioctl_kd(2)
- tsearch(3)
- mq_notify(2)
- fcvt(3)
- clntudp_bufcreate(3)
- getpwent_r(3)
- pthread_getspecific(3)
- memfrob(3)
- arc4random_buf(3)
- forkpty(3)
- powl(3)
- dlopen(3)
- stderr(3)
- set_thread_area(2)
- query_module(2)
- sem_close(3)
- strndup(3)
- __malloc_hook(3)
- setjmp(3)
- stdio(3)
- bdflush(2)
- sendto(2)
- mpx(2)
- fopen(3)
- setpriority(2)
- nextdownl(3)
- mprobe(3)
- oldstat(2)
- sem_destroy(3)
- bcopy(3)
- remap_file_pages(2)
- isgreaterequal(3)
- getpass(3)
- seekdir(3)
- break(2)
- authunix_create_default(3)
- tty_ioctl(4)
- process_madvise(2)
- endfsent(3)
- atoq(3)
- strftime(3)
- fts(3)
- getgrgid(3)
- isxdigit(3)
- ftello(3)
- regcomp(3)
- error(3)
- getenv(3)
- clnt_sperrno(3)
- readahead(2)
- y0(3)
- roundup(3)
- io_destroy(2)
- vsnprintf(3)
- lgammal(3)
- eventfd_write(3)
- pthread_mutex_trylock(3)
- lchown(2)
- dladdr(3)
- error_print_progname(3)
- pthread_mutexattr_settype(3)
- strspn(3)
- __after_morecore_hook(3)
- localtime(3)
- fsync(2)
- ether_aton(3)
- csinhl(3)
- trunc(3)
- xdr_u_char(3)
- syslog(3)
- y1f(3)
- ioctl_nsfs(2)
- wmemcmp(3)
- ffsll(3)
- ether_ntohost(3)
- bswap_32(3)
- umount2(2)
- sigfillset(3)
- landlock_restrict_self(2)
- pthread_join(3)
- sysinfo(2)
- clock_settime(2)
- llrint(3)
- s390_guarded_storage(2)
- getc(3)
- inet_lnaof(3)
- tcgetpgrp(3)
- clock_getres(2)
- etext(3)
- strfmon_l(3)
- putwc_unlocked(3)
- xdr_replymsg(3)
- scalbl(3)
- fdim(3)
- getspent(3)
- sem_timedwait(3)
- posix_fallocate(3)
- res_nmkquery(3)
- pthread_spin_unlock(3)
- mq_timedsend(2)
- opterr(3)
- getloadavg(3)
- strsignal(3)
- finite(3)
- inw_p(2)
- csinhf(3)
- execveat(2)
- seed48(3)
- sigset(3)
- setgroups32(2)
- logbl(3)
- wcsdup(3)
- clnt_geterr(3)
- sys_errlist(3)
- inotify_rm_watch(2)
- qgcvt(3)
- wcspbrk(3)
- sin(3)
- lookup_dcookie(2)
- s390_pci_mmio_read(2)
- wcscmp(3)
- getutxent(3)
- pciconfig_read(2)
- initstate(3)
- backtrace(3)
- putc_unlocked(3)
- fedisableexcept(3)
- rt_sigprocmask(2)
- clock_adjtime(2)
- fwprintf(3)
- jnl(3)
- grantpt(3)
- cimagl(3)
- getgrnam_r(3)
- remquol(3)
- swprintf(3)
- mbrtowc(3)
- fileno_unlocked(3)
- readlinkat(2)
- sigignore(3)
- strndupa(3)
- semctl(2)
- assert_perror(3)
- sendfile(2)
- shm_unlink(3)
- log(3)
- ungetc(3)
- erf(3)
- qfcvt(3)
- pthread_atfork(3)
- login(3)
- setservent(3)
- jrand48_r(3)
- wcsnlen(3)
- tcflow(3)
- pthread_cond_destroy(3)
- inl(2)
- srand48_r(3)
- erfcf(3)
- iconv(3)
- pthread_mutex_consistent_np(3)
- fabsl(3)
- pclose(3)
- nfsservctl(2)
- gai_error(3)
- wcsncmp(3)
- islower_l(3)
- iswctype(3)
- svc_register(3)
- arm_sync_file_range(2)
- strfry(3)
- strfromd(3)
- getttyent(3)
- rand(3)
- fchown32(2)
- ctime(3)
- fsetxattr(2)
- feupdateenv(3)
- random(3)
- getpwnam_r(3)
- sigwait(3)
- aio_fsync(3)
- mq_open(2)
- tanh(3)
- localtime_r(3)
- bsd_signal(3)
- strsep(3)
- mknodat(2)
- cexpf(3)
- cacosh(3)
- mbrlen(3)
- aio_cancel(3)
- mq_getsetattr(2)
- fdatasync(2)
- htons(3)
- sem_post(3)
- htobe16(3)
- vtimes(3)
- fgetpwent_r(3)
- getwchar_unlocked(3)
- mkdirat(2)
- dup(2)
- free_hugepages(2)
- feraiseexcept(3)
- lockf(3)
- userfaultfd(2)
- pthread_attr_setaffinity_np(3)
- memcpy(3)
- prlimit64(2)
- ferror(3)
- ldexpf(3)
- aio_return(3)
- adjtimex(2)
- execle(3)
- tailq(3)
- cabs(3)
- endaliasent(3)
- execvp(3)
- hasmntopt(3)
- if_freenameindex(3)
- signal(2)
- dn_comp(3)
- pthread_attr_getstack(3)
- ether_hostton(3)
- re_comp(3)
- cexp2l(3)
- getwd(3)
- llroundl(3)
- cos(3)
- pthread_mutex_consistent(3)
- isalpha_l(3)
- io_cancel(2)
- frexp(3)
- finitel(3)
- perf_event_open(2)
- pthread_exit(3)
- ioctl_console(2)
- timelocal(3)
- timersub(3)
- setresgid(2)
- semop(2)
- getgroups(2)
- envz_entry(3)
- xdr_u_long(3)
- seccomp(2)
- ftrylockfile(3)
- setuid(2)
- wcwidth(3)
- llround(3)
- cacoshf(3)
- pthread_attr_setschedpolicy(3)
- fgetpos(3)
- xdr_array(3)
- sprintf(3)
- wmemset(3)
- setcontext(3)
- copysignl(3)
- be64toh(3)
- matherr(3)
- hypotl(3)
- rawmemchr(3)
- fmodf(3)
- mount(2)
- mktime(3)
- stdarg(3)
- clnttcp_create(3)
- string(3)
- profil(3)
- clnt_perror(3)
- getpriority(2)
- regerror(3)
- clone2(2)
- getgid(2)
- pthread_spin_lock(3)
- iswblank(3)
- ftell(3)
- dup3(2)
- toascii(3)
- strncpy(3)
- mrand48_r(3)
- setstate(3)
- sigqueue(3)
- cpowf(3)
- setlogmask(3)
- sched_getcpu(3)
- htobe32(3)
- list(3)
- isdigit_l(3)
- chdir(2)
- fstat(2)
- pwritev2(2)
- get_thread_area(2)
- freelocale(3)
- acoshl(3)
- socketpair(2)
- scalbln(3)
- fpclassify(3)
- getpwnam(3)
- pthread_getcpuclockid(3)
- ioprio_get(2)
- strtok_r(3)
- exit_group(2)
- scalbnf(3)
- xdrrec_create(3)
- pthread_mutex_destroy(3)
- sqrt(3)
- dirname(3)
- exit(2)
- ulckpwdf(3)
- cargl(3)
- powerof2(3)
- simpleq(3)
- process_vm_writev(2)
- fdopendir(3)
- getpt(3)
- floorl(3)
- va_start(3)
- lcong48(3)
- strerror_l(3)
- xdrrec_eof(3)
- key_setsecret(3)
- lstat64(2)
- memfd_secret(2)
- sigreturn(2)
- casinhf(3)
- valloc(3)
- stat64(2)
- jn(3)
- sinl(3)
- pthread_testcancel(3)
- cfgetispeed(3)
- dup2(2)
- getnetent(3)
- pthread_setconcurrency(3)
- memccpy(3)
- rt_sigqueueinfo(2)
- ccosf(3)
- sincos(3)
- tcdrain(3)
- ccos(3)
- chmod(2)
- cacosf(3)
- lstat(2)
- pthread_spin_trylock(3)
- sigisemptyset(3)
- getrpcbyname(3)
- fpathconf(3)
- copysign(3)
- round(3)
- wmemchr(3)
- qfcvt_r(3)
- fattach(2)
- __fsetlocking(3)
- adjtime(3)
- makedev(3)
- des_crypt(3)
- iswspace(3)
- twalk(3)
- exec(3)
- link(2)
- fileno(3)
- endpwent(3)
- logb(3)
- wcscspn(3)
- console_ioctl(4)
- fgetpwent(3)
- setegid(2)
- clnt_destroy(3)
- getaddrinfo_a(3)
- svc_getargs(3)
- addmntent(3)
- globfree(3)
- islower(3)
- muntrace(3)
- clnt_pcreateerror(3)
- llrintl(3)
- clnt_control(3)
- fgetspent_r(3)
- strstr(3)
- putmsg(2)
- __fwritable(3)
- res_nsearch(3)
- fseeko(3)
- mq_timedreceive(3)
- log10(3)
- fexecve(3)
- gammaf(3)
- pthread_setschedparam(3)
- wcscpy(3)
- xdr_float(3)
- pthread_attr_setdetachstate(3)
- sem_wait(3)
- pow10l(3)
- re_exec(3)
- rand_r(3)
- putpmsg(2)
- getdelim(3)
- utimes(2)
- mq_close(3)
- setutent(3)
- creall(3)
- mq_send(3)
- telldir(3)
- powf(3)
- erfl(3)
- pthread_self(3)
- pselect6(2)
- unlocked_stdio(3)
- insw(2)
- cfsetspeed(3)
- argz_create(3)
- xdr_string(3)
- pthread_attr_getguardsize(3)
- finitef(3)
- setlocale(3)
- bcmp(3)
- fmtmsg(3)
- sendmsg(2)
- pthread_cleanup_push(3)
- inb_p(2)
- mmap64(3)
- getuid32(2)
- truncate(2)
- mlock2(2)
- fegetround(3)
- ugetrlimit(2)
- getprotobynumber_r(3)
- utmpxname(3)
- isinf(3)
- clearerr_unlocked(3)
- stime(2)
- nftw(3)
- duplocale(3)
- svcraw_create(3)
- svc_getcaller(3)
- ctanhl(3)
- cbrt(3)
- floorf(3)
- sethostid(3)
- sigemptyset(3)
- sigaltstack(2)
- mkfifo(3)
- lsearch(3)
- getservent_r(3)
- islessgreater(3)
- floor(3)
- argz_append(3)
- tzset(3)
- res_mkquery(3)
- fstatat(2)
- strchr(3)
- semtimedop(2)
- bindresvport(3)
- tcsetattr(3)
- warn(3)
- getservent(3)
- atanhl(3)
- tdelete(3)
- ynf(3)
- ether_ntoa_r(3)
- fesetenv(3)
- mq_timedsend(3)
- quotactl(2)
- init_module(2)
- rcmd(3)
- fenv(3)
- getutxid(3)
- pthread_mutexattr_getpshared(3)
- scalbnl(3)
- atan2l(3)
- argz_count(3)
- rpmatch(3)
- timerfd_gettime(2)
- ualarm(3)
- pthread_attr_init(3)
- vdprintf(3)
- pthread_cancel(3)
- fflush(3)
- setkey_r(3)
- mbstowcs(3)
- mremap(2)
- strcasestr(3)
- hcreate_r(3)
- siginterrupt(3)
- offsetof(3)
- atan(3)
- wctomb(3)
- getutent(3)
- significand(3)
- arm_fadvise64_64(2)
- dremf(3)
- wcswidth(3)
- syscall(2)
- rintf(3)
- bswap_64(3)
- pthread_attr_getschedparam(3)
- lroundf(3)
- timegm(3)
- posix_fadvise(2)
- getrlimit(2)
- svc_freeargs(3)
- xdr_enum(3)
- hcreate(3)
- ptrace(2)
- backtrace_symbols_fd(3)
- fetestexcept(3)
- ccosh(3)
- htole32(3)
- kexec_load(2)
- fallocate(2)
- timer_gettime(2)
- tgammaf(3)
- errno(3)
- sched_get_priority_max(2)
- xdr_getpos(3)
- vwprintf(3)
- ssetmask(2)
- ether_ntoa(3)
- waitpid(2)
- sched_getattr(2)
- inotify_init(2)
- fma(3)
- gnu_get_libc_version(3)
- svctcp_create(3)
- wcstombs(3)
- gethostname(2)
- strerror_r(3)
- sigismember(3)
- fgetws_unlocked(3)
- hash(3)
- circleq(3)
- getrpcbynumber_r(3)
- pthread_cond_timedwait(3)
- uname(2)
- fgetc_unlocked(3)
- mq_open(3)
- cosl(3)
- rewinddir(3)
- nextdown(3)
- longjmp(3)
- execv(3)
- iconv_open(3)
- xencrypt(3)
- ctermid(3)
- isgraph_l(3)
- move_pages(2)
- isunordered(3)
- msgsnd(2)
- rt_sigtimedwait(2)
- syncfs(2)
- mlockall(2)
- pthread_getschedparam(3)
- lsetxattr(2)
- getutid_r(3)
- log1pl(3)
- catanf(3)
- passwd2des(3)
- iconv_close(3)
- aligned_alloc(3)
- sched_setscheduler(2)
- gmtime(3)
- __free_hook(3)
- acoshf(3)
- mtrace(3)
- resolver(3)
- clog10f(3)
- sethostname(2)
- pthread_attr_setguardsize(3)
- tuxcall(2)
- atanh(3)
- ispunct_l(3)
- svcudp_bufcreate(3)
- ctanh(3)
- j1l(3)
- log10l(3)
- alloca(3)
- sigpending(2)
- nexttoward(3)
- isnormal(3)
- svc_getreq(3)
- putchar(3)
- getnetbyaddr(3)
- cpowl(3)
- get_kernel_syms(2)
- getutline_r(3)
- pthread_setaffinity_np(3)
- isnan(3)
- getprotoent(3)
- catclose(3)
- getsid(2)
- endrpcent(3)
- fts_close(3)
- gnu_dev_minor(3)
- ruserok_af(3)
- getutent_r(3)
- getegid(2)
- sgetmask(2)
- posix_memalign(3)
- atanf(3)
- unshare(2)
- lremovexattr(2)
- strncasecmp(3)
- endutent(3)
- updwtmpx(3)
- outsw(2)
- sched_getparam(2)
- setuid32(2)
- catgets(3)
- nextupl(3)
- openat(2)
- logout(3)
- free(3)
- setfsuid(2)
- getutline(3)
- svc_sendreply(3)
- fadvise64_64(2)
- cargf(3)
- __ppc_set_ppr_low(3)
- casinh(3)
- outb_p(2)
- fputwc(3)
- log10f(3)
- getnetgrent(3)
- fputws_unlocked(3)
- ffsl(3)
- endttyent(3)
- isgreater(3)
- sigmask(3)
- sgetspent_r(3)
- fmaxf(3)
- openlog(3)
- strncmp(3)
- closedir(3)
- rexec_af(3)
- exp2(3)
- mcheck(3)
- isalpha(3)
- pthread_mutex_init(3)
- catopen(3)
- clock_nanosleep(2)
- ioctl(2)
- remainder(3)
- olduname(2)
- getcpu(2)
- setns(2)
- asinhl(3)
- wcscasecmp(3)
- nearbyintl(3)
- atan2f(3)
- wctob(3)
- nextdownf(3)
- gmtime_r(3)
- fmal(3)
- setfsgid32(2)
- dlinfo(3)
- posix_spawnp(3)
- fgets_unlocked(3)
- major(3)
- fseek(3)
- xdr_callhdr(3)
- execve(2)
- exit(3)
- makecontext(3)
- sysctl(2)
- oldolduname(2)
- getgrouplist(3)
- pthread_getattr_np(3)
- ffs(3)
- sem_init(3)
- gcvt(3)
- fts_children(3)
- rt_sigreturn(2)
- mallinfo(3)
- insl(2)
- geteuid(2)
- signalfd(2)
- erfcl(3)
- sched_get_priority_min(2)
- sched_setaffinity(2)
- wcsrchr(3)
- xdr_reference(3)
- snprintf(3)
- delete_module(2)
- j0f(3)
- malloc_hook(3)
- casinf(3)
- y0f(3)
- endgrent(3)
- y1l(3)
- pthread_create(3)
- wcsncasecmp(3)
- pidfd_getfd(2)
- htobe64(3)
- _sysctl(2)
- lrand48_r(3)
- warnx(3)
- lgammaf_r(3)
- verrx(3)
- finit_module(2)
- gsignal(3)
- recvfrom(2)
- log2(3)
- fflush_unlocked(3)
- getaliasbyname_r(3)
- pthread_mutexattr_setrobust(3)
- getdirentries(3)
- getrpcbyname_r(3)
- ppoll(2)
- tmpfile(3)
- isupper_l(3)
- xdr_free(3)
- res_nquery(3)
- fts_open(3)
- shutdown(2)
- xdr_callmsg(3)
- coshl(3)
- ntp_gettimex(3)
- afs_syscall(2)
- be32toh(3)
- fchmodat(2)
- addseverity(3)
- pause(2)
- strcmp(3)
- mkostemps(3)
- wcsrtombs(3)
- scandir(3)
- __freadable(3)
- killpg(3)
- add_key(2)
- strcoll(3)
- migrate_pages(2)
- pthread_setattr_default_np(3)
- pthread_attr_setsigmask_np(3)
- sigabbrev_np(3)
- readdir(2)
- subpage_prot(2)
- strfromf(3)
- sysv_signal(3)
- gethostbyname2_r(3)
- outl_p(2)
- sync(2)
- pthread_attr_getinheritsched(3)
- socket(2)
- msgrcv(2)
- fgetws(3)
- pthread_cleanup_push_defer_np(3)
- getnetgrent_r(3)
- ynl(3)
- endservent(3)
- srand(3)
- endmntent(3)
- cbrtl(3)
- setitimer(2)
- pmap_rmtcall(3)
- svcerr_systemerr(3)
- fesetround(3)
- ilogbf(3)
- __fwriting(3)
- log1p(3)
- futimens(3)
- xdrrec_endofrecord(3)
- setreuid32(2)
- swab(3)
- pthread_spin_init(3)
- memchr(3)
- fminf(3)
- getipnodebyname(3)
- msgop(2)
- wait(2)
- ether_aton_r(3)
- open_wmemstream(3)
- xdr_bool(3)
- pthread_tryjoin_np(3)
- xdr_int(3)
- inet_net_ntop(3)
- fdimf(3)
- srand48(3)
- xdr_setpos(3)
- asinf(3)
- program_invocation_name(3)
- write(2)
- mkdtemp(3)
- pthread_cleanup_pop(3)
- ptsname_r(3)
- lgammal_r(3)
- pthread_attr_getstackaddr(3)
- authunix_create(3)
- getpmsg(2)
- ceill(3)
- cexp2f(3)
- kcmp(2)
- setup(2)
- err(3)
- sync_file_range2(2)
- getpid(2)
- wcsncat(3)
- envz_get(3)
- futimes(3)
- mincore(2)
- herror(3)
- ether_line(3)
- feholdexcept(3)
- fputc(3)
- keyctl(2)
- timer_delete(2)
- posix_spawn(3)
- faccessat2(2)
- setnetgrent(3)
- pwrite(2)
- aio_read(3)
- shmget(2)
- acosh(3)
- sigdelset(3)
- __ppc_get_timebase(3)
- __flbf(3)
- dladdr1(3)
- argz_create_sep(3)
- mblen(3)
- gethostent(3)
- pciconfig_iobase(2)
- recvmmsg(2)
- isprint_l(3)
- csqrtf(3)
- wcstoimax(3)
- hsearch_r(3)
- svcudp_create(3)
- setreuid(2)
- le16toh(3)
- name_to_handle_at(2)
- strftime_l(3)
- pthread_attr_setschedparam(3)
- eventfd(2)
- atanhf(3)
- pthread_setspecific(3)
- pthread_cond_init(3)
- acosl(3)
- llistxattr(2)
- fputwc_unlocked(3)
- scanf(3)
- getmntent_r(3)
- getchar(3)
- res_ninit(3)
- error_one_per_line(3)
- sigsetmask(3)
- putwchar(3)
- llroundf(3)
- rt_sigpending(2)
- send(2)
- wcsstr(3)
- log2l(3)
- fmod(3)
- va_copy(3)
- res_search(3)
- res_nsend(3)
- res_query(3)
- wait3(2)
- encrypt_r(3)
- system(3)
- close_range(2)
- ecvt_r(3)
- read(2)
- auth_destroy(3)
- realloc(3)
- pipe2(2)
- dn_expand(3)
- timerclear(3)
- get_avphys_pages(3)
- mbsnrtowcs(3)
- strtok(3)
- fwide(3)
- __ppc_get_timebase_freq(3)
- gai_suspend(3)
- stpcpy(3)
- lldiv(3)
- iswxdigit(3)
- posix_openpt(3)
- s390_pci_mmio_write(2)
- pthread_spin_destroy(3)
- callrpc(3)
- getifaddrs(3)
- aio_suspend(3)
- fread_unlocked(3)
- get_nprocs_conf(3)
- getuid(2)
- spu_run(2)
- termios(3)
- umask(2)
- csqrtl(3)
- register_printf_modifier(3)
- sem_trywait(3)
- tee(2)
- msync(2)
- mpool(3)
- setdomainname(2)
- fopencookie(3)
- nl_langinfo(3)
- sockatmark(3)
- getspent_r(3)
- casinhl(3)
- fdiml(3)
- ntohs(3)
- fgets(3)
- time(2)
- casinl(3)
- pthread_detach(3)
- seccomp_unotify(2)
apt-get install manpages-dev
Available languages:
en fr ja ruManual
futex
NOMBIBLIOTHĂQUE
SYNOPSIS
DESCRIPTION
Argument
Opérations futex
Futex et héritage de priorité
VALEUR RENVOYĂE
ERREURS
STANDARDS
HISTORIQUE
EXEMPLES
Source du programme
VOIR AUSSI
TRADUCTION
NOM
futex â Verrouillage rapide en mode utilisateur
BIBLIOTHĂQUE
BibliothĂšque C standard ( libc , -lc )
SYNOPSIS
#include
<linux/futex.h>
/* Définition des
constantes
FUTEX_*
*/
#include <sys/syscall.h>
/* Définition des
constantes
SYS_*
*/
#include <unistd.h>
long
syscall(SYS_futex, uint32_t *
uaddr
, int
futex_op
, uint32_t
val
,
const struct timespec *
timeout
,
/*
ou :
uint32_t
val2
*/
uint32_t *
uaddr2
, uint32_t
val3
);
Remarque : la glibc ne fournit pas de fonction autour de futex (), nĂ©cessitant lâutilisation de syscall (2).
DESCRIPTION
Lâappel systĂšme futex () offre une mĂ©thode pour attendre quâune condition soit vraie. On lâutilise en gĂ©nĂ©ral comme construction de blocage dans le contexte de la synchronisation de la mĂ©moire partagĂ©e. Quand on utilise des futex, la majoritĂ© des opĂ©rations de synchronisation sâeffectue dans lâespace utilisateur. Un programme de lâespace utilisateur nâutilise lâappel systĂšme futex () que lorsquâil est probable quâil doive se bloquer plus longtemps avant que la condition ne soit vraie. Dâautres opĂ©rations futex () peuvent ĂȘtre utilisĂ©es pour rĂ©veiller des processus ou des threads qui attendent une condition en particulier.
Un futex est une valeur 32 bits â dĂ©signĂ©e ci-dessous comme « mot futex » âdont lâadresse est fournie Ă lâappel systĂšme futex () (les futex ont une taille de 32 bits sur toutes les plateformes, y compris les systĂšmes 64 bits). Toutes les opĂ©rations futex sont pilotĂ©es par cette valeur. Afin de partager un futex entre des processus, le futex est placĂ© dans une zone de la mĂ©moire partagĂ©e créée en utilisant (par exemple) mmap (2) ou shmat (2) (ainsi, le mot futex peut avoir plusieurs adresses virtuelles dans diffĂ©rents processus, mais ces adresses se rapportent toutes au mĂȘme emplacement de la mĂ©moire physique). Dans un programme multithreadĂ©, il suffit de mettre le mot futex dans une variable globale partagĂ©e par tous les threads.
Lors de lâexĂ©cution dâune opĂ©ration futex qui demande le blocage dâun thread, le noyau ne le bloquera que si le mot futex a une valeur fournie par le thread appelant (en tant quâun des paramĂštres de lâappel futex ()) correspondant Ă celle prĂ©vue du mot futex. Le chargement de la valeur du mot futex, la comparaison de cette valeur avec celle attendue et le blocage sâeffectueront de maniĂšre atomique et seront entiĂšrement organisĂ©s par rapport aux opĂ©rations qui sont effectuĂ©es en parallĂšle par dâautres threads sur le mĂȘme mot futex. Ainsi, le mot futex est utilisĂ© pour relier la synchronisation de lâespace utilisateur et lâimplĂ©mentation du blocage par le noyau. Tout comme une opĂ©ration compare-and-exchange atomique qui modifie potentiellement la mĂ©moire partagĂ©e, le blocage par futex est une opĂ©ration compare-and-block atomique.
Une utilisation des futex consiste Ă implĂ©menter des verrous. LâĂ©tat du verrou (câest-Ă -dire acquis ou non acquis) peut se reprĂ©senter comme un drapeau auquel on a un accĂšs atomique en mĂ©moire partagĂ©e. En absence de conflit (uncontended case), un thread peut accĂ©der et modifier lâĂ©tat du verrou avec des instructions atomiques, par exemple le passer de maniĂšre atomique de lâĂ©tat non acquis Ă acquis, en utilisant une instruction compare-and-exchange atomique (de telles instructions sâeffectuent entiĂšrement dans lâespace utilisateur et le noyau ne conserve aucune information sur lâĂ©tat du verrou). Dâun autre cĂŽtĂ©, un thread peut ĂȘtre incapable dâacquĂ©rir un verrou parce quâil est dĂ©jĂ acquis par un autre thread. Il peut alors passer lâattribut du verrou en tant que mot futex, et la valeur reprĂ©sentant lâĂ©tat acquis en tant que valeur attendue pour lâopĂ©ration dâattente de futex (). Cette opĂ©ration futex () bloquera si et seulement si le verrou est encore acquis (câest-Ă -dire si la valeur du mot futex correspond toujours à « lâĂ©tat acquis »). Lorsque le verrou est relĂąchĂ©, le thread doit dâabord rĂ©initialiser lâĂ©tat du verrou sur non acquis puis exĂ©cuter une opĂ©ration futex qui rĂ©veille les threads bloquĂ©s par le drapeau de verrou utilisĂ© en tant que mot futex (cela peut ĂȘtre mieux optimisĂ© pour Ă©viter les rĂ©veils inutiles). Voir futex (7) pour plus de dĂ©tails sur la maniĂšre dâutiliser les futex.
Outre la fonctionnalitĂ© de base du futex consistant Ă attendre et Ă rĂ©veiller, dâautres opĂ©rations futex visent Ă gĂ©rer des cas dâutilisation plus complexes.
Remarquez quâaucune initialisation ou destruction explicite nâest nĂ©cessaire pour utiliser les futex ; le noyau ne garde un futex (câest-Ă -dire un artefact dâimplĂ©mentation interne au noyau) que pendant que les opĂ©rations telles que FUTEX_WAIT , dĂ©crite ci-dessous, sâeffectuent sur un mot futex en particulier.
Argument
Le paramĂštre uaddr pointe vers un mot futex. Sur toutes les plateformes, les futex sont des entiers de quatre octets qui doivent ĂȘtre alignĂ©s sur une limite de quatre octets. LâopĂ©ration Ă effectuer sur le futex est indiquĂ©e dans le paramĂštre de futex_op ; val est une valeur dont la signification et lâobjectif dĂ©pendent de futex_op .
Les autres paramĂštres ( timeout , uaddr2 et val3 ) ne sont nĂ©cessaires que pour certaines opĂ©rations futex dĂ©crites ci-dessous. Si un de ces arguments nâest pas nĂ©cessaire, il est ignorĂ©.
Pour plusieurs opĂ©rations de blocage, le paramĂštre timeout est un pointeur vers une structure timespec qui indique la durĂ©e maximale de lâopĂ©ration. Toutefois, contrairement au prototype dĂ©crit ci-dessus, pour certaines opĂ©rations, les quatre octets les moins significatifs de ce paramĂštre sont utilisĂ©s comme un entier dont la signification est dĂ©terminĂ©e par lâopĂ©ration. Pour ces opĂ©rations, le noyau diffuse la valeur timeout dâabord Ă unsigned long , puis Ă uint32_t , et dans le reste de cette page, ce paramĂštre est dĂ©signĂ© par val2 quand il est interprĂ©tĂ© de cette maniĂšre.
Lorsquâil est nĂ©cessaire, le paramĂštre uaddr2 est un pointeur vers un deuxiĂšme mot futex utilisĂ© par lâopĂ©ration.
LâinterprĂ©tation du paramĂštre de lâentier final, val3 , dĂ©pend de lâopĂ©ration.
Opérations futex
Le
paramĂštre
futex_op
est en deux parties :
une commande qui indique lâopĂ©ration Ă
effectuer et un bit ORed avec zéro ou plusieurs
options qui changent le comportement de
lâopĂ©ration. Les options qui peuvent ĂȘtre
incluses dans
futex_op
sont les suivantes :
FUTEX_PRIVATE_FLAG
(depuis Linux 2.6.22)
Ce bit dâoption peut ĂȘtre utilisĂ© avec toutes les opĂ©rations futex. Il dit au noyau que le futex est un processus privĂ© non partagĂ© avec dâautres processus (câest-Ă -dire quâil nâest utilisĂ© que pour la synchronisation entre les threads du mĂȘme processus). Cela permet au noyau dâeffectuer des optimisations de performance supplĂ©mentaires.
Par commoditĂ©, <linux/futex.h> dĂ©finit un ensemble de constantes dont le suffixe est _PRIVATE et qui sont Ă©quivalentes Ă toutes les opĂ©rations listĂ©es ci-dessous mais avec lâattribut FUTEX_PRIVATE_FLAG ORed dans la valeur de la constante. On trouve ainsi FUTEX_WAIT_PRIVATE , FUTEX_WAKE_PRIVATE et ainsi de suite.
FUTEX_CLOCK_REALTIME (depuis Linux 2.6.28)
Ce bit dâoption ne peut ĂȘtre utilisĂ© quâavec les opĂ©rations FUTEX_WAIT_BITSET , FUTEX_WAIT_REQUEUE_PI (depuis Linux 4.5), FUTEX_WAIT (depuis Linux 4.5) et FUTEX_LOCK_PI2 (depuis Linux 5.14).
Si cette option est positionnĂ©e, le noyau mesure le timeout par rapport Ă lâhorloge CLOCK_REALTIME .
Si cette option nâest pas positionnĂ©e, le noyau mesure le timeout par rapport Ă lâhorloge CLOCK_MONOTONIC .
LâopĂ©ration
indiquée dans
futex_op
prend une de ces
valeurs :
FUTEX_WAIT
(depuis Linux 2.6.0)
Cette option teste que la valeur du mot futex vers laquelle pointe lâadresse uaddr contient toujours la valeur val attendue, et si tel est le cas, elle sâendort jusquâĂ une opĂ©ration FUTEX_WAKE sur le mot futex. Le chargement de la valeur du mot futex est un accĂšs en mĂ©moire atomique (câest-Ă -dire quâil utilise des instructions machine atomiques de lâarchitecture concernĂ©e). Ce chargement, la comparaison avec la valeur attendue et la mise en sommeil sâeffectuent de maniĂšre atomique et sont totalement organisĂ©s selon les autres opĂ©rations futex sur le mĂȘme mot futex. Si le thread commence Ă dormir, il est considĂ©rĂ© comme en attente de ce mot futex. Si la valeur futex ne correspond pas Ă val , lâappel Ă©choue immĂ©diatement avec lâerreur EAGAIN .
Le but de la comparaison avec la valeur attendue est dâempĂȘcher des rĂ©veils perdus. Si un autre thread a changĂ© la valeur du mot futex aprĂšs que le thread a dĂ©cidĂ© de se bloquer en se fondant sur la valeur dâavant, et si lâautre thread a effectuĂ© une opĂ©ration FUTEX_WAKE (ou un rĂ©veil Ă©quivalent) aprĂšs le changement de cette valeur et avant cette opĂ©ration FUTEX_WAIT , le thread appelant observera cette valeur et ne commencera pas Ă dormir.
Si le timeout nâest pas NULL, la structure vers laquelle il pointe indique un dĂ©lai dâattente (cet intervalle sera arrondi Ă la valeur supĂ©rieure Ă partir de la granularitĂ© de lâhorloge systĂšme et il est garanti de ne pas expirer en avance). Le dĂ©lai est mesurĂ© par dĂ©faut par rapport Ă lâhorloge CLOCK_MONOTONIC mais depuis Linux 4.5, lâhorloge CLOCK_REALTIME peut ĂȘtre choisie en indiquant FUTEX_CLOCK_REALTIME dans futex_op . Si le timeout est NULL, lâappel se bloque indĂ©finiment.
Remarque : pour FUTEX_WAIT , le timeout est interprĂ©tĂ© comme une valeur relative. Cela diffĂšre des autres opĂ©rations futex oĂč le timeout est interprĂ©tĂ© comme une valeur absolue. Pour obtenir lâĂ©quivalent de FUTEX_WAIT , avec un dĂ©lai absolu, utilisez FUTEX_WAIT_BITSET en indiquant val3 comme FUTEX_BITSET_MATCH_ANY .
Les paramÚtres uaddr2 et val3 sont ignorés.
FUTEX_WAKE (depuis Linux 2.6.0)
Cette opĂ©ration rĂ©veille jusquâĂ val Ă©lĂ©ments en attente (comme dans FUTEX_WAIT ) sur le mot futex Ă lâadresse uaddr . GĂ©nĂ©ralement, val est indiquĂ© soit sous la forme de 1 (rĂ©veil dâun seul Ă©lĂ©ment en attente) soit avec INT_MAX (rĂ©veil de tous les Ă©lĂ©ments en attente). Vous nâavez aucune garantie quant aux Ă©lĂ©ments qui sont rĂ©veillĂ©s (par exemple un Ă©lĂ©ment en attente dont la prioritĂ© dâordonnancement Ă©levĂ©e nâest pas garanti de se rĂ©veiller avant un autre dâune prioritĂ© plus basse).
Les paramÚtres timeout , uaddr2 et val3 sont ignorés.
FUTEX_FD (de Linux 2.6.0 jusquâĂ Linux 2.6.25 inclus)
Cette opĂ©ration crĂ©e un descripteur de fichier associĂ© au futex sur uaddr . Lâappelant doit fermer le descripteur de fichier renvoyĂ© aprĂšs lâavoir utilisĂ©. Quand un autre processus ou un autre thread effectue un FUTEX_WAKE sur le mot futex, le descripteur de fichier indique quâil est accessible en lecture avec select (2), poll (2), et epoll (7)
Le descripteur de fichier peut ĂȘtre utilisĂ© pour avoir des notifications asynchrones, si val nâest pas nul, puis, quand un autre processus ou un autre thread exĂ©cute FUTEX_WAKE , lâappelant recevra le numĂ©ro du signal passĂ© Ă val .
Les paramÚtres timeout , uaddr2 et val3 sont ignorés.
Parce quâil Ă©tait de façon inhĂ©rente sujet Ă des situations de concurrence, FUTEX_FD a Ă©tĂ© supprimĂ© de Linux 2.6.26 et les suivants.
FUTEX_REQUEUE (depuis Linux 2.6.0)
Cette opĂ©ration effectue la mĂȘme chose que FUTEX_CMP_REQUEUE (voir ci-dessous), sauf quâelle ne vĂ©rifie rien en utilisant la valeur dans val3 (le paramĂštre val3 est ignorĂ©).
FUTEX_CMP_REQUEUE (depuis Linux 2.6.7)
Cette opĂ©ration vĂ©rifie dâabord si lâemplacement uaddr contient toujours la valeur val3 . Si tel nâest pas le cas, lâopĂ©ration Ă©choue avec lâerreur EAGAIN . Si tel est le cas, lâopĂ©ration rĂ©veille un maximum de val Ă©lĂ©ments en attente du futex sur uaddr . Sâil y a plus de val Ă©lĂ©ments en attente, les autres sont supprimĂ©s de la file dâattente du futex source sur uaddr et ajoutĂ©s Ă la file dâattente du futex cible sur uaddr2 . Le paramĂštre val2 indique une limite supĂ©rieure du nombre dâĂ©lĂ©ments remis en attente dans le futex sur uaddr2 .
Le chargement Ă partir de uaddr est un accĂšs atomique en mĂ©moire (câest-Ă -dire quâil utilise les instructions machine atomiques de lâarchitecture concernĂ©e). Ce chargement, la comparaison avec val3 et la remise en attente dâĂ©lĂ©ments sâeffectuent de maniĂšre atomique et sont totalement organisĂ©es par rapport aux autres opĂ©rations sur le mĂȘme mot futex.
Les valeurs classiques quâon indique Ă val sont 0 ou 1 (indiquer INT_MAX nâest pas utile car cela rendrait lâopĂ©ration FUTEX_CMP_REQUEUE Ă©quivalente Ă FUTEX_WAKE ). La valeur limite indiquĂ©e avec val2 est gĂ©nĂ©ralement 1 ou INT_MAX (indiquer 0 en paramĂštre nâest pas utile car cela rendrait lâopĂ©ration FUTEX_CMP_REQUEUE Ă©quivalente Ă FUTEX_WAIT ).
LâopĂ©ration FUTEX_CMP_REQUEUE a Ă©tĂ© ajoutĂ©e pour remplacer lâancienne FUTEX_REQUEUE . La diffĂ©rence est que la vĂ©rification de la valeur sur uaddr peut ĂȘtre utilisĂ©e pour sâassurer que la remise en attente ne se produit que sous certaines conditions, ce qui Ă©vite les conflits de mĂ©moire (race conditions) dans certains cas dâutilisation.
FUTEX_REQUEUE et FUTEX_CMP_REQUEUE peuvent ĂȘtre utilisĂ©es pour Ă©viter des rĂ©veils en troupeau (thundering herd) qui peuvent survenir quand on utilise FUTEX_WAKE dans des cas oĂč tous les Ă©lĂ©ments en attente quâon rĂ©veille doivent acquĂ©rir un autre futex. Imaginons le scĂ©nario suivant oĂč plusieurs threads attendent en B, une file dâattente implĂ©mentĂ©e en utilisant un futex :
lock(A)
while (!check_value(V)) {
unlock(A);
block_on(B);
lock(A);
};
unlock(A);
Si un thread qui se rĂ©veille utilisait FUTEX_WAKE , tous les Ă©lĂ©ments attendant en B se rĂ©veilleraient et essaieraient dâacquĂ©rir le verrou A. Cependant, rĂ©veiller tous ces threads de cette maniĂšre serait vain car tous les threads, sauf un, se bloqueraient immĂ©diatement Ă nouveau via le verrou A. Au contraire, une remise dans la file dâattente ne rĂ©veille quâun Ă©lĂ©ment et dĂ©place les autres sur le verrou A et quand celui rĂ©veillĂ© dĂ©verrouille A, le suivant peut continuer.
FUTEX_WAKE_OP (depuis Linux 2.6.14)
Cette opĂ©ration a Ă©tĂ© ajoutĂ©e pour prendre en charge certains cas dâutilisation de lâespace utilisateur oĂč plus dâun futex Ă la fois doit ĂȘtre gĂ©rĂ©. Lâexemple le plus frappant est lâimplĂ©mentation de pthread_cond_signal (3), qui nĂ©cessite des opĂ©rations sur deux futex, une pour implĂ©menter le mutex, lâautre pour utiliser dans lâimplĂ©mentation de la file dâattente associĂ©e Ă la variable conditionnelle. FUTEX_WAKE_OP permet dâimplĂ©menter de tels cas sans augmenter le nombre de conflits et de changement de contexte.
LâopĂ©ration FUTEX_ WAKE_OP revient Ă exĂ©cuter le code suivant de maniĂšre atomique et complĂštement organisĂ© en fonction des opĂ©rations futex sur un des deux mots futex fournis :
uint32_t oldval
= *(uint32_t *) uaddr2;
*(uint32_t *) uaddr2 = oldval
op oparg
;
futex(uaddr, FUTEX_WAKE, val, 0, 0, 0);
if (oldval
cmp cmparg
)
futex(uaddr2, FUTEX_WAKE, val2, 0, 0, 0);
En dâautres termes, FUTEX_WAKE_OP fait ce qui suit :
|
- |
sauvegarde la valeur dâorigine du mot futex sur uaddr2 et effectue une opĂ©ration pour modifier la valeur du futex sur uaddr2 ; il sâagit dâun accĂšs en mĂ©moire read-modify-write atomique (câest-Ă -dire dâune utilisation des instructions machine atomiques liĂ©es Ă lâarchitecture concernĂ©e) |
||
|
- |
réveille un maximum de val éléments en attente sur le futex pour le mot futex sur uaddr ; |
||
|
- |
et selon les rĂ©sultats dâun test de la valeur dâorigine du mot futex sur uaddr2 , rĂ©veille un maximum de val2 Ă©lĂ©ments en attente du mot futex sur le futex sur uaddr2 . |
LâopĂ©ration et la comparaison qui doivent ĂȘtre effectuĂ©es sont encodĂ©es dans les bits du paramĂštre val3 . Visuellement, lâencodage est :
+---+---+-----------+-----------+
|op |cmp| oparg | cmparg |
+---+---+-----------+-----------+
4 4 12 12 <== # of bits
ExprimĂ© en code, lâencodage est :
#define
FUTEX_OP(op, oparg, cmp, cmparg) \
(((op & 0xf) << 28) | \
((cmp & 0xf) << 24) | \
((oparg & 0xfff) << 12) | \
(cmparg & 0xfff))
Dans ce qui précÚde, op et cmp sont chacun des codes listés ci-dessous. Les composants oparg et cmparg sont des valeurs numériques littérales, sauf les remarques ci-dessous.
Le composant op prend une de ces valeurs :
FUTEX_OP_SET 0
/* uaddr2 = oparg; */
FUTEX_OP_ADD 1 /* uaddr2 += oparg; */
FUTEX_OP_OR 2 /* uaddr2 |= oparg; */
FUTEX_OP_ANDN 3 /* uaddr2 &= ~oparg; */
FUTEX_OP_XOR 4 /* uaddr2 ^= oparg; */
En outre, comparer bit Ă bit (ORing) la valeur suivante dans op a pour consĂ©quence que (1 << oparg) sera utilisĂ© en tant quâopĂ©rande :
FUTEX_OP_ARG_SHIFT 8 /* Utiliser (1 << oparg) comme opérande */
Le champ cmp prend une de ces valeurs :
FUTEX_OP_CMP_EQ
0 /* si (oldval == cmparg) réveiller */
FUTEX_OP_CMP_NE 1 /* si (oldval != cmparg) réveiller
*/
FUTEX_OP_CMP_LT 2 /* si (oldval < cmparg)
réveiller */
FUTEX_OP_CMP_LE 3 /* si (oldval <= cmparg)
réveiller */
FUTEX_OP_CMP_GT 4 /* si (oldval > cmparg)
réveiller */
FUTEX_OP_CMP_GE 5 /* si (oldval >= cmparg)
réveiller */
Le code de retour de FUTEX_WAKE_OP est la somme du nombre dâĂ©lĂ©ments en attente rĂ©veillĂ©s par le futex uaddr et du nombre dâĂ©lĂ©ments en attente rĂ©veillĂ©s sur le futex uaddr2 .
FUTEX_WAIT_BITSET (depuis Linux 2.6.25)
Cette opĂ©ration est Ă©quivalente Ă FUTEX_WAIT , sauf que val3 est utilisĂ© pour fournir un masque de bit de 32 bits au noyau. Ce masque, oĂč au moins un bit doit ĂȘtre positionnĂ©, est stockĂ© dans la partie interne du noyau de lâĂ©lĂ©ment en attente. Voir la description de FUTEX_WAKE_BITSET pour plus de dĂ©tails.
Si timeout nâest pas NULL, la structure vers laquelle il pointe indique un dĂ©lai absolu de lâopĂ©ration dâattente. Si timeout est NULL, lâopĂ©ration peut se bloquer indĂ©finiment.
Lâargument uaddr2 est ignorĂ©.
FUTEX_WAKE_BITSET (depuis Linux 2.6.25)
Cette opĂ©ration est identique Ă FUTEX_WAKE , sauf que le paramĂštre val3 est utilisĂ© pour fournir un masque de bit de 32 bits au noyau. Ce masque, oĂč au moins un bit doit ĂȘtre positionnĂ©, est utilisĂ© pour choisir les Ă©lĂ©ments en attente qui doivent ĂȘtre rĂ©veillĂ©s. Le choix se fait par une comparaison bit Ă bit AND du masque de bit « wait » (Ă savoir la valeur de val3 ) et par un masque de bit stockĂ© dans la partie interne de lâĂ©lĂ©ment en attente (le masque de bit « wait » positionnĂ© en utilisant FUTEX_WAIT_BITSET ). Tous les Ă©lĂ©ments en attente pour lesquels le AND est positif sont rĂ©veillĂ©s ; les autres restent endormis.
Lâeffet de FUTEX_WAIT_BITSET et de FUTEX_WAKE_BITSET est de permettre un rĂ©veil sĂ©lectif parmi les Ă©lĂ©ments en attente bloquĂ©s sur le mĂȘme futex. Cependant, remarquez que selon le cas, lâutilisation de cette fonction de mĂ©lange de masques de bit sur un futex peut ĂȘtre moins efficace que le fait dâavoir plusieurs futex, car elle a besoin que le noyau vĂ©rifie tous les Ă©lĂ©ments en attente sur un futex, y compris ceux non concernĂ©s par le rĂ©veil (Ă savoir quâils nâont pas de bit pertinent positionnĂ© dans leur masque de bit « wait »).
La constante FUTEX_BITSET_MATCH_ANY , qui correspond Ă tous les positionnements 32 bits du masque, peut ĂȘtre utilisĂ© en tant que val3 de FUTEX_WAIT_BITSET et de FUTEX_WAKE_BITSET . En dehors des diffĂ©rences dans la gestion du paramĂštre timeout , lâopĂ©ration FUTEX_WAIT est Ă©quivalente Ă FUTEX_WAIT_BITSET oĂč val3 est indiquĂ© en tant que FUTEX_BITSET_MATCH_ANY ; câest-Ă -dire permettre le rĂ©veil par nâimporte quel Ă©lĂ©ment en attente). LâopĂ©ration FUTEX_WAKE est Ă©quivalente Ă FUTEX_WAKE_BITSET oĂč val3 est indiquĂ© en tant que FUTEX_BITSET_MATCH_ANY ; câest-Ă -dire, rĂ©veiller nâimporte quel Ă©lĂ©ment en attente.
Les arguments uaddr2 et timeout sont ignorés.
Futex et héritage de priorité
Linux prend en charge lâhĂ©ritage de prioritĂ© (priority inheritance, PI) des futex, afin de gĂ©rer des problĂšmes dâinversion des prioritĂ©s quâon peut rencontrer avec des verrous futex normaux. Lâinversion des prioritĂ©s est un problĂšme qui survient quand une tĂąche de haute prioritĂ© est bloquĂ©e en attente dâacquĂ©rir un verrou que possĂšde une tĂąche de basse prioritĂ© issue du processeur. Du coup, la tĂąche de prioritĂ© basse ne va pas relĂącher le verrou et celle de haute prioritĂ© reste bloquĂ©e.
LâhĂ©ritage de prioritĂ© est un mĂ©canisme pour gĂ©rer le problĂšme dâinversion des prioritĂ©s. Avec ce mĂ©canisme, quand une tĂąche Ă haute prioritĂ© est bloquĂ©e par un verrou possĂ©dĂ© par une tĂąche Ă basse prioritĂ©, la prioritĂ© de la seconde est temporairement amenĂ©e au mĂȘme niveau que celle Ă haute prioritĂ©, de sorte quâelle ne soit pas doublĂ©e par une tĂąche de niveau intermĂ©diaire et quâelle puisse ainsi avancer pour relĂącher le verrou. Pour fonctionner, lâhĂ©ritage de prioritĂ© doit ĂȘtre transitif, ce qui signifie que si une tĂąche Ă haute prioritĂ© bloque sur le verrou dâune tĂąche Ă prioritĂ© intermĂ©diaire (et ainsi de suite sur des chaĂźnes de la taille de votre choix), les deux tĂąches (ou plus gĂ©nĂ©ralement toutes les tĂąches de la chaĂźne de verrous) voient leur niveau de prioritĂ© amenĂ© Ă celui de la tĂąche Ă haute prioritĂ©.
Du point de vue de lâespace utilisateur, le futex a conscience dâun PI en acceptant une rĂ©glementation (dĂ©crite ci-dessous) entre lâespace utilisateur et le noyau sur la valeur du mot futex, couplĂ© Ă lâutilisation dâopĂ©rations futex PI dĂ©crites ci-dessous (contrairement aux autres opĂ©rations futex dĂ©crites ci-dessus, celles PI-futex sont conçues pour lâimplĂ©mentation de mĂ©canismes IPC trĂšs spĂ©cifiques).
Les opĂ©rations PI-futex dĂ©crites ci-dessous diffĂšrent des autres opĂ©rations dans le sens oĂč elles imposent des rĂšgles dans lâutilisation de la valeur du mot futex :
|
- |
Si le verrou nâest pas acquis, la valeur du mot futex doit ĂȘtre 0 . |
||
|
- |
Si le verrou est acquis, la valeur du mot futex doit ĂȘtre lâID du thread (TID ; voir gettid (2)) du thread propriĂ©taire. |
||
|
- |
Si le verrou a un propriĂ©taire et sâil y a des threads en concurrence pour le verrou, le bit FUTEX_WAITERS doit ĂȘtre positionnĂ© dans la valeur du mot futex ; autrement dit, cette valeur est : |
FUTEX_WAITERS | TID
(Remarquez que cela nâest pas possible pour un mot futex PI dâĂȘtre sans propriĂ©taire ni FUTEX_WAITERS dĂ©fini).
Avec cette rĂšgle, une application de lâespace utilisateur peut acquĂ©rir un verrou non acquis ou en relĂącher un en utilisant des instructions atomiques dans lâespace utilisateur (comme une opĂ©ration compare-and-swap telle que cmpxchg sur lâarchitecture x86). Lâacquisition dâun verrou consiste simplement dans lâutilisation de compare-and-swap pour positionner la valeur du mot futex de maniĂšre atomique sur le TID de lâappelant si sa valeur prĂ©cĂ©dente Ă©tait 0 . RelĂącher un verrou exige dâutiliser compare-and-swap pour positionner la valeur du mot futex sur 0 si la valeur prĂ©cĂ©dente Ă©tait le TID prĂ©vu.
Si un futex est dĂ©jĂ acquis (câest-Ă -dire quâil a une valeur positive), les Ă©lĂ©ments en attente doivent utiliser lâopĂ©ration FUTEX_LOCK_PI pour acquĂ©rir le verrou. Si dâautres threads attendent le verrou, le bit FUTEX_WAITERS est dĂ©fini dans la valeur du futex ; dans ce cas le dĂ©tenteur du verrou doit utiliser lâopĂ©ration FUTEX_UNLOCK_PI pour relĂącher le verrou.
Dans le cas oĂč les appelants sont bloquĂ©s dans le noyau (câest-Ă -dire quâils doivent effectuer un appel futex ()), ils traitent directement avec ce quâon appelle un RT-mutex, un mĂ©canisme de verrouillage du noyau qui implĂ©mente la sĂ©mantique de lâhĂ©ritage de prioritĂ© requis. AprĂšs que le RT-mutex est acquis, la valeur futex est mise Ă jour en fonction, avant que le thread appelant ne renvoie vers lâespace utilisateur.
Il est important de remarquer que le noyau mettra Ă jour la valeur du mot futex avant de renvoyer vers lâespace utilisateur (cela enlĂšve la possibilitĂ© pour la valeur dâun mot futex de se terminer dans un Ă©tat non valable, par exemple en ayant un propriĂ©taire mais en ayant la valeur 0 , ou en ayant des Ă©lĂ©ments en attente mais aucun bit FUTEX_WAITERS positionnĂ©).
Si un futex a un RT-mutex associĂ© dans le noyau (câest-Ă -dire quâil y a des Ă©lĂ©ments en attente bloquĂ©s) et si le propriĂ©taire du futex/RT-mutex meurt de maniĂšre inattendue, le noyau nettoie le RT-mutex et passe la main au prochain Ă©lĂ©ment en attente. Cela implique, en retour, que la valeur dans lâespace utilisateur soit mise Ă jour en fonction. Pour dire que câest nĂ©cessaire, le noyau positionne le bit FUTEX_OWNER_DIED dans le mot futex ainsi que dans lâID du thread du nouveau propriĂ©taire. Lâespace utilisateur peut dĂ©tecter cette situation par la prĂ©sence du bit FUTEX_OWNER_DIED et il est alors responsable pour nettoyer lâespace laissĂ© par le propriĂ©taire mort.
Les PI futex sont utilisĂ©s en indiquant une des valeurs listĂ©es ci-dessous dans futex_op . Remarquez que les opĂ©rations de PI futex doivent ĂȘtre utilisĂ©es par paires et sont soumises Ă des exigences supplĂ©mentaires :
|
- |
FUTEX_LOCK_PI , FUTEX_LOCK_PI2 et FUTEX_TRYLOCK_PI vont de pair avec FUTEX_UNLOCK_PI . FUTEX_UNLOCK_PI ne doit ĂȘtre appelĂ© que sur un futex appartenant au thread appelant, tel que dĂ©fini par les rĂšgles de la valeur, sans quoi on obtient lâerreur EPERM . |
||
|
- |
FUTEX_WAIT_REQUEUE_PI va de pair avec FUTEX_CMP_REQUEUE_PI . Elles doivent sâeffectuer depuis un futex non-PI vers un PI futex distinct (sans quoi on obtient lâerreur EINVAL ). De plus, val (le nombre dâĂ©lĂ©ments en attente Ă rĂ©veiller) doit ĂȘtre de 1 (sans quoi on obtient lâerreur EINVAL ). |
Les
opérations PI futex sont comme suit :
FUTEX_LOCK_PI
(depuis Linux 2.6.18)
Cette opĂ©ration est utilisĂ©e aprĂšs avoir essayĂ© sans succĂšs dâacquĂ©rir un verrou en utilisant une instruction atomique en mode utilisateur, car le mot futex a une valeur positive â en particulier parce quâil contenait le TID (spĂ©cifique Ă lâespace de noms PID) du verrou propriĂ©taire.
LâopĂ©ration vĂ©rifie la valeur du mot futex sur lâadresse uaddr . Si la valeur est de 0 , le noyau essaie de positionner de maniĂšre atomique la valeur du futex sur le TID de lâappelant. Si la valeur du mot futex est positive, le noyau positionne de maniĂšre atomique le bit FUTEX_WAITERS , qui signale au propriĂ©taire du futex quâil ne peut pas dĂ©verrouiller le futex dans lâespace utilisateur de maniĂšre atomique, en positionnant la valeur du futex Ă 0 . AprĂšs cela, le noyau :
|
(1) |
Essaie de trouver le thread associé au TID du propriétaire. |
||
|
(2) |
CrĂ©e ou rĂ©utilise lâĂ©tat du noyau sur la base du propriĂ©taire (sâil sâagit du premier Ă©lĂ©ment en attente, il nâexiste pas dâĂ©tat du noyau pour ce futex, donc il est créé en verrouillant le RT-mutex et le propriĂ©taire du futex devient propriĂ©taire du RT-mutex). Si des Ă©lĂ©ments en attente existent, lâĂ©tat existant est rĂ©utilisĂ©. |
||
|
(3) |
Rattache lâĂ©lĂ©ment en attente au futex (câest-Ă -dire que lâĂ©lĂ©ment est mis dans la file dâattente du RT-futex). |
Sâil existe plus dâun Ă©lĂ©ment en attente, la mise dans la file dâun Ă©lĂ©ment se fait par ordre de prioritĂ© descendant (pour des informations sur lâordre des prioritĂ©s, voir les points sur lâordonnancement SCHED_DEADLINE , SCHED_FIFO et SCHED_RR dans sched (7)). Le propriĂ©taire hĂ©rite soit de la bande passante de processeur de lâĂ©lĂ©ment en attente (si lâĂ©lĂ©ment est programmĂ© sous la rĂšgle SCHED_DEADLINE ou SCHED_FIFO ), soit de la prioritĂ© de lâĂ©lĂ©ment en attente (sâil est programmĂ© sous la rĂšgle SCHED_RR ou SCHED_FIFO ). Cet hĂ©ritage suit la chaĂźne de verrous dans les cas de verrous imbriquĂ©s et il effectue la dĂ©tection des verrous morts (deadlocks).
Le paramĂštre timeout fournit un dĂ©lai de tentative de verrouillage. Si timeout est positif, la structure vers laquelle il pointe indique un dĂ©lai absolu mesurĂ© en fonction de lâhorloge CLOCK_REALTIME . Si timeout est NULL, lâopĂ©ration se bloquera indĂ©finiment.
Les paramÚtres uaddr2 , val et val3 sont ignorés.
FUTEX_LOCK_PI2 (depuis Linux 5.14)
Cette opĂ©ration est la mĂȘme que FUTEX_LOCK_PI , sauf que lâhorloge par rapport Ă laquelle timeout est mesurĂ© peut ĂȘtre sĂ©lectionnĂ©e. Par dĂ©faut, le dĂ©lai (absolu) indiquĂ© dans timeout est mesurĂ© par rapport Ă lâhorloge CLOCK_MONOTONIC mais si lâattribut FUTEX_CLOCK_REALTIME est indiquĂ© dans futex_op , le dĂ©lai est mesurĂ© par rapport Ă lâhorloge CLOCK_REALTIME .
FUTEX_TRYLOCK_PI (depuis Linux 2.6.18)
LâopĂ©ration essaie dâacquĂ©rir le verrou sur uaddr . Elle est appelĂ©e quand lâacquisition atomique dans lâespace utilisateur nâa pas rĂ©ussi parce que le mot futex ne valait pas 0 .
Du fait que le noyau accĂšde Ă plus dâinformations dâĂ©tat que lâespace utilisateur, lâacquisition du verrou pourrait rĂ©ussir si elle est effectuĂ©e par le noyau dans les cas oĂč le mot futex (câest-Ă -dire les informations dâĂ©tat accessibles dans lâespace utilisateur) contient un Ă©tat stable ( FUTEX_WAITERS et/ou FUTEX_OWNER_DIED ). Cela peut arriver quand le propriĂ©taire du futex est mort. Lâespace utilisateur ne peut pas gĂ©rer cette condition de maniĂšre "race-free", mais le noyau peut corriger cela et acquĂ©rir le futex.
Les paramÚtres uaddr2 , val , timeout et val3 sont ignorés.
FUTEX_UNLOCK_PI (depuis Linux 2.6.18)
Cette opĂ©ration rĂ©veille lâĂ©lĂ©ment ayant la plus haute prioritĂ© et attendant un FUTEX_LOCK_PI ou un FUTEX_LOCK_PI2 Ă lâadresse indiquĂ©e par le paramĂštre uaddr .
Cela est appelĂ© quand la valeur dans lâespace utilisateur sur uaddr ne peut pas ĂȘtre passĂ©e Ă 0 de maniĂšre atomique depuis un TID (du propriĂ©taire).
Les paramÚtres uaddr2 , val , timeout et val3 sont ignorés.
FUTEX_CMP_REQUEUE_PI (depuis Linux 2.6.31)
Cette opĂ©ration est une variante PI-aware de FUTEX_CMP_REQUEUE . Elle remet en attente des Ă©lĂ©ments bloquĂ©s avec FUTEX_WAIT_REQUEUE_PI sur uaddr Ă partir dâun futex source non-PI ( uaddr ) vers un futex cible PI ( uaddr2 ).
Comme avec FUTEX_CMP_REQUEUE , cette opĂ©ration rĂ©veille un maximum de val Ă©lĂ©ments qui attendent le futex sur uaddr . Toutefois, pour FUTEX_CMP_REQUEUE_PI , val doit valoir 1 (puisque son but principal est dâĂ©viter lâeffet de troupeau (thundering herd). Les autres Ă©lĂ©ments sont supprimĂ©s de la file dâattente du futex source sur uaddr et ajoutĂ©s sur celle du futex cible sur uaddr2 .
Les paramĂštres val2 et val3 ont le mĂȘme objectif quâavec FUTEX_CMP_REQUEUE .
FUTEX_WAIT_REQUEUE_PI (depuis Linux 2.6.31)
Attendre un futex non-PI sur uaddr et se mettre potentiellement en attente (avec une opĂ©ration FUTEX_CMP_REQUEUE_PI dans une autre tĂąche), dâun futex PI sur uaddr2 . LâopĂ©ration dâattente sur uaddr est la mĂȘme que pour FUTEX_WAIT .
LâĂ©lĂ©ment peut ĂȘtre retirĂ© de la file dâattente sur uaddr sans ĂȘtre transfĂ©rĂ© sur uaddr2 Ă lâaide dâune opĂ©ration FUTEX_WAKE dans une autre tĂąche. Dans ce cas, lâopĂ©ration FUTEX_WAIT_REQUEUE_PI Ă©choue avec lâerreur EAGAIN .
Si timeout nâest pas NULL, la structure vers laquelle il pointe indique un dĂ©lai absolu de lâopĂ©ration dâattente. Si timeout est NULL, lâopĂ©ration peut se bloquer indĂ©finiment.
Lâargument val3 est ignorĂ©.
FUTEX_WAIT_REQUEUE_PI et FUTEX_CMP_REQUEUE_PI ont Ă©tĂ© ajoutĂ©s pour gĂ©rer un cas dâutilisation bien particulier : la prise en charge des variables conditionnelles de threads POSIX ayant connaissance de lâhĂ©ritage de prioritĂ©. LâidĂ©e est que ces opĂ©rations devraient toujours aller par paires, afin de garantir que lâespace utilisateur et le noyau restent toujours synchronisĂ©s. Ainsi, dans lâopĂ©ration FUTEX_WAIT_REQUEUE_PI , lâapplication dans lâespace utilisateur prĂ©-indique la cible de la remise en attente qui va se faire dans lâopĂ©ration FUTEX_CMP_REQUEUE_PI .
VALEUR RENVOYĂE
En cas dâerreur (en supposant que futex () a Ă©tĂ© appelĂ© Ă lâaide de syscall (2)), toutes les opĂ©rations renvoient -1 et positionnent errno pour indiquer lâerreur.
En cas de
succÚs, le code de retour dépend de
lâopĂ©ration, comme dĂ©crit dans la liste
suivante :
FUTEX_WAIT
Renvoie 0 si lâappelant a Ă©tĂ© rĂ©veillĂ©. Remarquez quâun rĂ©veil peut Ă©galement rĂ©sulter de lâutilisation de motifs dâutilisation classiques de futex dans du code non liĂ© qui a pu utiliser lâemplacement mĂ©moire du mot futex (par exemple des implĂ©mentations classiques basĂ©es sur futex de mutex Pthreads peuvent provoquer cela dans certaines conditions). Donc, les appelants devraient toujours, Ă titre conservatoire, supposer quâun code de retour 0 peut signifier un faux rĂ©veil, et donc utiliser la valeur du mot futex (Ă savoir le schĂ©ma de synchronisation de lâespace utilisateur) pour dĂ©cider de rester bloquĂ©s ou pas.
FUTEX_WAKE
Renvoie le nombre de processus en attente qui ont été réveillés.
FUTEX_FD
Renvoie le nouveau descripteur de fichier associé au futex.
FUTEX_REQUEUE
Renvoie le nombre de processus en attente qui ont été réveillés.
FUTEX_CMP_REQUEUE
Renvoie le nombre total dâĂ©lĂ©ments en attente rĂ©veillĂ©s ou remis dans la file du futex pour le mot futex sur uaddr2 . Si cette valeur est supĂ©rieure Ă val , la diffĂ©rence devient le nombre dâĂ©lĂ©ments en attente remis dans la file du futex pour le mot futex sur uaddr2 .
FUTEX_WAKE_OP
Renvoie le nombre total dâĂ©lĂ©ments en attente rĂ©veillĂ©s. Il sâagit de la somme des Ă©lĂ©ments rĂ©veillĂ©s sur les deux futex pour les mots futex sur uaddr et uaddr2 .
FUTEX_WAIT_BITSET
Renvoie 0 si lâappelant a Ă©tĂ© rĂ©veillĂ©. Voir FUTEX_WAIT sur la maniĂšre dâinterprĂ©ter cela correctement en pratique.
FUTEX_WAKE_BITSET
Renvoie le nombre de processus en attente qui ont été réveillés.
FUTEX_LOCK_PI
Renvoie 0 si le futex a appliqué le verrou avec succÚs.
FUTEX_LOCK_PI2
Renvoie 0 si le futex a appliqué le verrou avec succÚs.
FUTEX_TRYLOCK_PI
Renvoie 0 si le futex a appliqué le verrou avec succÚs.
FUTEX_UNLOCK_PI
Renvoie 0 si le futex a correctement enlevé le verrou.
FUTEX_CMP_REQUEUE_PI
Renvoie le nombre total dâĂ©lĂ©ments en attente rĂ©veillĂ©s ou remis dans la file du futex pour le mot futex sur uaddr2 . Si cette valeur est supĂ©rieure Ă val , la diffĂ©rence devient le nombre dâĂ©lĂ©ments en attente remis dans la file du futex pour le mot futex sur uaddr2 .
FUTEX_WAIT_REQUEUE_PI
Renvoie 0 si lâappelant a Ă©tĂ© mis dans la file dâattente avec succĂšs au futex pour le mot futex sur uaddr2 .
ERREURS
|
EACCES |
Pas dâaccĂšs en lecture Ă la mĂ©moire dâun mot futex. |
||
|
EAGAIN |
( FUTEX_WAIT , FUTEX_WAIT_BITSET , FUTEX_WAIT_REQUEUE_PI ) La valeur vers laquelle pointait uaddr nâĂ©tait pas Ă©gale Ă la valeur val attendue au moment de lâappel. |
Remarque : sur Linux, les noms symboliques EAGAIN et EWOULDBLOCK (les deux apparaissent dans diffĂ©rents endroits du code futex du noyau) ont la mĂȘme valeur.
|
EAGAIN |
( FUTEX_CMP_REQUEUE , FUTEX_CMP_REQUEUE_PI ) La valeur vers laquelle pointait uaddr nâĂ©tait pas Ă©gale Ă la valeur val3 attendue. |
||
|
EAGAIN |
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_CMP_REQUEUE_PI ) LâID du thread propriĂ©taire du futex sur uaddr (pour FUTEX_CMP_REQUEUE_PI : uaddr2 ) est sur le point de se terminer, mais il nâa pas encore gĂ©rĂ© le nettoyage de lâĂ©tat interne. RĂ©essayez. |
EDEADLK
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_CMP_REQUEUE_PI ) Le mot futex sur uaddr est dĂ©jĂ verrouillĂ© par lâappelant.
EDEADLK
( FUTEX_CMP_REQUEUE_PI ) Pendant quâil remettait en attente un Ă©lĂ©ment du PI futex pour le mot futex sur uaddr2 , le noyau a dĂ©tectĂ© un verrou mort (deadlock).
|
EFAULT |
Le paramĂštre dâun pointeur nĂ©cessaire (câest-Ă -dire uaddr , uaddr2 ou timeout ) ne pointait pas vers une adresse valable de lâespace utilisateur. |
||
|
EINTR |
Une opĂ©ration FUTEX_WAIT ou FUTEX_WAIT_BITSET a Ă©tĂ© interrompue par un signal (voir signal (7)). Dans Linux 2.6.22, cette erreur pouvait aussi ĂȘtre renvoyĂ©e pour un faux rĂ©veil ; depuis Linux 2.6.22, cela nâarrive plus. |
||
|
EINVAL |
LâopĂ©ration dans futex_op fait partie de celles qui utilisent un dĂ©lai, mais le paramĂštre timeout fourni nâĂ©tait pas valable ( tv_sec valait moins de 0 ou tv_nsec ne valait pas moins de 1 000 000 000). |
||
|
EINVAL |
LâopĂ©ration indiquĂ©e dans futex_op utilise uaddr et/ou uaddr2 mais lâun dâeux ne pointe pas vers un objet valable â câest-Ă -dire, lâadresse nâest pas alignĂ©e sur quatre octets. |
||
|
EINVAL |
( FUTEX_WAIT_BITSET , FUTEX_WAKE_BITSET ) Le masque de bit fourni dans val3 vaut zéro. |
||
|
EINVAL |
( FUTEX_CMP_REQUEUE_PI ) uaddr est Ă©gal Ă uaddr2 (câest-Ă -dire quâune remise en attente a Ă©tĂ© tentĂ©e sur le mĂȘme futex). |
||
|
EINVAL |
( FUTEX_FD ) Le numĂ©ro du signal fourni dans val nâest pas valable. |
||
|
EINVAL |
( FUTEX_WAKE , FUTEX_WAKE_OP , FUTEX_WAKE_BITSET , FUTEX_REQUEUE , FUTEX_CMP_REQUEUE ) Le noyau a dĂ©tectĂ© une incohĂ©rence entre lâĂ©tat de lâespace utilisateur sur uaddr et lâĂ©tat du noyau â câest-Ă -dire quâil a dĂ©tectĂ© un Ă©lĂ©ment qui attend dans FUTEX_LOCK_PI ou FUTEX_LOCK_PI2 sur uaddr . |
||
|
EINVAL |
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_UNLOCK_PI ) Le noyau a dĂ©tectĂ© une incohĂ©rence entre lâĂ©tat de lâespace utilisateur sur uaddr et lâĂ©tat du noyau. Cela indique soit une corruption dâĂ©tat, soit que le noyau a trouvĂ© un Ă©lĂ©ment en attente sur uaddr qui attend aussi Ă lâaide de FUTEX_WAIT ou de FUTEX_WAIT_BITSET . |
||
|
EINVAL |
( FUTEX_CMP_REQUEUE_PI ) Le noyau a dĂ©tectĂ© une incohĂ©rence entre lâĂ©tat de lâespace utilisateur sur uaddr et lâĂ©tat du noyau ; câest-Ă -dire quâil a dĂ©tectĂ© un Ă©lĂ©ment qui attend via FUTEX_WAIT ou FUTEX_WAIT_BITSET sur uaddr2 . |
||
|
EINVAL |
( FUTEX_CMP_REQUEUE_PI ) Le noyau a dĂ©tectĂ© une incohĂ©rence entre lâĂ©tat de lâespace utilisateur sur uaddr et lâĂ©tat du noyau ; câest-Ă -dire quâil a dĂ©tectĂ© un Ă©lĂ©ment qui attend Ă lâaide de FUTEX_WAIT ou de FUTEX_WAIT_BITESET sur uaddr . |
||
|
EINVAL |
( FUTEX_CMP_REQUEUE_PI ) Le noyau a dĂ©tectĂ© une incohĂ©rence entre lâĂ©tat de lâespace utilisateur sur uaddr et lâĂ©tat du noyau ; câest-Ă -dire quâil a dĂ©tectĂ© un Ă©lĂ©ment qui attend Ă lâaide de FUTEX_LOCK_PI ou de FUTEX_LOCK_PI2 (au lieu de FUTEX_WAIT_REQUEUE_PI ). |
||
|
EINVAL |
( FUTEX_CMP_REQUEUE_PI ) Tentative de remise dans la file dâun Ă©lĂ©ment en attente vers un futex diffĂ©rent de celui indiquĂ© avec lâappel FUTEX_WAIT_REQUEUE_PI correspondant pour cet Ă©lĂ©ment. |
||
|
EINVAL |
( FUTEX_CMP_REQUEUE_PI ) Le paramĂštre val ne vaut pas 1 . |
||
|
EINVAL |
Argument incorrect. |
||
|
ENFILE |
( FUTEX_FD ) La limite du nombre total de fichiers ouverts sur le systÚme a été atteinte. |
||
|
ENOMEM |
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_CMP_REQUEUE_PI ) Le noyau nâa pas pu allouer de la mĂ©moire pour conserver les informations dâĂ©tat. |
||
|
ENOSYS |
Opération non valable indiquée dans futex_op . |
||
|
ENOSYS |
Lâoption FUTEX_CLOCK_REALTIME Ă©tait indiquĂ©e dans futex_op , mais lâopĂ©ration qui lâaccompagne nâest ni FUTEX_WAIT , ni FUTEX_WAIT_BITSET , ni FUTEX_WAIT_REQUEUE_PI , ni FUTEX_LOCK_PI2 . |
||
|
ENOSYS |
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_UNLOCK_PI , FUTEX_CMP_REQUEUE_PI , FUTEX_WAIT_REQUEUE_PI ) Une vĂ©rification pendant lâexĂ©cution a dĂ©terminĂ© que lâopĂ©ration nâest pas disponible. Les opĂ©rations PI-futex ne sont pas implĂ©mentĂ©es sur toutes les architectures et ne sont pas prises en charge sur certaines variantes de processeur. |
||
|
EPERM |
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_CMP_REQUEUE_PI ) Lâappelant nâest pas autorisĂ© Ă se rattacher au futex sur uaddr (pour FUTEX_CMP_REQUEUE_PI : le futex sur uaddr2 ) (cela peut venir dâune corruption de lâĂ©tat dans lâespace utilisateur). |
||
|
EPERM |
( FUTEX_UNLOCK_PI ) Le verrou reprĂ©sentĂ© par le mot futex nâappartient pas Ă lâappelant. |
||
|
ESRCH |
( FUTEX_LOCK_PI , FUTEX_LOCK_PI2 , FUTEX_TRYLOCK_PI , FUTEX_CMP_REQUEUE_PI ) LâID du thread dans le mot futex sur uaddr nâexiste pas. |
||
|
ESRCH |
( FUTEX_CMP_REQUEUE_PI ) LâID du thread dans le mot futex sur uaddr2 nâexiste pas. |
ETIMEDOUT
LâopĂ©ration de futex_op a utilisĂ© un dĂ©lai indiquĂ© dans timeout et le dĂ©lai a expirĂ© avant la fin de lâopĂ©ration.
STANDARDS
Linux.
HISTORIQUE
Linux 2.6.0.
La prise en charge initiale des futex a été ajoutée dans Linux 2.5.7 mais avec une sémantique différente de celle décrite ci-dessus. Un appel systÚme à 4 paramÚtres avec la sémantique décrite dans cette page a été ajouté dans Linux 2.5.40. Dans Linux 2.5.70, un cinquiÚme paramÚtre a été ajouté. Un sixiÚme paramÚtre a été ajouté dans Linux 2.6.7.
EXEMPLES
Le programme ci-dessous montre lâutilisation des futex dans un programme oĂč un processus parent et un processus enfant utilisent une paire de futex situĂ©e dans un tableau anonyme partagĂ© pour synchroniser lâaccĂšs Ă une ressource partagĂ©e : le terminal. Les deux processus Ă©crivent chacun un message nloops (un paramĂštre en ligne de commande qui vaut 5 par dĂ©faut sâil est absent) sur le terminal et ils utilisent un protocole de synchronisation pour garantir quâils alternent dans lâĂ©criture des messages. Pendant lâexĂ©cution de ce programme, nous voyons un affichage comme suit :
$
./futex_demo
Parent (18534) 0
Child (18535) 0
Parent (18534) 1
Child (18535) 1
Parent (18534) 2
Child (18535) 2
Parent (18534) 3
Child (18535) 3
Parent (18534) 4
Child (18535) 4
Source du programme
/* futex_demo.c
Usage: futex_demo [nloops]
(Default: 5)
Montrer lâutilisation des futex dans un programme
oĂč le parent et
lâenfant utilisent une paire de futex situĂ©e
dans un tableau anonyme
partagĂ© pour synchroniser lâaccĂšs
à une ressource partagée : le
terminal. Les processus écrivent chacun des messages
'num-loops'
sur le terminal et ils utilisent un protocole de
synchronisation qui
garantit quâils alternent lâĂ©criture des
messages.
*/
#define _GNU_SOURCE
#include <err.h>
#include <errno.h>
#include <linux/futex.h>
#include <stdatomic.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
static uint32_t *futex1, *futex2, *iaddr;
static int
futex(uint32_t *uaddr, int futex_op, uint32_t val,
const struct timespec *timeout, uint32_t *uaddr2, uint32_t
val3)
{
return syscall(SYS_futex, uaddr, futex_op, val,
timeout, uaddr2, val3);
}
/* Acquérir le futex vers lequel pointe 'futexp' :
attendre que sa
valeur passe Ă 1 puis positionner la valeur sur 0. */
static void
fwait(uint32_t *futexp)
{
long s;
const uint32_t one = 1;
/* atomic_compare_exchange_strong(ptr, oldval, newval)
fait atomiquement comme :
if (*ptr == *oldval)
*ptr = newval;
Il renvoie true si le test a montré true et *ptr a
été mis à jour. */
while (1) {
/* Le futex est-il disponible ? */
if (atomic_compare_exchange_strong(futexp, &one, 0))
break; /* Oui */
/* Le futex nâest pas disponible ; attendre. */
s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0);
if (s == -1 && errno != EAGAIN)
err(EXIT_FAILURE, "futex-FUTEX_WAIT");
}
}
/* RelĂącher le futex vers lequel pointe
'futexp'Â : si le futex a
actuellement la valeur 0, positionner la valeur Ă 1
et réveiller tous les
futex en attente pour que si le pair est bloqué dans
fwait(), ça puisse
continuer. */
static void
fpost(uint32_t *futexp)
{
long s;
const uint32_t zero = 0;
/* atomic_compare_exchange_strong() a été
décrit
dans les commentaires ci-dessus. */
if (atomic_compare_exchange_strong(futexp, &zero, 1)) {
s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
if (s == -1)
err(EXIT_FAILURE, "futex-FUTEX_WAKE");
}
}
int
main(int argc, char *argv[])
{
pid_t childPid;
unsigned int nloops;
setbuf(stdout, NULL);
nloops = (argc > 1) ? atoi(argv[1]) : 5;
/* Créer un tableau anonyme partagé qui
gardera les futex.
Comme les futex vont ĂȘtre partagĂ©s entre les
processus, nous
utilisons donc les opérations futex
« shared » (donc pas celles
dont le suffixe est "_PRIVATE") */
iaddr = mmap(NULL, sizeof(*iaddr) * 2, PROT_READ |
PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (iaddr == MAP_FAILED)
err(EXIT_FAILURE, "mmap");
futex1 = &iaddr[0];
futex2 = &iaddr[1];
*futex1 = 0; /* State: unavailable */
*futex2 = 1; /* State: available */
/* Créer un processus enfant qui hérite du
tableau anonyme
partagé. */
childPid = fork();
if (childPid == -1)
err(EXIT_FAILURE, "fork");
if (childPid == 0) { /* Child */
for (unsigned int j = 0; j < nloops; j++) {
fwait(futex1);
printf("Child (%jd) %u\n", (intmax_t) getpid(),
j);
fpost(futex2);
}
exit(EXIT_SUCCESS);
}
/* Le parent se retrouve ici. */
for (unsigned int j = 0; j < nloops; j++) {
fwait(futex2);
printf("Parent (%jd) %u\n", (intmax_t) getpid(),
j);
fpost(futex1);
}
wait(NULL);
exit(EXIT_SUCCESS);
}
VOIR AUSSI
get_robust_list (2), restart_syscall (2), pthread_mutexattr_getprotocol (3), futex (7), sched (7)
Les fichiers suivants des sources du noyau :
|
- |
Documentation/pi-futex.txt |
|||
|
- |
Documentation/futex-requeue-pi.txt |
|||
|
- |
Documentation/locking/rt-mutex.txt |
|||
|
- |
Documentation/locking/rt-mutex-design.txt |
|||
|
- |
Documentation/robust-futex-ABI.txt |
Franke, H.,
Russell, R., and Kirwood, M., 2002.
Fuss, Futexes and
Furwocks: Fast Userlevel Locking in Linux
(Ă
partir des actions dâOttawa Linux Symposium 2002),
http://kernel.org/doc/ols/2002/ols2002-pages-479-495.pdf
Hart, D., 2009. A futex overview and update , http://lwn.net/Articles/360699/
Hart, D. et Guniguntala, D., 2009. Requeue-PI: Making Glibc Condvars PI-Aware (Ă partir des comptes rendus de lâatelier Real-Time Linux 2009), http://lwn.net/images/conf/rtlws11/papers/proc/p10.pdf
Drepper, U., 2011. Futexes Are Tricky , http://www.akkadia.org/drepper/futex.pdf
La
bibliothĂšque dâexemples de futex,
futex-*.tar.bz2 Ă
https://mirrors.kernel.org/pub/linux/kernel/people/rusty/
TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter Ă la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il nây a aucune RESPONSABILITĂ LĂGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org .