develooper Front page | perl.perl5.porters | Postings from February 2006

Re: possibly (tiny) size saving idea

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
February 3, 2006 05:10
Subject:
Re: possibly (tiny) size saving idea
Message ID:
20060203130955.GY616@plum.flirble.org
On Sat, Jan 28, 2006 at 08:04:38PM +0000, Nick Ing-Simmons wrote:
> Nicholas Clark <nick@ccl4.org> writes:
> >As far as I can tell, the rest of the code won't notice if that array is
> >malloc()ed and resized as needed. From what I remember, that would add no
> >significant complexity to the code.
> 
> It is global so that all threads and pseudo-forks can see it.
> It isn't malloc-ed just because the Win32/PerlHost "per-thread" malloc
> got in the way. It is possible that the global malloc pool could be used.

Well, I committed it as change 27059, so lets see if it works.

Nicholas Clark

Change 27059 by nicholas@nicholas-saigo on 2006/02/03 13:06:00

        Change PL_perlio_fd_refcnt from a fixed size static array to a pointer
        to a dynamic array.

Affected files ...

... //depot/perl/embedvar.h#213 edit
... //depot/perl/perlapi.h#135 edit
... //depot/perl/perlio.c#300 edit
... //depot/perl/perlvars.h#67 edit

Differences ...

==== //depot/perl/embedvar.h#213 (text+w) ====

@@ -882,6 +882,8 @@
 #define PL_Gperlio_debug_fd    (my_vars->Gperlio_debug_fd)
 #define PL_perlio_fd_refcnt    (my_vars->Gperlio_fd_refcnt)
 #define PL_Gperlio_fd_refcnt   (my_vars->Gperlio_fd_refcnt)
+#define PL_perlio_fd_refcnt_size       (my_vars->Gperlio_fd_refcnt_size)
+#define PL_Gperlio_fd_refcnt_size      (my_vars->Gperlio_fd_refcnt_size)
 #define PL_ppaddr              (my_vars->Gppaddr)
 #define PL_Gppaddr             (my_vars->Gppaddr)
 #define PL_sh_path             (my_vars->Gsh_path)
@@ -931,6 +933,7 @@
 #define PL_Gpatleave           PL_patleave
 #define PL_Gperlio_debug_fd    PL_perlio_debug_fd
 #define PL_Gperlio_fd_refcnt   PL_perlio_fd_refcnt
+#define PL_Gperlio_fd_refcnt_size      PL_perlio_fd_refcnt_size
 #define PL_Gppaddr             PL_ppaddr
 #define PL_Gsh_path            PL_sh_path
 #define PL_Gsig_defaulting     PL_sig_defaulting

==== //depot/perl/perlapi.h#135 (text+w) ====

@@ -946,6 +946,8 @@
 #define PL_perlio_debug_fd     (*Perl_Gperlio_debug_fd_ptr(NULL))
 #undef  PL_perlio_fd_refcnt
 #define PL_perlio_fd_refcnt    (*Perl_Gperlio_fd_refcnt_ptr(NULL))
+#undef  PL_perlio_fd_refcnt_size
+#define PL_perlio_fd_refcnt_size       (*Perl_Gperlio_fd_refcnt_size_ptr(NULL))
 #undef  PL_ppaddr
 #define PL_ppaddr              (*Perl_Gppaddr_ptr(NULL))
 #undef  PL_sh_path

==== //depot/perl/perlio.c#300 (text) ====

@@ -56,8 +56,6 @@
 
 #include "XSUB.h"
 
-#define PERLIO_MAX_REFCOUNTABLE_FD 2048
-
 #ifdef __Lynx__
 /* Missing proto on LynxOS */
 int mkstemp(char*);
@@ -2247,6 +2245,42 @@
 
 /* PL_perlio_fd_refcnt[] is in intrpvar.h */
 
+/* Must be called with PerlIO_mutex locked.  */
+static void
+S_more_refcounted_fds(pTHX_ const int new_fd) {
+    const int old_max = PL_perlio_fd_refcnt_size;
+    const int new_max = 16 + (new_fd & 15);
+    int *new_array;
+
+    PerlIO_debug("More fds - old=%d, need %d, new=%d\n",
+                old_max, new_fd, new_max);
+
+    if (new_fd < old_max) {
+       return;
+    }
+
+    new_array
+       = PerlMemShared_realloc(PL_perlio_fd_refcnt, new_max * sizeof(int));
+
+    if (!new_array) {
+#ifdef USE_THREADS
+       MUTEX_UNLOCK(&PerlIO_mutex);
+#endif
+       /* Can't use PerlIO to write as it allocates memory */
+       PerlLIO_write(PerlIO_fileno(Perl_error_log),
+                     PL_no_mem, strlen(PL_no_mem));
+       my_exit(1);
+    }
+
+    PL_perlio_fd_refcnt_size = new_max;
+    PL_perlio_fd_refcnt = new_array;
+
+    PerlIO_debug("Zeroing %p, %d\n", new_array + old_max, new_max - old_max);
+
+    Zero(new_array + old_max, new_max - old_max, int);
+}
+
+
 void
 PerlIO_init(pTHX)
 {
@@ -2260,13 +2294,18 @@
 PerlIOUnix_refcnt_inc(int fd)
 {
     dTHX;
-    if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) {
+    if (fd >= 0) {
        dVAR;
+
 #ifdef USE_THREADS
        MUTEX_LOCK(&PerlIO_mutex);
 #endif
+       if (fd >= PL_perlio_fd_refcnt_size)
+           S_more_refcounted_fds(aTHX_ fd);
+
        PL_perlio_fd_refcnt[fd]++;
        PerlIO_debug("fd %d refcnt=%d\n",fd,PL_perlio_fd_refcnt[fd]);
+
 #ifdef USE_THREADS
        MUTEX_UNLOCK(&PerlIO_mutex);
 #endif
@@ -2278,11 +2317,16 @@
 {
     dTHX;
     int cnt = 0;
-    if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) {
+    if (fd >= 0) {
        dVAR;
 #ifdef USE_THREADS
        MUTEX_LOCK(&PerlIO_mutex);
 #endif
+       /* XXX should this be a panic?  */
+       if (fd >= PL_perlio_fd_refcnt_size)
+           S_more_refcounted_fds(aTHX_ fd);
+
+       /* XXX should this be a panic if it drops below 0?  */
        cnt = --PL_perlio_fd_refcnt[fd];
        PerlIO_debug("fd %d refcnt=%d\n",fd,cnt);
 #ifdef USE_THREADS
@@ -2512,7 +2556,7 @@
     if (flags & PERLIO_DUP_FD) {
        fd = PerlLIO_dup(fd);
     }
-    if (fd >= 0 && fd < PERLIO_MAX_REFCOUNTABLE_FD) {
+    if (fd >= 0) {
        f = PerlIOBase_dup(aTHX_ f, o, param, flags);
        if (f) {
            /* If all went well overwrite fd in dup'ed lay with the dup()'ed fd */

==== //depot/perl/perlvars.h#67 (text) ====

@@ -76,7 +76,8 @@
 #endif
 
 #ifdef USE_PERLIO
-PERLVARA(Gperlio_fd_refcnt, 2048, int) /* PERLIO_MAX_REFCOUNTABLE_FD */
+PERLVARI(Gperlio_fd_refcnt, int*, 0) /* Pointer to array of fd refcounts.  */
+PERLVARI(Gperlio_fd_refcnt_size, int, 0) /* Size of the array */
 PERLVARI(Gperlio_debug_fd, int, 0) /* the fd to write perlio debug into, 0 means not set yet */
 #endif
 

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About