smp_call.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024/9/12 zhujiale the first version
  9. * 2024/10/24 Shell added non-blocking IPI calling method
  10. */
  11. #ifndef __SMP_IPI_H__
  12. #define __SMP_IPI_H__
  13. #include <rtthread.h>
  14. /* callback of smp call */
  15. typedef void (*rt_smp_call_cb_t)(void *data);
  16. typedef rt_bool_t (*rt_smp_cond_t)(int cpu, void *info);
  17. #define SMP_CALL_EVENT_GLOB_ASYNC 0x1
  18. #define SMP_CALL_EVENT_GLOB_SYNC 0x2
  19. #define SMP_CALL_EVENT_REQUEST 0x4
  20. #define SMP_CALL_WAIT_ALL (1ul << 0)
  21. #define SMP_CALL_NO_LOCAL (1ul << 1)
  22. #define SMP_CALL_SIGNAL (1ul << 2)
  23. #define RT_ALL_CPU ((1 << RT_CPUS_NR) - 1)
  24. struct rt_smp_event
  25. {
  26. int event_id;
  27. void *data;
  28. rt_smp_call_cb_t func;
  29. union
  30. {
  31. rt_atomic_t *calling_cpu_mask;
  32. rt_atomic_t usage_tracer;
  33. } typed;
  34. };
  35. struct rt_smp_call_req
  36. {
  37. /* handle the busy status synchronization */
  38. rt_hw_spinlock_t freed_lock;
  39. struct rt_smp_event event;
  40. rt_ll_slist_t slist_node;
  41. };
  42. void rt_smp_call_ipi_handler(int vector, void *param);
  43. void rt_smp_call_each_cpu(rt_smp_call_cb_t func, void *data, rt_uint8_t flags);
  44. void rt_smp_call_each_cpu_cond(rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond_func);
  45. void rt_smp_call_cpu_mask(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flags);
  46. void rt_smp_call_cpu_mask_cond(rt_ubase_t cpu_mask, rt_smp_call_cb_t func, void *data, rt_uint8_t flag, rt_smp_cond_t cond_func);
  47. void rt_smp_call_init(void);
  48. rt_err_t rt_smp_call_request(int callcpu, rt_uint8_t flags, struct rt_smp_call_req *call_req);
  49. void rt_smp_call_req_init(struct rt_smp_call_req *call_req,
  50. rt_smp_call_cb_t func, void *data);
  51. void rt_smp_request_wait_freed(struct rt_smp_call_req *req);
  52. #define rt_smp_for_each_cpu(_iter) for (_iter = 0; (_iter) < RT_CPUS_NR; (_iter)++)
  53. rt_inline size_t rt_smp_get_next_remote(size_t iter, size_t cpuid)
  54. {
  55. iter++;
  56. return iter == cpuid ? iter + 1 : iter;
  57. }
  58. #define rt_smp_for_each_remote_cpu(_iter, _cpuid) for (_iter = rt_smp_get_next_remote(-1, _cpuid); (_iter) < RT_CPUS_NR; _iter=rt_smp_get_next_remote(_iter, _cpuid))
  59. #endif