1
0
Fork 0
forked from nuttx/nuttx-update

esp_rtc: use small lock in arch/risc-v/src/common/espressif/esp_rtc.c

reason:
We would like to replace the big lock with a small lock.

Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-12-18 19:41:55 +08:00 committed by Xiang Xiao
parent 48c439190d
commit 59a849a7cc
3 changed files with 48 additions and 36 deletions

View file

@ -369,7 +369,7 @@ void IRAM_ATTR esp_hr_timer_start(struct esp_hr_timer_s *timer,
if (timer->state != HR_TIMER_IDLE) if (timer->state != HR_TIMER_IDLE)
{ {
esp_hr_timer_stop(timer); esp_hr_timer_stop_nolock(timer);
} }
/* Calculate the timer's alarm value */ /* Calculate the timer's alarm value */
@ -481,12 +481,10 @@ void esp_hr_timer_start_periodic(struct esp_hr_timer_s *timer,
* *
****************************************************************************/ ****************************************************************************/
void IRAM_ATTR esp_hr_timer_stop(struct esp_hr_timer_s *timer) void IRAM_ATTR esp_hr_timer_stop_nolock(struct esp_hr_timer_s *timer)
{ {
struct esp_hr_timer_context_s *priv = &g_hr_timer_context; struct esp_hr_timer_context_s *priv = &g_hr_timer_context;
irqstate_t flags = spin_lock_irqsave(&priv->lock);
/* "start" function can set the timer's repeat flag, and "stop" function /* "start" function can set the timer's repeat flag, and "stop" function
* should remove this flag. * should remove this flag.
*/ */
@ -546,14 +544,16 @@ void IRAM_ATTR esp_hr_timer_stop(struct esp_hr_timer_s *timer)
list_delete(&timer->list); list_delete(&timer->list);
timer->state = HR_TIMER_IDLE; timer->state = HR_TIMER_IDLE;
spin_unlock_irqrestore(&priv->lock, flags);
timer->callback(timer->arg); timer->callback(timer->arg);
flags = spin_lock_irqsave(&priv->lock);
} }
}
void IRAM_ATTR esp_hr_timer_stop(struct esp_hr_timer_s *timer)
{
struct esp_hr_timer_context_s *priv = &g_hr_timer_context;
irqstate_t flags = spin_lock_irqsave(&priv->lock);
esp_hr_timer_stop_nolock(timer);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
@ -578,11 +578,11 @@ void esp_hr_timer_delete(struct esp_hr_timer_s *timer)
struct esp_hr_timer_context_s *priv = &g_hr_timer_context; struct esp_hr_timer_context_s *priv = &g_hr_timer_context;
flags = enter_critical_section(); flags = spin_lock_irqsave(&priv->lock);
if (timer->state == HR_TIMER_READY) if (timer->state == HR_TIMER_READY)
{ {
esp_hr_timer_stop(timer); esp_hr_timer_stop_nolock(timer);
} }
else if (timer->state == HR_TIMER_TIMEOUT) else if (timer->state == HR_TIMER_TIMEOUT)
{ {
@ -590,11 +590,13 @@ void esp_hr_timer_delete(struct esp_hr_timer_s *timer)
} }
else if (timer->state == HR_TIMER_DELETE) else if (timer->state == HR_TIMER_DELETE)
{ {
goto exit; spin_unlock_irqrestore(&priv->lock, flags);
return;
} }
list_add_after(&priv->toutlist, &timer->list); list_add_after(&priv->toutlist, &timer->list);
timer->state = HR_TIMER_DELETE; timer->state = HR_TIMER_DELETE;
spin_unlock_irqrestore(&priv->lock, flags);
/* Wake up the thread to process deleted timers */ /* Wake up the thread to process deleted timers */
@ -603,9 +605,6 @@ void esp_hr_timer_delete(struct esp_hr_timer_s *timer)
{ {
tmrerr("Failed to post sem ret=%d\n", ret); tmrerr("Failed to post sem ret=%d\n", ret);
} }
exit:
leave_critical_section(flags);
} }
/**************************************************************************** /****************************************************************************

View file

@ -181,6 +181,7 @@ void esp_hr_timer_start_periodic(struct esp_hr_timer_s *timer,
****************************************************************************/ ****************************************************************************/
void esp_hr_timer_stop(struct esp_hr_timer_s *timer); void esp_hr_timer_stop(struct esp_hr_timer_s *timer);
void esp_hr_timer_stop_nolock(struct esp_hr_timer_s *timer);
/**************************************************************************** /****************************************************************************
* Name: esp_hr_timer_delete * Name: esp_hr_timer_delete

View file

@ -102,6 +102,8 @@ struct esp_rtc_lowerhalf_s
struct alm_cbinfo_s alarmcb[CONFIG_RTC_NALARMS]; struct alm_cbinfo_s alarmcb[CONFIG_RTC_NALARMS];
#endif /* CONFIG_RTC_ALARM */ #endif /* CONFIG_RTC_ALARM */
spinlock_t lock;
}; };
#endif/* CONFIG_RTC_DRIVER */ #endif/* CONFIG_RTC_DRIVER */
@ -420,13 +422,12 @@ static bool esp_rtc_havesettime(struct rtc_lowerhalf_s *lower)
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_RTC_DRIVER) && defined(CONFIG_RTC_ALARM) #if defined(CONFIG_RTC_DRIVER) && defined(CONFIG_RTC_ALARM)
static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower, static int esp_rtc_setalarm_nolock(struct rtc_lowerhalf_s *lower,
const struct lower_setalarm_s *alarminfo) const struct lower_setalarm_s *alarminfo)
{ {
struct esp_rtc_lowerhalf_s *priv = (struct esp_rtc_lowerhalf_s *)lower; struct esp_rtc_lowerhalf_s *priv = (struct esp_rtc_lowerhalf_s *)lower;
struct alm_cbinfo_s *cbinfo; struct alm_cbinfo_s *cbinfo;
uint64_t timeout; uint64_t timeout;
irqstate_t flags;
int id; int id;
DEBUGASSERT(priv != NULL); DEBUGASSERT(priv != NULL);
@ -446,8 +447,6 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
/* Create the RT-Timer alarm */ /* Create the RT-Timer alarm */
flags = spin_lock_irqsave(NULL);
if (cbinfo->alarm_hdl == NULL) if (cbinfo->alarm_hdl == NULL)
{ {
struct esp_hr_timer_args_s hr_timer_args; struct esp_hr_timer_args_s hr_timer_args;
@ -461,7 +460,6 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
if (ret < 0) if (ret < 0)
{ {
rtcerr("Failed to create HR Timer=%d\n", ret); rtcerr("Failed to create HR Timer=%d\n", ret);
spin_unlock_irqrestore(NULL, flags);
return ret; return ret;
} }
} }
@ -474,10 +472,22 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
esp_hr_timer_start(cbinfo->alarm_hdl, cbinfo->deadline_us, false); esp_hr_timer_start(cbinfo->alarm_hdl, cbinfo->deadline_us, false);
spin_unlock_irqrestore(NULL, flags);
return OK; return OK;
} }
static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
const struct lower_setalarm_s *alarminfo)
{
struct esp_rtc_lowerhalf_s *priv = (struct esp_rtc_lowerhalf_s *)lower;
irqstate_t flags;
int ret;
flags = spin_lock_irqsave(&priv->lock);
ret = esp_rtc_setalarm_nolock(lower, alarminfo);
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
#endif /* CONFIG_RTC_DRIVER && CONFIG_RTC_ALARM */ #endif /* CONFIG_RTC_DRIVER && CONFIG_RTC_ALARM */
/**************************************************************************** /****************************************************************************
@ -501,6 +511,7 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower, static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower,
const struct lower_setrelative_s *alarminfo) const struct lower_setrelative_s *alarminfo)
{ {
struct esp_rtc_lowerhalf_s *priv = (struct esp_rtc_lowerhalf_s *)lower;
struct lower_setalarm_s setalarm; struct lower_setalarm_s setalarm;
time_t seconds; time_t seconds;
int ret = -EINVAL; int ret = -EINVAL;
@ -510,7 +521,7 @@ static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower,
if (alarminfo->reltime > 0) if (alarminfo->reltime > 0)
{ {
flags = spin_lock_irqsave(NULL); flags = spin_lock_irqsave(&priv->lock);
seconds = alarminfo->reltime; seconds = alarminfo->reltime;
gmtime_r(&seconds, (struct tm *)&setalarm.time); gmtime_r(&seconds, (struct tm *)&setalarm.time);
@ -520,9 +531,9 @@ static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower,
setalarm.id = alarminfo->id; setalarm.id = alarminfo->id;
setalarm.cb = alarminfo->cb; setalarm.cb = alarminfo->cb;
setalarm.priv = alarminfo->priv; setalarm.priv = alarminfo->priv;
ret = esp_rtc_setalarm(lower, &setalarm); ret = esp_rtc_setalarm_nolock(lower, &setalarm);
spin_unlock_irqrestore(NULL, flags); spin_unlock_irqrestore(&priv->lock, flags);
} }
return ret; return ret;
@ -566,7 +577,7 @@ static int esp_rtc_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid)
return -ENODATA; return -ENODATA;
} }
flags = spin_lock_irqsave(NULL); flags = spin_lock_irqsave(&priv->lock);
/* Stop and delete the alarm */ /* Stop and delete the alarm */
@ -579,7 +590,7 @@ static int esp_rtc_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid)
cbinfo->deadline_us = 0; cbinfo->deadline_us = 0;
cbinfo->alarm_hdl = NULL; cbinfo->alarm_hdl = NULL;
spin_unlock_irqrestore(NULL, flags); spin_unlock_irqrestore(&priv->lock, flags);
return OK; return OK;
} }
@ -616,7 +627,7 @@ static int esp_rtc_rdalarm(struct rtc_lowerhalf_s *lower,
priv = (struct esp_rtc_lowerhalf_s *)lower; priv = (struct esp_rtc_lowerhalf_s *)lower;
flags = spin_lock_irqsave(NULL); flags = spin_lock_irqsave(&priv->lock);
/* Get the alarm according to the alarm ID */ /* Get the alarm according to the alarm ID */
@ -630,7 +641,7 @@ static int esp_rtc_rdalarm(struct rtc_lowerhalf_s *lower,
localtime_r((const time_t *)&ts.tv_sec, localtime_r((const time_t *)&ts.tv_sec,
(struct tm *)alarminfo->time); (struct tm *)alarminfo->time);
spin_unlock_irqrestore(NULL, flags); spin_unlock_irqrestore(&priv->lock, flags);
return OK; return OK;
} }
@ -664,7 +675,7 @@ time_t up_rtc_time(void)
uint64_t time_us; uint64_t time_us;
irqstate_t flags; irqstate_t flags;
flags = spin_lock_irqsave(NULL); flags = spin_lock_irqsave(&g_rtc_lowerhalf.lock);
#ifdef CONFIG_RTC_DRIVER #ifdef CONFIG_RTC_DRIVER
/* NOTE: HR-Timer starts to work after the board is initialized, and the /* NOTE: HR-Timer starts to work after the board is initialized, and the
@ -694,7 +705,7 @@ time_t up_rtc_time(void)
time_us = esp_rtc_get_time_us() + esp_rtc_get_boot_time(); time_us = esp_rtc_get_time_us() + esp_rtc_get_boot_time();
} }
spin_unlock_irqrestore(NULL, flags); spin_unlock_irqrestore(&g_rtc_lowerhalf.lock, flags);
return (time_t)(time_us / USEC_PER_SEC); return (time_t)(time_us / USEC_PER_SEC);
} }
@ -723,7 +734,7 @@ int up_rtc_gettime(struct timespec *tp)
irqstate_t flags; irqstate_t flags;
uint64_t time_us; uint64_t time_us;
flags = spin_lock_irqsave(NULL); flags = spin_lock_irqsave(&g_rtc_lowerhalf.lock);
#ifdef CONFIG_RTC_DRIVER #ifdef CONFIG_RTC_DRIVER
if (g_hr_timer_enabled) if (g_hr_timer_enabled)
@ -740,7 +751,7 @@ int up_rtc_gettime(struct timespec *tp)
tp->tv_sec = time_us / USEC_PER_SEC; tp->tv_sec = time_us / USEC_PER_SEC;
tp->tv_nsec = (time_us % USEC_PER_SEC) * NSEC_PER_USEC; tp->tv_nsec = (time_us % USEC_PER_SEC) * NSEC_PER_USEC;
spin_unlock_irqrestore(NULL, flags); spin_unlock_irqrestore(&g_rtc_lowerhalf.lock, flags);
return OK; return OK;
} }
@ -770,7 +781,7 @@ int up_rtc_settime(const struct timespec *ts)
DEBUGASSERT(ts != NULL && ts->tv_nsec < NSEC_PER_SEC); DEBUGASSERT(ts != NULL && ts->tv_nsec < NSEC_PER_SEC);
flags = spin_lock_irqsave(NULL); flags = spin_lock_irqsave(&g_rtc_lowerhalf.lock);
now_us = ((uint64_t) ts->tv_sec) * USEC_PER_SEC + now_us = ((uint64_t) ts->tv_sec) * USEC_PER_SEC +
ts->tv_nsec / NSEC_PER_USEC; ts->tv_nsec / NSEC_PER_USEC;
@ -794,7 +805,7 @@ int up_rtc_settime(const struct timespec *ts)
esp_rtc_set_boot_time(rtc_offset_us); esp_rtc_set_boot_time(rtc_offset_us);
spin_unlock_irqrestore(NULL, flags); spin_unlock_irqrestore(&g_rtc_lowerhalf.lock, flags);
return OK; return OK;
} }
@ -873,6 +884,7 @@ int esp_rtc_driverinit(void)
return ret; return ret;
} }
spin_lock_init(&g_rtc_lowerhalf.lock);
g_hr_timer_enabled = true; g_hr_timer_enabled = true;
/* Get the time difference between HR Timer and RTC */ /* Get the time difference between HR Timer and RTC */