From 7256d67a1ccbea1eca062d899b32dd1d9817fa14 Mon Sep 17 00:00:00 2001 From: zhushengle Date: Tue, 30 Mar 2021 17:34:23 +0800 Subject: [PATCH] =?UTF-8?q?IssueNo:#!3456=20Description:=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?setitimer=E5=A4=9A=E6=A0=B8=E9=9D=99=E6=80=81=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20Sig:kernel=20Feature=20or=20Bugfix:Bugfix=20Binary=20Source:?= =?UTF-8?q?No?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I43661908d0d5248f70acb16ea95dc76fcdb6a84e --- compat/posix/src/time.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/compat/posix/src/time.c b/compat/posix/src/time.c index 462ea7c0..cf9c9a76 100755 --- a/compat/posix/src/time.c +++ b/compat/posix/src/time.c @@ -883,8 +883,10 @@ clock_t times(struct tms *buf) int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue) { + UINT32 intSave; LosTaskCB *taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet()); LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID); + timer_t timerID = 0; struct itimerspec spec; struct itimerspec ospec; int ret = LOS_OK; @@ -894,15 +896,28 @@ int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue set_errno(EINVAL); return -1; } - LOS_TaskLock(); + + /* To avoid creating an invalid timer after the timer has already been create */ if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) { - ret = timer_create(CLOCK_REALTIME, NULL, &processCB->timerID); + ret = timer_create(CLOCK_REALTIME, NULL, &timerID); if (ret != LOS_OK) { - LOS_TaskUnlock(); return ret; } } - LOS_TaskUnlock(); + + /* The initialization of this global timer must be in spinlock + * timer_create cannot be located in spinlock. + */ + SCHEDULER_LOCK(intSave); + if (processCB->timerID == (timer_t)(UINTPTR)MAX_INVALID_TIMER_VID) { + processCB->timerID = timerID; + SCHEDULER_UNLOCK(intSave); + } else { + SCHEDULER_UNLOCK(intSave); + if (timerID) { + timer_delete(timerID); + } + } if (!ValidTimeval(&value->it_value) || !ValidTimeval(&value->it_interval)) { set_errno(EINVAL);