@@ -144,9 +144,12 @@ internal static unsafe class Native
144144 /// </summary>
145145 [ DllImport ( "libc" , SetLastError = true ) ] internal static extern int eventfd ( uint initval , int flags ) ;
146146
147- [ DllImport ( "libc" , SetLastError = true ) ] internal static extern int sched_setaffinity ( int pid , nuint cpusetsize , ref ulong mask ) ;
148-
149-
147+ [ DllImport ( "libc" , SetLastError = true ) ] internal static extern int sched_setaffinity ( int pid , IntPtr cpusetsize , ref ulong mask ) ;
148+
149+ [ DllImport ( "libc" , SetLastError = true ) ] internal static extern int sched_setaffinity ( int pid , IntPtr cpusetsize , ref cpu_set_t mask ) ;
150+
151+ [ DllImport ( "libc" ) ] internal static extern int gettid ( ) ; // Linux thread id
152+
150153 // =========================
151154 // Struct definitions
152155 // =========================
@@ -264,4 +267,28 @@ internal struct Linger
264267 internal const int EPIPE = 32 ;
265268 internal const int ECONNABORTED = 103 ;
266269 internal const int ECONNRESET = 104 ;
270+
271+ public static void PinCurrentThreadToCpu ( int cpuIndex )
272+ {
273+ if ( cpuIndex < 0 || cpuIndex >= Environment . ProcessorCount )
274+ throw new ArgumentOutOfRangeException ( nameof ( cpuIndex ) ) ;
275+
276+ unsafe
277+ {
278+ var set = new cpu_set_t ( ) ;
279+ int word = cpuIndex / 64 ;
280+ int bit = cpuIndex % 64 ;
281+ set . Bits [ word ] = 1UL << bit ;
282+
283+ int tid = gettid ( ) ;
284+ int ret = sched_setaffinity ( tid , ( IntPtr ) sizeof ( cpu_set_t ) , ref set ) ;
285+ if ( ret != 0 )
286+ throw new InvalidOperationException ( $ "sched_setaffinity failed with errno { Marshal . GetLastPInvokeError ( ) } ") ;
287+ }
288+ }
267289}
290+
291+ internal unsafe struct cpu_set_t
292+ {
293+ public fixed ulong Bits [ 16 ] ; // 1024 bits (enough for up to 1024 CPUs)
294+ }
0 commit comments