Skip to content

Commit ce6301c

Browse files
committed
combine PL_strategy_* bools into 1 exported symbol
These 9 symbols are just 2 bits wide bools. I presume each one is declared as a 4 byte int because either they are lvals taking a 4 byte enum assignment or because C doesn't acknowledge the SMP concept and doesn't describe any unit tests for threads or SMP address spaces. ISO C stopped describing what volatile and register do on a HW level long ago. Considering all current former and future CPU archs Perl has executed on, there is no money-back guarentee from all CPU mfgs that doing R/Ws to the same mem addr by 2 CPU cores will not shard or be atomic. As of 5.43, metaconfig and perl.h still don't know about the std::atomic API that first appeared in C11/C++11. PL_strategy_* is required de-jure, not de-facto, by C11/C++11 to be using the atomic_load() token. It is very overkill to use the atomic_load() token on these PL_strategy_* vars. atomic_load() can be added to PL_strategy_* after a verified and reproduced bug ticket on the correct permutation of hardware and compiler that needs it. Dr Memory, Asan, and Valgrind aren't hardware. These 9 different exported linker symbols take up significant screen space in various C dev tools. These vars will never be part of a copy paste backtrace SEGV report. They are undocumented, not public CPAN API. The only user is doio.c They take up alot of bytes inside of libperl since symbol PL_strategy_mkstemp can't be smaller than 24 == (sizeof("PL_strategy_mkstemp") + sizeof(U32)) Dynamic instrumenting all dereferences of PL_strategy_dup but not instrumenting PL_strategy_mkstemp, using LD_PRELOAD inside a private + obsolete + proprietary + closed source + lost source build of libperl.so ... All of the PL_strategy_* symbols have no references to them on Win32. The Win32 doio.o/doio.obj file doesn't link against the PL_strategy_* symbols. They would've been discarded on Windows, but their names appeared inside perldll.def so that is that and ABI is ABI. The easiest step is to combine the symbols into 1 ascii C string name. Any other improvements will be more complex and can be done another time. This step is beneficial on all OS since the shared library loaders on all OSes have to loop over the array of "Symbols" to connect 2 files, or 2 User Services (TM IBM), or 2 Subroutines (TM Larry Wall) atleast once on startup. If this io_strategy code needs to be stepped debeg (unlikely) keeping all the bools together in 1 struct is easier to see their state in the watch window since its 1 name to type in vs 9 names. The amount of vertical screen space these exported symbols occupy in C devel tools if they are drawn, and need to be scrolled or glanced by, or more partial match letters to type, vs what these syms/vars do and the state they hold, is the main reason this commit was written.
1 parent 52d9c9c commit ce6301c

File tree

4 files changed

+50
-30
lines changed

4 files changed

+50
-30
lines changed

doio.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ Perl_PerlLIO_dup_cloexec(pTHX_ int oldfd)
196196
* PERL_IMPLICIT_SYS builds.
197197
*/
198198
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
199-
PL_strategy_dup,
199+
PL_strategy.dup,
200200
fcntl(oldfd, F_DUPFD_CLOEXEC, 0),
201201
PerlLIO_dup(oldfd));
202202
#else
@@ -214,7 +214,7 @@ Perl_PerlLIO_dup2_cloexec(pTHX_ int oldfd, int newfd)
214214
* PERL_IMPLICIT_SYS builds.
215215
*/
216216
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
217-
PL_strategy_dup2,
217+
PL_strategy.dup2,
218218
dup3(oldfd, newfd, O_CLOEXEC),
219219
PerlLIO_dup2(oldfd, newfd));
220220
#else
@@ -279,7 +279,7 @@ Perl_PerlLIO_open_cloexec(pTHX_ const char *file, int flag)
279279
PERL_ARGS_ASSERT_PERLLIO_OPEN_CLOEXEC;
280280
#if defined(O_CLOEXEC)
281281
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
282-
PL_strategy_open,
282+
PL_strategy.open,
283283
PerlLIO_open(file, flag | O_CLOEXEC),
284284
PerlLIO_open(file, flag));
285285
#else
@@ -293,7 +293,7 @@ Perl_PerlLIO_open3_cloexec(pTHX_ const char *file, int flag, int perm)
293293
PERL_ARGS_ASSERT_PERLLIO_OPEN3_CLOEXEC;
294294
#if defined(O_CLOEXEC)
295295
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
296-
PL_strategy_open3,
296+
PL_strategy.open3,
297297
PerlLIO_open3(file, flag | O_CLOEXEC, perm),
298298
PerlLIO_open3(file, flag, perm));
299299
#else
@@ -310,7 +310,7 @@ static int Internal_Perl_my_mkstemp_cloexec(char *templte)
310310
PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC;
311311
# if defined(O_CLOEXEC)
312312
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
313-
PL_strategy_mkstemp,
313+
PL_strategy.mkstemp,
314314
Perl_my_mkostemp(templte, O_CLOEXEC),
315315
Perl_my_mkstemp(templte));
316316
# else
@@ -334,7 +334,7 @@ Perl_my_mkstemp_cloexec(char *templte)
334334
PERL_ARGS_ASSERT_MY_MKSTEMP_CLOEXEC;
335335
# if defined(O_CLOEXEC)
336336
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
337-
PL_strategy_mkstemp,
337+
PL_strategy.mkstemp,
338338
Perl_my_mkostemp(templte, O_CLOEXEC),
339339
Perl_my_mkstemp(templte));
340340
# else
@@ -349,7 +349,7 @@ Perl_my_mkostemp_cloexec(char *templte, int flags)
349349
PERL_ARGS_ASSERT_MY_MKOSTEMP_CLOEXEC;
350350
#if defined(O_CLOEXEC)
351351
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
352-
PL_strategy_mkstemp,
352+
PL_strategy.mkstemp,
353353
Perl_my_mkostemp(templte, flags | O_CLOEXEC),
354354
Perl_my_mkostemp(templte, flags));
355355
#else
@@ -368,7 +368,7 @@ Perl_PerlProc_pipe_cloexec(pTHX_ int *pipefd)
368368
* PERL_IMPLICIT_SYS builds.
369369
*/
370370
# if !defined(PERL_IMPLICIT_SYS) && defined(HAS_PIPE2) && defined(O_CLOEXEC)
371-
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PL_strategy_pipe, pipefd,
371+
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PL_strategy.pipe, pipefd,
372372
pipe2(pipefd, O_CLOEXEC),
373373
PerlProc_pipe(pipefd));
374374
# else
@@ -384,7 +384,7 @@ Perl_PerlSock_socket_cloexec(pTHX_ int domain, int type, int protocol)
384384
{
385385
# if defined(SOCK_CLOEXEC)
386386
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
387-
PL_strategy_socket,
387+
PL_strategy.socket,
388388
PerlSock_socket(domain, type | SOCK_CLOEXEC, protocol),
389389
PerlSock_socket(domain, type, protocol));
390390
# else
@@ -404,7 +404,7 @@ Perl_PerlSock_accept_cloexec(pTHX_ int listenfd, struct sockaddr *addr,
404404
* on PERL_IMPLICIT_SYS builds.
405405
*/
406406
DO_ONEOPEN_EXPERIMENTING_CLOEXEC(
407-
PL_strategy_accept,
407+
PL_strategy.accept,
408408
accept4(listenfd, addr, addrlen, SOCK_CLOEXEC),
409409
PerlSock_accept(listenfd, addr, addrlen));
410410
# else
@@ -423,7 +423,7 @@ Perl_PerlSock_socketpair_cloexec(pTHX_ int domain, int type, int protocol,
423423
{
424424
PERL_ARGS_ASSERT_PERLSOCK_SOCKETPAIR_CLOEXEC;
425425
# ifdef SOCK_CLOEXEC
426-
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PL_strategy_socketpair, pairfd,
426+
DO_PIPEOPEN_EXPERIMENTING_CLOEXEC(PL_strategy.socketpair, pairfd,
427427
PerlSock_socketpair(domain, type | SOCK_CLOEXEC, protocol, pairfd),
428428
PerlSock_socketpair(domain, type, protocol, pairfd));
429429
# else

globvar.sym

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,7 @@ PL_sig_name
6666
PL_sig_num
6767
PL_simple
6868
PL_simple_bitmask
69-
PL_strategy_dup
70-
PL_strategy_dup2
71-
PL_strategy_open
72-
PL_strategy_open3
73-
PL_strategy_mkstemp
74-
PL_strategy_socket
75-
PL_strategy_accept
76-
PL_strategy_pipe
77-
PL_strategy_socketpair
69+
PL_strategy
7870
PL_strict_utf8_dfa_tab
7971
PL_subversion
8072
PL_utf8skip

perl.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5230,6 +5230,35 @@ EXTERN_C void PerlIO_teardown(void);
52305230
# define PERLIO_TERM
52315231
#endif
52325232

5233+
/* these record the best way to perform certain IO operations while
5234+
* atomically setting FD_CLOEXEC. On the first call, a probe is done
5235+
* and the result recorded for use by subsequent calls.
5236+
* In theory these variables aren't thread-safe, but the worst that can
5237+
* happen is that two threads will both do an initial probe or even less
5238+
* likley both ithreads will repeat the probe a couple times over the next
5239+
* 100 ms.
5240+
*
5241+
* If a cross platform atomic API gets added to perl.h, all reads and writes
5242+
* to PL_strategy need force a memory fence. Certain archs like ARM in SMP mode
5243+
* by design will never re-read or flush memory writes between their L2 cache
5244+
* central physical unless software commands the CPU core to do it.
5245+
*
5246+
* struct io_stategy {} can be reduced to a U32 with 18 bits if its known
5247+
* the CC guarentees (PL_strategy & 0xC == 0x8) is safe against sharding.
5248+
*/
5249+
5250+
struct io_strategy {
5251+
int strategy_dup; /* doio.c */
5252+
int strategy_dup2; /* doio.c */
5253+
int strategy_open; /* doio.c */
5254+
int strategy_open3; /* doio.c */
5255+
int strategy_mkstemp; /* doio.c */
5256+
int strategy_socket; /* doio.c */
5257+
int strategy_accept; /* doio.c */
5258+
int strategy_pipe; /* doio.c */
5259+
int strategy_socketpair; /* doio.c */
5260+
};
5261+
52335262
#ifdef MYMALLOC
52345263
# ifdef MUTEX_INIT_CALLS_MALLOC
52355264
# define MALLOC_INIT \

perlvars.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -400,21 +400,20 @@ PERLVAR(G, user_prop_mutex, perl_mutex) /* Mutex for manipulating
400400
*/
401401
PERLVARI(G, shutdownhook, shutdown_proc_t, &Perl_noshutdownhook)
402402

403-
/* these record the best way to perform certain IO operations while
403+
/* This struct records the best way to perform certain IO operations while
404404
* atomically setting FD_CLOEXEC. On the first call, a probe is done
405405
* and the result recorded for use by subsequent calls.
406406
* In theory these variables aren't thread-safe, but the worst that can
407407
* happen is that two treads will both do an initial probe
408+
*
409+
* Boolean-like probe results for certain I/O operations and FD_CLOEXEC.
410+
* Each flag has 3 states: enum CLOEXEC_EXPERIMENT (== 0), CLOEXEC_AT_OPEN,
411+
* and CLOEXEC_AFTER_OPEN.
412+
*
413+
* doio.c is the only user of this var currently. This variable is exported
414+
* in case experimental XS code needs to perfectly replicate an IO pp_*() func.
408415
*/
409-
PERLVARI(G, strategy_dup, int, 0) /* doio.c */
410-
PERLVARI(G, strategy_dup2, int, 0) /* doio.c */
411-
PERLVARI(G, strategy_open, int, 0) /* doio.c */
412-
PERLVARI(G, strategy_open3, int, 0) /* doio.c */
413-
PERLVARI(G, strategy_mkstemp, int, 0) /* doio.c */
414-
PERLVARI(G, strategy_socket, int, 0) /* doio.c */
415-
PERLVARI(G, strategy_accept, int, 0) /* doio.c */
416-
PERLVARI(G, strategy_pipe, int, 0) /* doio.c */
417-
PERLVARI(G, strategy_socketpair, int, 0) /* doio.c */
416+
PERLVAR(G, strategy, struct io_strategy)
418417

419418
PERLVARI(G, my_environ, char **, NULL)
420419
PERLVARI(G, origenviron, char **, NULL)

0 commit comments

Comments
 (0)