线程安全问题
ZMer2019 opened this issue · comments
在inline hook里面,比如对OSKext::start()的hook,破坏了多条指令,如果某个线程已经执行到原来前12个字节中的某条指令,如何处理多核的线程安全问题?
我在注释里提了一句:
// TODO: Use the KeSetAffinityThread + KeGetCurrentProcessorNumber +
// KeSetTargetProcessorDpc + KeInsertQueueDpc or similar method
单就这个点来说,OSKext::start() 执行路径里有持 mutex 锁操作,所以相对还好。但如果换个别的并发高频 syscall 则必须要废掉其它核了。
我在注释里提了一句:
// TODO: Use the KeSetAffinityThread + KeGetCurrentProcessorNumber +
// KeSetTargetProcessorDpc + KeInsertQueueDpc or similar method
单就这个点来说,OSKext::start() 执行路径里有持 mutex 锁操作,所以相对还好。但如果换个别的并发高频 syscall 则必须要废掉其它核了。
DPC那个架构属于Windows自有的,在macOS上,有什么好的建议来废掉其他内核么?谢谢
从 10.5 Leopard 开始 macOS 引入了 Thread Affinity 概念,这里有个老文档提到了步骤:
https://developer.apple.com/library/archive/releasenotes/Performance/RN-AffinityAPI/#//apple_ref/doc/uid/TP40006635-CH1-DontLinkElementID_2
An application that wants to place a thread on every available processor would do the following:
- Obtain the number of processors on the system using sysctl(3) (see below).
- Create that number of threads.
- Set each thread with a distinct affinity tag.
- Start all threads.
总的来说就是创建 n 个线程,n 是 CPU 核的数量,然后把线程通过 thread_policy_set 函数由 affinity_tag 绑到对应的核上去。然后一个线程关中断做事,其它线程关中断/自旋就行了。参数 flavor 输入是 4 (THREAD_AFFINITY_POLICY)。com.apple.kpi.mach 导出了 task_policy_set,但没有导出 task_policy_get。
从 10.5 Leopard 开始 macOS 引入了 Thread Affinity 概念,这里有个老文档提到了步骤:
https://developer.apple.com/library/archive/releasenotes/Performance/RN-AffinityAPI/#//apple_ref/doc/uid/TP40006635-CH1-DontLinkElementID_2An application that wants to place a thread on every available processor would do the following:
- Obtain the number of processors on the system using sysctl(3) (see below).
- Create that number of threads.
- Set each thread with a distinct affinity tag.
- Start all threads.
总的来说就是创建 n 个线程,n 是 CPU 核的数量,然后把线程通过 thread_policy_set 函数由 affinity_tag 绑到对应的核上去。然后一个线程关中断做事,其它线程关中断/自旋就行了。参数 flavor 输入是 4 (THREAD_AFFINITY_POLICY)。com.apple.kpi.mach 导出了 task_policy_set,但没有导出 task_policy_get。
好的,非常感谢!
不客气!