xiaoxiang781216 commented on a change in pull request #4270:
URL: https://github.com/apache/incubator-nuttx/pull/4270#discussion_r682553257



##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }

Review comment:
       Because one thread may just pass the first check but is interrupted by 
OS before hold the lock. Other thread may call localtime_r and then initialize 
the tzinfo before the first thread resume. The second check avoid the first 
thread initialize tzinfo twice.

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }
+
+#ifndef __KERNEL__
+  if (up_interrupt_context())
+    {
+      return;
+    }

Review comment:
       If you "grep -r gmtime" in arch or drivers folder, more than 20 place 
call this function. If we allow kernel component call locale time related API, 
the check need be done here instead each call site.

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }

Review comment:
       > Thanks for providing this example scenario. I am still having a hard 
time to understand how the first check copes with this concurrency between 
threads.
   > Let's assume threads A and B.
   > Thread A fails the check (which means timezone info was still not 
initialized). But, the OS interrupts thread A before it locks the semaphore.
   > Thread B then calls `tzset` and locks the semaphore, completes the 
initialization of timezone info and unlock the semaphore.
   > Thread A later resumes execution, finally locks the semaphore and, as 
expected, finds that timezone is already initialized.
   > The same outcome would happen if the first check did not exist, wouldn't 
it?
   > 
   > Sorry if there is something too obvious I am not realizing, but I'd like 
to be convinced that the first check is not useless.
   
   Yes, but the problem is that you can't take the lock and then do the check 
in the interrupt.
   

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }
+
+#ifndef __KERNEL__
+  if (up_interrupt_context())
+    {
+      return;
+    }

Review comment:
       I am fine with any approach, but the mainline will panic directly if you 
enable both config. And you can remove localtime from syslog by lose the local 
timing, but the call in driver is hard to remove.

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }

Review comment:
       Because the first check can't hold the lock after we check 

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }

Review comment:
       Because the first check can't hold the lock after we check 

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }

Review comment:
       Your mean move up_interrupt_context before tz_semtake? it seem work.

##########
File path: libs/libc/time/lib_localtime.c
##########
@@ -2528,9 +2537,20 @@ void tzset(void)
 {
   FAR const char *name;
 
-  tz_semtake(&g_lcl_sem);
-
   name = getenv("TZ");
+  if (g_lcl_isset > 0 && name && strcmp(g_lcl_tzname, name) == 0)
+    {
+      return;
+    }

Review comment:
       Yes, your analysis is right: double check in gmstub is right, but tzset 
is redundant.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to