SlideShare a Scribd company logo
Futex Scaling for Multicore Systems
ACM Applicative Conference – June 2016. New York, NY.
Davidlohr Bueso <dave@stgolabs.net>
SUSE Labs.
2
Agenda
1. Introduction
2. Implementing Futexes
● Overall architecture.
● Addressing performance bottlenecks.
3. Notes/Practises in Userspace.
3
Introduction
• Linux kernel (v2.5) functionality for userspace: “Fast
userspace mutual exclusion” through the futex(2)
interface:
‒ Method for a program to wait for a value at a given address to
change, and a method to wake up anyone waiting on a particular
address.
‒ A futex is in essence a userspace address.
4
Introduction
• Linux kernel (v2.5) functionality for userspace: “Fast
userspace mutual exclusion” through the futex(2)
interface:
‒ Method for a program to wait for a value at a given address to
change, and a method to wake up anyone waiting on a particular
address.
‒ A futex is in essence a userspace address.
• Futexes are very basic and lend themselves well for
building higher level locking abstractions such as POSIX
threads:
‒ pthread_mutex_*(), pthread_rwlock_*(),
pthread_barrier_*(), pthread_cond_wait(), etc.
5
Introduction
• In the uncontended cases, user locking implementations
never need to exit from userspace, and the kernel is
graciously unaware, nor cares. CAS is enough.
6
Introduction
• In the uncontended cases, user locking implementations
never need to exit from userspace, and the kernel is
graciously unaware, nor cares. CAS is enough.
• In the case of sysv sems this is not true as jumping to
kernel space is always required to handle the call.
• Lock fastpaths therefore have a significant advantage
using by futexes.
7
Introduction
int futex(int *uaddr, int futex_op,              
          int val, struct timespec *to,         
 int *uaddr2, int val3);
8
Introduction
int futex(int *uaddr, int futex_op,              
          int val, struct timespec *to,         
 int *uaddr2, int val3);
‒ The futex, 32-bit lock variable field
9
Introduction
int futex(int *uaddr, int futex_op,              
          int val, struct timespec *to,         
 int *uaddr2, int val3);
‒ What operation to do on the futex, ie:
 FUTEX_WAIT, FUTEX_WAKE
10
Introduction
int futex(int *uaddr, int futex_op,              
          int val, struct timespec *to,         
 int *uaddr2, int val3);
‒ What operation to do on the futex, ie:
 FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, etc.
11
Introduction
int futex(int *uaddr, int futex_op,              
          int val, struct timespec *to,         
 int *uaddr2, int val3);
• Special cases (operations):
‒ PI-futexes (PTHREAD_PRIO_INHERIT)
FUTEX_LOCK/UNLOCK_PI
FUTEX_CMP/WAIT_REQUEUE_PI, etc.
12
Introduction
int futex(int *uaddr, int futex_op,              
          int val, struct timespec *to,         
 int *uaddr2, int val3);
• Special cases (operations):
‒ PI-futexes (PTHREAD_PRIO_INHERIT)
FUTEX_LOCK/UNLOCK_PI
FUTEX_CMP/WAIT_REQUEUE_PI, etc.
‒ Robust futexes (lock owner crashes)
set_robust_list(2), get_robust_list(2)
13
Introduction
void lock(uint32_t *futex)
{
        uint32_t old = *futex;
        if (old == UNLOCKED) /* fastpath */
                old = cmpxchg(futex, UNLOCKED, LOCKED);
        while (old != UNLOCKED) {
                if (old == LOCKED)
                        old = cmpxchg(futex, LOCKED, WAITER);
                if (old != UNLOCKED) {
                        futex(futex, FUTEX_WAIT, WAITERS,…);
                        old = *futex;
                }
                if (old == UNLOCKED)
                        old = cmpxchg(futex, UNLOCKED, WAITERS);
        }
 }
14
Introduction
void unlock(uint32_t *futex)
{
        uint32_t old = *futex;
        if (old == LOCKED)
                old = cmpxchg(futex, LOCKED, UNLOCK);
        if (old == WAITER) {
                old = cmpxchg(futex, WAITER, UNLOCKED);
                nwakes = futex(futex, FUTEX_WAKE, 1, ...);
    /* check nwakes == 1 */
        }
}
Implementing Futexes
16
Kernel Implementation
• The uaddr is used by the kernel to create a unique futex
key, each key hashes to a hash bucket.
• The task’s stack holds the futex_q chain when waiting
(servicing FUTEX_WAIT operations).
17
Kernel Implementation
• Wait queues are at the heart of futexes.
‒ Priority queues (high prio tasks first, otherwise FIFO).
‒ Governed by a chained global hash table.
18
Kernel Implementation
• Each bucket is serialized by a spinlock – all operations
require holding the lock beforehand.
• One or more futexes can share the queue (collisions).
19
Bottlenecks
• There are some immediately apparent issues with the
current futex architecture.
‒ Global hash table (really bad for NUMA).
‒ Hash table collisions.
‒ hb­>lock contention/hold times.
20
Bottlenecks
• There are some immediately apparent issues with the
current futex architecture.
‒ Global hash table (really bad for NUMA).
‒ Hash table collisions.
‒ hb­>lock contention/hold times.
• All of these can have disastrous effects on both
performance, as systems increase in hardware
capabilities, as well as determinism for real-time.
21
Bottlenecks
• There are some immediately apparent issues with the
current futex architecture.
‒ Global hash table (really bad for NUMA).
‒ Hash table collisions.
‒ hb­>lock contention/hold times.
• All of these can have disastrous effects on both
performance, as systems increase in hardware
capabilities, as well as determinism for real-time.
• Numerous efforts have been taken to mitigate some of
these scalability problems.
22
Keys and Hashing
• Uses Jenkins hash function (lookup3).
‒ Fast and distributes hash values rather uniformly
(on real workloads).
• Keys for private vs shared futexes.
‒ Private simply use the current address space and the futex
uaddr.
‒ Shared mappings require page pinning (gup), locks, RCU, ref
counting, etc. Even worse if inode-backed.
• For shared mappings, lockless get_futex_key()
‒ Avoids taking the page_lock (sleepable).
‒ Good for performance and RT.
23
Keys and Hashing
52-core, 2 socket x86-64 (Haswell)
nfutexes = nthreads * 1024
24
Keys and Hashing
• Avoiding collisions and therefore improving the
parallelisation of different futexes is a major plus.
‒ Ie: two or more user locks can be operated on concurrently
without being serialized by the same hb­>lock.
‒ The perfect hash size will of course have one to one hb:futex
ratio.
25
Keys and Hashing
• Futexes started out at 256 entry hash table, which
caused havoc on multicore systems. Since then we
scale by number of CPUs (and avoid false sharing).
‒ Improved raw hashing throughput by 80% to 800% in
increasing futex counts.
26
Per-process Hash Table
• Recent patchset proposed upstream to address the
NUMA issues of the global table for private futexes.
• Dynamically sized: if a potential collision is detected the
size of the hash table is doubled.
• Hash table being on the same NUMA node as the task
operating on the futex.
• Addresses collisions by dedicating more hash table space
per process.
27
Per-thread Hash Table
28
Hash Bucket Lock Contention
• For a successful futex call to occur, intuitively, among
others, the following work must occur while holding
the the hb­>lock
‒ Priority list handling.
‒ Block/wakeup(s).
• It is not hard to find pathological contention on some
hb­>lock, when multiple operations are being done
on the same futex/lock.
29
Lockless Wakeups
• Internally acknowledge that one or more tasks are to
be awoken, then call wake_up_process() after
releasing the bucket spinlock.
30
Lockless Wakeups
• Internally acknowledge that one or more tasks are to
be awoken, then call wake_up_process() after
releasing the bucket spinlock.
• Lockless wake-queues respect the order given by the
caller, hence wakeup fairness does not change
whatsoever.
31
Lockless Wakeups
Works particularly well for batch wakeups of tasks
blocked on a particular futex.
‒ Ie waking all reader-waiters that where blocked on some lock
held for write. (Where N is a large number):
      futex(uaddr, FUTEX_WAKE, N, ...);
32
Lockless Wakeups
16
32
48
64
80
96
0 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08
parallel-wakeups
no-batch
batched
time (ms)
threads
26-core (HT), 2 socket x86-64 (Haswell)
33
Queued/MCS Spinlocks (x86)
• Bottlenecks in userspace can easily lead to severe
contention on the hb­>lock, and therefore exposed
to the semantics of spinlocks.
34
Queued/MCS Spinlocks (x86)
• Bottlenecks in userspace can easily lead to severe
contention on the hb­>lock, and therefore exposed
to the semantics of spinlocks.
58.32%  826174  xxx  [kernel.kallsyms] [k] _raw_spin_lock
            ­­­ _raw_spin_lock
             |
             |­­53.74%­­ futex_wake
             |          do_futex
             |          sys_futex
             |          system_call_fastpath
             |­­45.90%­­ futex_wait_setup
             |          futex_wait
             |          do_futex
             |          sys_futex
             |          system_call_fastpath            
35
Queued/MCS Spinlocks (x86)
• Replaced the regular ticket spinlock implementation.
• Each lock waiter will be queued and spins on its own
cacheline (per-cpu variable) rather than the lock itself.
‒ This occurs until the waiter becomes the head of the queue
(next in line to take the lock).
‒ Eliminates much of the cacheline bouncing (inter-socket traffic)
caused by contended ticket locks.
36
Queued/MCS Spinlocks (x86)
• Replaced the regular ticket spinlock implementation.
• Each lock waiter will be queued and spins on its own
cacheline (per-cpu variable) rather than the lock itself.
‒ This occurs until the waiter becomes the head of the queue
(next in line to take the lock).
‒ Eliminates much of the cacheline bouncing (inter-socket traffic)
caused by contended ticket locks.
• This really matters on systems with > 4-sockets, but
can bring 8 or 16-socket machines to its knees.
‒ Experiments show improvements in throughput of up to 2.4x
on 80 core machines.
‒ Reports of lockups for futexes on 240-core systems.
37
Queued/MCS Spinlocks (x86)
• qspinlocks outperform ticket locks in the uncontended
case. Ie avg single threaded lock+unlock:
• Therefore smaller systems under non-pathological
(normal case) workloads can also benefit.
Time (ns)
Ticket lock (unlock: CAS) 17.63
Queued lock (unlock: store) 9.54
(2.6Ghz x86-64)
38
PI-Futexes
• Futexes make use of rt-mutexes to support priority-
inheritance (PTHREAD_PRIO_INHERIT) semantics.
‒ pi_state is attached to the waiter’s futex_q
‒ The pi_state­>pi_mutex top-waiter (highest priority
waiter) has been optimized for both lockless wakeups and
avoid blocking if current lock owner is running.
39
PI-Futexes
1 4 8 16 24 48 64
0
2000000
4000000
6000000
8000000
10000000
12000000
14000000
pistress benchmark
top-waiter
regular
groups of 3-threads
totalinversions
32-core, 2 socket x86-64
Practices in Userspace
41
General Notes
• The performance optimizations at the Kernel side are only
one part of the picture. Using futexes is just as important.
• As with any system call, there really is no single recipe to
make good use of futexes in userspace. The kernel simply
obliges.
• Locking algorithms can play a huge factor in performance
on large-scale machines.
‒ Contention on a 240-core system is much more severe than
on a 40-core machine.
42
General Notes
• Locks in both the kernel and in userspace can be exposed
to the same architectural difficulties: cacheline contention
and NUMA-awareness.
• Many applications today are developed/tuned for certain
amount of CPUs.
‒ Scaling based only on the number of CPUs is likely to introduce
significant lock and cacheline contention.
• Unsurprisingly similar optimizations and tools to obtain
data for analysis (perf, tracing, etc) can be taken from this
presentation and applied to your locks.
43
Best Practises
• Data partitioning.
‒ Cacheline contention within a single NUMA node can be
significantly less severe than among cores from different NUMA
nodes.
• Lock granularity.
• Data layout
‒ structure organization, avoiding false sharing.
‒ Cacheline bouncing can occur when there are multiple hb­>lock
residing on the same cacheline and different futexes hash to
adjacent buckets.
• Avoid futex(2) calls unless necessary
‒ Ie: make sure there are waiters to wakeup.
44
References
• man 2 futex
• Hart, Darren. “A futex overview and update”. lwn.net. Nov 2009.
• Drepper, Ulrich. “Futexes are Tricky”. Nov 2011.
• Hart, D. “Requeue-PI: Making Glibc Condvars PI-Aware”. Proc. RT
Linux Summit 2011.
• Bueso, D. Norton, S. “An Overview of Kernel Lock Improvements”.
Linux Con. 2014. Chicago, IL.
Thank you.
46

More Related Content

What's hot (20)

PDF
Etsy Activity Feeds Architecture
Dan McKinley
 
PDF
Practical Problem Solving with Apache Hadoop & Pig
Milind Bhandarkar
 
PDF
Introduction to GPU Programming
Chakkrit (Kla) Tantithamthavorn
 
PDF
Solving PostgreSQL wicked problems
Alexander Korotkov
 
PDF
Linux Performance Tools
Brendan Gregg
 
PDF
AWS Kinesis Streams
Fernando Rodriguez
 
PPTX
Jvm tuning for low latency application & Cassandra
Quentin Ambard
 
PDF
GMSL in Linux
Kieran Bingham
 
PPTX
Lessons Learned From Running 1800 Clusters (Brooke Jensen, Instaclustr) | Cas...
DataStax
 
PPTX
Introduction to Apache Kudu
Jeff Holoman
 
PPTX
Apache Spark
SugumarSarDurai
 
PDF
eBPF Trace from Kernel to Userspace
SUSE Labs Taipei
 
PDF
Apache Spark at Airbnb
Databricks
 
PPTX
Grafana Mimir and VictoriaMetrics_ Performance Tests.pptx
RomanKhavronenko
 
PDF
Wido den Hollander - 10 ways to break your Ceph cluster
ShapeBlue
 
PPTX
A simple introduction to redis
Zhichao Liang
 
PDF
Hadoop Overview & Architecture
EMC
 
PDF
syzkaller: the next gen kernel fuzzer
Dmitry Vyukov
 
PDF
CanSecWest 2017 - Port(al) to the iOS Core
Stefan Esser
 
PPTX
Redis introduction
Federico Daniel Colombo Gennarelli
 
Etsy Activity Feeds Architecture
Dan McKinley
 
Practical Problem Solving with Apache Hadoop & Pig
Milind Bhandarkar
 
Introduction to GPU Programming
Chakkrit (Kla) Tantithamthavorn
 
Solving PostgreSQL wicked problems
Alexander Korotkov
 
Linux Performance Tools
Brendan Gregg
 
AWS Kinesis Streams
Fernando Rodriguez
 
Jvm tuning for low latency application & Cassandra
Quentin Ambard
 
GMSL in Linux
Kieran Bingham
 
Lessons Learned From Running 1800 Clusters (Brooke Jensen, Instaclustr) | Cas...
DataStax
 
Introduction to Apache Kudu
Jeff Holoman
 
Apache Spark
SugumarSarDurai
 
eBPF Trace from Kernel to Userspace
SUSE Labs Taipei
 
Apache Spark at Airbnb
Databricks
 
Grafana Mimir and VictoriaMetrics_ Performance Tests.pptx
RomanKhavronenko
 
Wido den Hollander - 10 ways to break your Ceph cluster
ShapeBlue
 
A simple introduction to redis
Zhichao Liang
 
Hadoop Overview & Architecture
EMC
 
syzkaller: the next gen kernel fuzzer
Dmitry Vyukov
 
CanSecWest 2017 - Port(al) to the iOS Core
Stefan Esser
 

Viewers also liked (20)

PDF
An Overview of [Linux] Kernel Lock Improvements -- Linuxcon NA 2014
Davidlohr Bueso
 
PDF
Memory Barriers in the Linux Kernel
Davidlohr Bueso
 
DOCX
Best topics for seminar
shilpi nagpal
 
PPTX
Doma faq
Rich Docekal
 
PDF
Futex 2017 programme gb
FUTEX CONVENTION
 
PDF
Linux kernel development chapter 10
huangachou
 
PPTX
ERP
Saroosh Zahid
 
PDF
Final Year M.Tech/B.Tech IEEE Projects-Dip,dsp & communication [matlab & ti p...
Chinnasamy C
 
PDF
FUTEX 2015 Programme gb
FUTEX CONVENTION
 
PPT
Introduction to YII framework
Naincy Gupta
 
PPTX
Enabling ARM® Server Technology for the Datacenter
AMD
 
PDF
6 Dean Google
Frank Cai
 
PPT
Yii php framework_honey
Honeyson Joseph
 
PDF
Red Hat Virtualization Where Performance Takes Off!
andreas kuncoro
 
PPTX
M.Tech project on Haar wavelet based approach for image compression
Veerendra B R Revanna
 
PPTX
A site in 15 minutes with yii
Andy Kelk
 
PPSX
Yii framework
Mohammed Saqib
 
PPTX
Sql server engine cpu cache as the new ram
Chris Adkin
 
PPTX
WebSocket MicroService vs. REST Microservice
Rick Hightower
 
PPT
Nram presentation 3
Prince Jairaj
 
An Overview of [Linux] Kernel Lock Improvements -- Linuxcon NA 2014
Davidlohr Bueso
 
Memory Barriers in the Linux Kernel
Davidlohr Bueso
 
Best topics for seminar
shilpi nagpal
 
Doma faq
Rich Docekal
 
Futex 2017 programme gb
FUTEX CONVENTION
 
Linux kernel development chapter 10
huangachou
 
Final Year M.Tech/B.Tech IEEE Projects-Dip,dsp & communication [matlab & ti p...
Chinnasamy C
 
FUTEX 2015 Programme gb
FUTEX CONVENTION
 
Introduction to YII framework
Naincy Gupta
 
Enabling ARM® Server Technology for the Datacenter
AMD
 
6 Dean Google
Frank Cai
 
Yii php framework_honey
Honeyson Joseph
 
Red Hat Virtualization Where Performance Takes Off!
andreas kuncoro
 
M.Tech project on Haar wavelet based approach for image compression
Veerendra B R Revanna
 
A site in 15 minutes with yii
Andy Kelk
 
Yii framework
Mohammed Saqib
 
Sql server engine cpu cache as the new ram
Chris Adkin
 
WebSocket MicroService vs. REST Microservice
Rick Hightower
 
Nram presentation 3
Prince Jairaj
 
Ad

Similar to Futex Scaling for Multi-core Systems (20)

PDF
Mutexes 2
Narendranath Reddy T
 
PDF
Reshaping Core Genomics Software Tools for the Manycore Era
Intel® Software
 
PPT
[CCC-28c3] Post Memory Corruption Memory Analysis
Moabi.com
 
PDF
Namespaces and cgroups - the basis of Linux containers
Kernel TLV
 
PDF
Vx works RTOS
Sai Malleswar
 
PDF
A NUMA interface for futex2 - Andre Almeida
Igalia
 
PDF
CNIT 127 14: Protection Mechanisms
Sam Bowne
 
PPTX
Real-Time Big Data with Storm, Kafka and GigaSpaces
Oleksii Diagiliev
 
PDF
Distributed Postgres
Stas Kelvich
 
PDF
zookeeer+raft-2.pdf
Chester Chen
 
PDF
StormCrawler at Bristech
Julien Nioche
 
PPTX
Memory model
Yi-Hsiu Hsu
 
PDF
xCORE architecture flyer
XMOS
 
PPT
Java util concurrent
Roger Xia
 
ODP
Fedora Virtualization Day: Linux Containers & CRIU
Andrey Vagin
 
PPTX
Real Time Operating System
Sharad Pandey
 
PDF
Zookeeper vs Raft: Stateful distributed coordination with HA and Fault Tolerance
Alluxio, Inc.
 
PDF
CNIT 127 14: Protection Mechanisms
Sam Bowne
 
PPT
timers 2.ppt
ycelgemici1
 
PDF
[Ruxcon 2011] Post Memory Corruption Memory Analysis
Moabi.com
 
Reshaping Core Genomics Software Tools for the Manycore Era
Intel® Software
 
[CCC-28c3] Post Memory Corruption Memory Analysis
Moabi.com
 
Namespaces and cgroups - the basis of Linux containers
Kernel TLV
 
Vx works RTOS
Sai Malleswar
 
A NUMA interface for futex2 - Andre Almeida
Igalia
 
CNIT 127 14: Protection Mechanisms
Sam Bowne
 
Real-Time Big Data with Storm, Kafka and GigaSpaces
Oleksii Diagiliev
 
Distributed Postgres
Stas Kelvich
 
zookeeer+raft-2.pdf
Chester Chen
 
StormCrawler at Bristech
Julien Nioche
 
Memory model
Yi-Hsiu Hsu
 
xCORE architecture flyer
XMOS
 
Java util concurrent
Roger Xia
 
Fedora Virtualization Day: Linux Containers & CRIU
Andrey Vagin
 
Real Time Operating System
Sharad Pandey
 
Zookeeper vs Raft: Stateful distributed coordination with HA and Fault Tolerance
Alluxio, Inc.
 
CNIT 127 14: Protection Mechanisms
Sam Bowne
 
timers 2.ppt
ycelgemici1
 
[Ruxcon 2011] Post Memory Corruption Memory Analysis
Moabi.com
 
Ad

Recently uploaded (20)

PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PPTX
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PDF
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PDF
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PPTX
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
iTop VPN With Crack Lifetime Activation Key-CODE
utfefguu
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
IDM Crack with Internet Download Manager 6.42 Build 43 with Patch Latest 2025
bashirkhan333g
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 

Futex Scaling for Multi-core Systems