Let the program run on a specific CPU in the kernel space of the implementation

Source: Internet
Author: User
If you need to run the program on a specific CPU, you can refer to the following code implementation In_interrupt
int my_func_on_cpu (int cpu)
{
int err;
Get_online_cpus ();
if (!cpu_online (CPU))
err =-einval;
Else
if (In_interrupt ())
Err = WORK_ON_CPU (CPU, __MY_FUNC_ON_CPU, NULL);
Else
Smp_call_function_single (CPU, __MY_FUNC_ON_CPU, &err,
true);
endif
Put_online_cpus ();
return err;
}
If you are sure that your code is in interrupt context, use Smp_call_function_single. If you run in the thread context, use WORK_ON_CPU, because WORK_ON_CPU
May sleep, so it cannot be used in the interrupt context.
If both environments are likely to run in the above way, you can use the In_interrupt () function to determine whether you are in the interrupt context.
Long work_on_cpu (int cpu, long (*FN) (void *), void *arg)
{
struct Work_for_cpu WFC = {. fn = fn,. arg = arg};


Init_work_onstack (&wfc.work, WORK_FOR_CPU_FN);
schedule_work_on (CPU, &wfc.work);
Flush_work (&wfc.work);
Destroy_work_on_stack (&wfc.work);
return wfc.ret;
}


WORK_ON_CPU first suggested a work_struct on the stack.
#define Init_work_onstack (_work, _func) \
__init_work ((_work), (_func), 1)
We do not define CONFIG_LOCKDEP. So we're going to take the else case.
#ifdef CONFIG_LOCKDEP
#define __init_work (_work, _func, _onstack) \
do {\
static struct Lock_class_key __key; \
\
__init_work ((_work), _onstack); \
(_work)->data = (atomic_long_t) work_data_init (); \
Lockdep_init_map (& (_work)->lockdep_map, #_work, &__key, 0); \
Init_list_head (& (_work)->entry); \
(_work)->func = (_func); \
} while (0)
#else
#define __init_work (_work, _func, _onstack) \
do {\
__init_work ((_work), _onstack); \
(_work)->data = (atomic_long_t) work_data_init (); \
Init_list_head (& (_work)->entry); \
(_work)->func = (_func); \
} while (0)
#endif


The callback function for this workqueue is
static void Work_for_cpu_fn (struct work_struct *work)
{
struct WORK_FOR_CPU *WFC = container_of (work, struct work_for_cpu, work);


Wfc->ret = WFC->FN (Wfc->arg);
}


That is, a function that invokes user registration directly.
Second call schedule_work_on (CPU, &wfc.work); To run Workqueue
Static inline bool schedule_work_on (int cpu, struct work_struct *work)
{
Return queue_work_on (CPU, SYSTEM_WQ, work);
}
The schedule_work_on is to run the work_struct that we created earlier on the stack into the workqueue_struct that the SYSTEM_WQ system has already defined.
Finally, call Flush_work (&wfc.work) to wait for wfc.work execution to complete.
Since our work_struct is built on stack, the WORK_ON_CPU function returns Work_struct is automatically destroyed.
So when you don't define config_debug_objects_work to DEBUG, Destroy_work_on_stack is an empty function.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.