cpu.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-10-30 Bernard The first version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #ifdef RT_USING_SMP
  13. static struct rt_cpu rt_cpus[RT_CPUS_NR];
  14. rt_hw_spinlock_t _cpus_lock;
  15. /**
  16. * This fucntion will return current cpu.
  17. */
  18. struct rt_cpu *rt_cpu_self(void)
  19. {
  20. return &rt_cpus[rt_hw_cpu_id()];
  21. }
  22. struct rt_cpu *rt_cpu_index(int index)
  23. {
  24. return &rt_cpus[index];
  25. }
  26. /**
  27. * This function will lock all cpus's scheduler and disable local irq.
  28. */
  29. rt_base_t rt_cpus_lock(void)
  30. {
  31. rt_base_t level;
  32. struct rt_cpu* pcpu;
  33. level = rt_hw_local_irq_disable();
  34. pcpu = rt_cpu_self();
  35. if (pcpu->current_thread != RT_NULL)
  36. {
  37. if (pcpu->current_thread->cpus_lock_nest++ == 0)
  38. {
  39. pcpu->current_thread->scheduler_lock_nest++;
  40. rt_hw_spin_lock(&_cpus_lock);
  41. }
  42. }
  43. return level;
  44. }
  45. RTM_EXPORT(rt_cpus_lock);
  46. /**
  47. * This function will restore all cpus's scheduler and restore local irq.
  48. */
  49. void rt_cpus_unlock(rt_base_t level)
  50. {
  51. struct rt_cpu* pcpu = rt_cpu_self();
  52. if (pcpu->current_thread != RT_NULL)
  53. {
  54. if (--pcpu->current_thread->cpus_lock_nest == 0)
  55. {
  56. pcpu->current_thread->scheduler_lock_nest--;
  57. rt_hw_spin_unlock(&_cpus_lock);
  58. }
  59. }
  60. rt_hw_local_irq_enable(level);
  61. }
  62. RTM_EXPORT(rt_cpus_unlock);
  63. /**
  64. * This function is invoked by scheduler.
  65. * It will restore the lock state to whatever the thread's counter expects.
  66. * If target thread not locked the cpus then unlock the cpus lock.
  67. */
  68. void rt_cpus_lock_status_restore(struct rt_thread *thread)
  69. {
  70. struct rt_cpu* pcpu = rt_cpu_self();
  71. pcpu->current_thread = thread;
  72. if (!thread->cpus_lock_nest)
  73. {
  74. rt_hw_spin_unlock(&_cpus_lock);
  75. }
  76. }
  77. RTM_EXPORT(rt_cpus_lock_status_restore);
  78. #endif