Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

posix: implement _POSIX_THREAD_SAFE_FUNCTIONS's time functions #74180

Merged
merged 2 commits into from
Aug 21, 2024

Conversation

ycsin
Copy link
Member

@ycsin ycsin commented Jun 12, 2024

Add:

  • asctime
  • asctime_r
  • localtime
  • localtime_r
  • ctime
  • ctime_r

@ycsin ycsin requested a review from cfriedt June 12, 2024 16:20
@ycsin ycsin force-pushed the pr/posix_thread_safe_functions branch from feca070 to 3bb69bf Compare June 13, 2024 06:45
@ycsin ycsin force-pushed the pr/posix_thread_safe_functions branch 2 times, most recently from 78031cc to 1b51d12 Compare June 13, 2024 16:57
@ycsin ycsin changed the title libc: common: implement asctime_r() & asctime() posix: implement _POSIX_THREAD_SAFE_FUNCTIONS Jun 14, 2024
@ycsin ycsin force-pushed the pr/posix_thread_safe_functions branch 4 times, most recently from 0266adb to 5487180 Compare June 14, 2024 18:28
@ycsin ycsin marked this pull request as ready for review June 14, 2024 18:28
@zephyrbot zephyrbot added area: Utilities area: Base OS Base OS Library (lib/os) area: C Library C Standard Library area: POSIX POSIX API Library labels Jun 14, 2024
@ycsin ycsin force-pushed the pr/posix_thread_safe_functions branch 3 times, most recently from 32d5924 to 8d5c07a Compare June 15, 2024 15:33
@ycsin ycsin changed the title posix: implement _POSIX_THREAD_SAFE_FUNCTIONS posix: implement _POSIX_THREAD_SAFE_FUNCTIONS's time functions Jun 15, 2024
@ycsin ycsin force-pushed the pr/posix_thread_safe_functions branch 2 times, most recently from bbeab7c to 75e322a Compare June 21, 2024 05:28
Comment on lines 54 to 65
char *asctime(const struct tm *timeptr);
struct tm *localtime(const time_t *timer);
struct tm *localtime_r(const time_t *ZRESTRICT timer, struct tm *ZRESTRICT result);
char *ctime(const time_t *clock);

#if defined(CONFIG_COMMON_LIBC_ASCTIME_R) || defined(__DOXYGEN__)
char *asctime_r(const struct tm *ZRESTRICT tp, char *ZRESTRICT buf);
#endif /* CONFIG_COMMON_LIBC_ASCTIME_R */

#if defined(CONFIG_COMMON_LIBC_CTIME_R) || defined(__DOXYGEN__)
char *ctime_r(const time_t *clock, char *buf);
#endif /* CONFIG_COMMON_LIBC_CTIME_R */
Copy link
Member

@cfriedt cfriedt Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the header file, this would probably work well.

Suggested change
char *asctime(const struct tm *timeptr);
struct tm *localtime(const time_t *timer);
struct tm *localtime_r(const time_t *ZRESTRICT timer, struct tm *ZRESTRICT result);
char *ctime(const time_t *clock);
#if defined(CONFIG_COMMON_LIBC_ASCTIME_R) || defined(__DOXYGEN__)
char *asctime_r(const struct tm *ZRESTRICT tp, char *ZRESTRICT buf);
#endif /* CONFIG_COMMON_LIBC_ASCTIME_R */
#if defined(CONFIG_COMMON_LIBC_CTIME_R) || defined(__DOXYGEN__)
char *ctime_r(const time_t *clock, char *buf);
#endif /* CONFIG_COMMON_LIBC_CTIME_R */
char *asctime(const struct tm *timeptr);
struct tm *localtime(const time_t *timer);
char *ctime(const time_t *clock);
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(__DOXYGEN__)
char *asctime_r(const struct tm *ZRESTRICT tp, char *ZRESTRICT buf);
char *ctime_r(const time_t *clock, char *buf);
struct tm *localtime_r(const time_t *ZRESTRICT timer, struct tm *ZRESTRICT result);
#endif

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I inject _POSIX_THREAD_SAFE_FUNCTIONS into this C header? I had a look at one of the picolibc time.h and they are not guarded

Comment on lines 157 to 163
config POSIX_THREAD_SAFE_FUNCTIONS
bool "POSIX thread-safe functions"
select COMMON_LIBC_ASCTIME_R
select COMMON_LIBC_GMTIME_R
select COMMON_LIBC_LOCALTIME_R_UTC
select COMMON_LIBC_CTIME_R
help
Select 'y' here to enable POSIX thread-safe functions including asctime_r(), ctime_r(),
flockfile(), ftrylockfile(), funlockfile(), getc_unlocked(), getchar_unlocked(),
Copy link
Member

@cfriedt cfriedt Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Darn - I just realized _POSIX_THREAD_SAFE_FUNCTIONS is an Option, and not an Option Group :(

Based on posixoptions(7), it seems to be a combination of POSIX_C_LANG_SUPPORT_R and POSIX_FILE_SYSTEM_R Option Groups

For reference
https://pubs.opengroup.org/onlinepubs/9799919799/xrat/V4_subprofiles.html

So likely we will need a new Kconfig.c_lang_r like this, approximately.

config POSIX_C_LANG_SUPPORT_R
    select COMMON_LIBC_ASCTIME_R
    select COMMON_LIBC_CTIME_R
    select COMMON_LIBC_GMTIME_R
    select COMMON_LIBC_LOCALTIME_R

With that, I think there are some nuances with how POSIX_THREAD_SAFE_FUNCTIONS should behave. Let me know if this makes sense.

Suggested change
config POSIX_THREAD_SAFE_FUNCTIONS
bool "POSIX thread-safe functions"
select COMMON_LIBC_ASCTIME_R
select COMMON_LIBC_GMTIME_R
select COMMON_LIBC_LOCALTIME_R_UTC
select COMMON_LIBC_CTIME_R
help
Select 'y' here to enable POSIX thread-safe functions including asctime_r(), ctime_r(),
flockfile(), ftrylockfile(), funlockfile(), getc_unlocked(), getchar_unlocked(),
config POSIX_THREAD_SAFE_FUNCTIONS
bool "POSIX thread-safe functions"
select POSIX_FILE_SYSTEM_R if POSIX_FILE_SYSTEM
select POSIX_C_LANG_SUPPORT_R
help
Select 'y' here to enable POSIX thread-safe functions including asctime_r(), ctime_r(),
flockfile(), ftrylockfile(), funlockfile(), getc_unlocked(), getchar_unlocked(),

config COMMON_LIBC_GMTIME_R
bool
help
common implementation of gmtime_r().

config COMMON_LIBC_LOCALTIME_R_UTC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one can be abbreviated without the UTC.

From here

Unlike localtime(), the localtime_r() function is not required to set tzname. If localtime_r() sets tzname, it shall also set daylight and timezone. If localtime_r() does not set tzname, it shall not set daylight and shall not set timezone. If the tm structure member tm_zone is accessed after the value of TZ is subsequently modified, the behaviour is undefined.

So if our implementation of localtime_r() never sets the timezone (i.e. is UTC-only), it's still compliant. No special treatment necessary. My assumption is that most would probably like to avoid bringing timezone details into Zephyr.

Suggested change
config COMMON_LIBC_LOCALTIME_R_UTC
config COMMON_LIBC_LOCALTIME_R

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COMMON_LIBC_LOCALTIME_R_UTC is shared by both the localtime() & localtime_r(), I guess that's why I added that suffix to make it obvious that both functions only work for UTC, should I still remove the _UTC suffix? Or maybe I should create another Kconfig for localtime()?

@@ -39,6 +39,9 @@ config MINIMAL_LIBC_TIME
bool "Time functions"
select COMMON_LIBC_TIME if POSIX_TIMERS
select COMMON_LIBC_GMTIME_R
select COMMON_LIBC_ASCTIME
select COMMON_LIBC_LOCALTIME_R_UTC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
select COMMON_LIBC_LOCALTIME_R_UTC
select COMMON_LIBC_LOCALTIME_R

Comment on lines +9 to +12
struct tm *localtime_r(const time_t *timer, struct tm *result)
{
return gmtime_r(timer, result);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct tm *localtime_r(const time_t *timer, struct tm *result)
{
return gmtime_r(timer, result);
}
#ifdef CONFIG_LIBC_TIME_LOCALTIME_R
struct tm *localtime_r(const time_t *timer, struct tm *result)
{
return gmtime_r(timer, result);
}
#endif

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

localtime_r() isn't a C function?

@cfriedt
Copy link
Member

cfriedt commented Aug 14, 2024

Pretty close - get some sleep and we'll check in again in the morning, your time.

@cfriedt
Copy link
Member

cfriedt commented Aug 14, 2024

@ycsin - I'm sorry that this PR (as well as several others you have made) have been delayed. I think this is partly due to false positives in Zephyr's CI.

As a workaround, feel free to include this commit in your PR.

@nashif nashif added the DNM This PR should not be merged (Do Not Merge) label Aug 16, 2024
@nashif
Copy link
Member

nashif commented Aug 16, 2024

DNM: has commit from PR that needs to be merged first.

`readdir_r()` belongs to the following option group

POSIX_FILE_SYSTEM_R: Thread-Safe File System

Create a new Kconfig `CONFIG_POSIX_FILE_SYSTEM_R` to compile
it.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
Implemented the following:
- `asctime_r()`
- `asctime()`
- `localtime()`
- `localtime_r()`
- `ctime()`
- `ctime_r()`

Specifically:
- the implementation of `localtime()` & `localtime_r()` simply
  wraps around the gmtime() & gmtime_r() functions, the
  results are always expressed as UTC.
- `ctime()` is equivalent to `asctime(localtime(clock))`, it
  inherits the limitation of `localtime()` as well, which only
  supports UTC results currently.

Added tests for these newly implemented functions.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
@ycsin ycsin force-pushed the pr/posix_thread_safe_functions branch from 4832201 to 12c7543 Compare August 21, 2024 11:43
@ycsin ycsin removed the DNM This PR should not be merged (Do Not Merge) label Aug 21, 2024
@nashif nashif merged commit fe94d43 into zephyrproject-rtos:main Aug 21, 2024
23 of 24 checks passed
@ycsin ycsin deleted the pr/posix_thread_safe_functions branch August 22, 2024 01:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Base OS Base OS Library (lib/os) area: C Library C Standard Library area: Coding Guidelines Coding guidelines and style area: Continuous Integration area: POSIX POSIX API Library area: Utilities
Projects
None yet
Development

Successfully merging this pull request may close these issues.

posix: implement localtime_r() posix: implement ctime_r() posix: implement asctime_r()
6 participants