Skip to content

Commit

Permalink
esp_rtc: use small lock in arch/risc-v/src/common/espressif/esp_rtc.c
Browse files Browse the repository at this point in the history
reason:
We would like to replace the big lock with a small lock.

Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 authored and xiaoxiang781216 committed Dec 20, 2024
1 parent 48c4391 commit 59a849a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 36 deletions.
29 changes: 14 additions & 15 deletions arch/risc-v/src/common/espressif/esp_hr_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ void IRAM_ATTR esp_hr_timer_start(struct esp_hr_timer_s *timer,

if (timer->state != HR_TIMER_IDLE)
{
esp_hr_timer_stop(timer);
esp_hr_timer_stop_nolock(timer);
}

/* Calculate the timer's alarm value */
Expand Down Expand Up @@ -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;

irqstate_t flags = spin_lock_irqsave(&priv->lock);

/* "start" function can set the timer's repeat flag, and "stop" function
* should remove this flag.
*/
Expand Down Expand Up @@ -546,14 +544,16 @@ void IRAM_ATTR esp_hr_timer_stop(struct esp_hr_timer_s *timer)

list_delete(&timer->list);
timer->state = HR_TIMER_IDLE;

spin_unlock_irqrestore(&priv->lock, flags);

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);
}

Expand All @@ -578,23 +578,25 @@ void esp_hr_timer_delete(struct esp_hr_timer_s *timer)

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)
{
esp_hr_timer_stop(timer);
esp_hr_timer_stop_nolock(timer);
}
else if (timer->state == HR_TIMER_TIMEOUT)
{
list_delete(&timer->list);
}
else if (timer->state == HR_TIMER_DELETE)
{
goto exit;
spin_unlock_irqrestore(&priv->lock, flags);
return;
}

list_add_after(&priv->toutlist, &timer->list);
timer->state = HR_TIMER_DELETE;
spin_unlock_irqrestore(&priv->lock, flags);

/* Wake up the thread to process deleted timers */

Expand All @@ -603,9 +605,6 @@ void esp_hr_timer_delete(struct esp_hr_timer_s *timer)
{
tmrerr("Failed to post sem ret=%d\n", ret);
}

exit:
leave_critical_section(flags);
}

/****************************************************************************
Expand Down
1 change: 1 addition & 0 deletions arch/risc-v/src/common/espressif/esp_hr_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_nolock(struct esp_hr_timer_s *timer);

/****************************************************************************
* Name: esp_hr_timer_delete
Expand Down
54 changes: 33 additions & 21 deletions arch/risc-v/src/common/espressif/esp_rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ struct esp_rtc_lowerhalf_s

struct alm_cbinfo_s alarmcb[CONFIG_RTC_NALARMS];
#endif /* CONFIG_RTC_ALARM */

spinlock_t lock;
};

#endif/* CONFIG_RTC_DRIVER */
Expand Down Expand Up @@ -420,13 +422,12 @@ static bool esp_rtc_havesettime(struct rtc_lowerhalf_s *lower)
****************************************************************************/

#if defined(CONFIG_RTC_DRIVER) && defined(CONFIG_RTC_ALARM)
static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
const struct lower_setalarm_s *alarminfo)
static int esp_rtc_setalarm_nolock(struct rtc_lowerhalf_s *lower,
const struct lower_setalarm_s *alarminfo)
{
struct esp_rtc_lowerhalf_s *priv = (struct esp_rtc_lowerhalf_s *)lower;
struct alm_cbinfo_s *cbinfo;
uint64_t timeout;
irqstate_t flags;
int id;

DEBUGASSERT(priv != NULL);
Expand All @@ -446,8 +447,6 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,

/* Create the RT-Timer alarm */

flags = spin_lock_irqsave(NULL);

if (cbinfo->alarm_hdl == NULL)
{
struct esp_hr_timer_args_s hr_timer_args;
Expand All @@ -461,7 +460,6 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
if (ret < 0)
{
rtcerr("Failed to create HR Timer=%d\n", ret);
spin_unlock_irqrestore(NULL, flags);
return ret;
}
}
Expand All @@ -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);

spin_unlock_irqrestore(NULL, flags);

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 */

/****************************************************************************
Expand All @@ -501,6 +511,7 @@ static int esp_rtc_setalarm(struct rtc_lowerhalf_s *lower,
static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower,
const struct lower_setrelative_s *alarminfo)
{
struct esp_rtc_lowerhalf_s *priv = (struct esp_rtc_lowerhalf_s *)lower;
struct lower_setalarm_s setalarm;
time_t seconds;
int ret = -EINVAL;
Expand All @@ -510,7 +521,7 @@ static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower,

if (alarminfo->reltime > 0)
{
flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&priv->lock);

seconds = alarminfo->reltime;
gmtime_r(&seconds, (struct tm *)&setalarm.time);
Expand All @@ -520,9 +531,9 @@ static int esp_rtc_setrelative(struct rtc_lowerhalf_s *lower,
setalarm.id = alarminfo->id;
setalarm.cb = alarminfo->cb;
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;
Expand Down Expand Up @@ -566,7 +577,7 @@ static int esp_rtc_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid)
return -ENODATA;
}

flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&priv->lock);

/* Stop and delete the alarm */

Expand All @@ -579,7 +590,7 @@ static int esp_rtc_cancelalarm(struct rtc_lowerhalf_s *lower, int alarmid)
cbinfo->deadline_us = 0;
cbinfo->alarm_hdl = NULL;

spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);

return OK;
}
Expand Down Expand Up @@ -616,7 +627,7 @@ static int esp_rtc_rdalarm(struct 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 */

Expand All @@ -630,7 +641,7 @@ static int esp_rtc_rdalarm(struct rtc_lowerhalf_s *lower,
localtime_r((const time_t *)&ts.tv_sec,
(struct tm *)alarminfo->time);

spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&priv->lock, flags);

return OK;
}
Expand Down Expand Up @@ -664,7 +675,7 @@ time_t up_rtc_time(void)
uint64_t time_us;
irqstate_t flags;

flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&g_rtc_lowerhalf.lock);

#ifdef CONFIG_RTC_DRIVER
/* NOTE: HR-Timer starts to work after the board is initialized, and the
Expand Down Expand Up @@ -694,7 +705,7 @@ time_t up_rtc_time(void)
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);
}
Expand Down Expand Up @@ -723,7 +734,7 @@ int up_rtc_gettime(struct timespec *tp)
irqstate_t flags;
uint64_t time_us;

flags = spin_lock_irqsave(NULL);
flags = spin_lock_irqsave(&g_rtc_lowerhalf.lock);

#ifdef CONFIG_RTC_DRIVER
if (g_hr_timer_enabled)
Expand All @@ -740,7 +751,7 @@ int up_rtc_gettime(struct timespec *tp)
tp->tv_sec = time_us / USEC_PER_SEC;
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;
}
Expand Down Expand Up @@ -770,7 +781,7 @@ int up_rtc_settime(const struct timespec *ts)

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 +
ts->tv_nsec / NSEC_PER_USEC;
Expand All @@ -794,7 +805,7 @@ int up_rtc_settime(const struct timespec *ts)

esp_rtc_set_boot_time(rtc_offset_us);

spin_unlock_irqrestore(NULL, flags);
spin_unlock_irqrestore(&g_rtc_lowerhalf.lock, flags);

return OK;
}
Expand Down Expand Up @@ -873,6 +884,7 @@ int esp_rtc_driverinit(void)
return ret;
}

spin_lock_init(&g_rtc_lowerhalf.lock);
g_hr_timer_enabled = true;

/* Get the time difference between HR Timer and RTC */
Expand Down

0 comments on commit 59a849a

Please sign in to comment.