* process.h (struct Lisp_Process): Replace Lisp_Objects `pid',
authorStefan Monnier <monnier@iro.umontreal.ca>
Sat, 8 Apr 2006 15:07:35 +0000 (15:07 +0000)
committerStefan Monnier <monnier@iro.umontreal.ca>
Sat, 8 Apr 2006 15:07:35 +0000 (15:07 +0000)
`raw_status_high', and `raw_status_low' with plain integers, and move
them to the end of the structure.

* alloc.c (allocate_process): Use PSEUDOVECSIZE to initialize the
pseudovector's size field so only the Lisp_Object fields get GC'd.

* process.c (update_status, make_process, Fdelete_process)
(Fprocess_status, list_processes_1, start_process_unwind)
(create_process, Fmake_network_process, server_accept_connection)
(wait_reading_process_output, send_process, Fprocess_running_child_p)
(process_send_signal, proc_encode_coding_system, Fprocess_send_eof)
(sigchld_handler, status_notify): Adjust to new non-Lisp fields for
`pid' and `raw_status'.
(Fprocess_id, Fsignal_process): Same, and additionally use floats when
representing PIDs that are larger than most-positive-fixnum.

src/ChangeLog
src/alloc.c
src/process.c
src/process.h

index 56957d6..54c9b86 100644 (file)
@@ -1,3 +1,26 @@
+2006-04-08  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * process.h (struct Lisp_Process): Replace Lisp_Objects `pid',
+       `raw_status_high', and `raw_status_low' with plain integers, and move
+       them to the end of the structure.
+
+       * alloc.c (allocate_process): Use PSEUDOVECSIZE to initialize the
+       pseudovector's size field so only the Lisp_Object fields get GC'd.
+
+       * process.c (update_status, make_process, Fdelete_process)
+       (Fprocess_status, list_processes_1, start_process_unwind)
+       (create_process, Fmake_network_process, server_accept_connection)
+       (wait_reading_process_output, send_process, Fprocess_running_child_p)
+       (process_send_signal, proc_encode_coding_system, Fprocess_send_eof)
+       (sigchld_handler, status_notify): Adjust to new non-Lisp fields for
+       `pid' and `raw_status'.
+       (Fprocess_id, Fsignal_process): Same, and additionally use floats when
+       representing PIDs that are larger than most-positive-fixnum.
+
+       * keymap.c (describe_map): Only use XINT if we checked INTEGERP.
+
+       * lisp.h (OFFSETOF, PSEUDOVECSIZE): New macros.
+
 2006-04-08  Eli Zaretskii  <eliz@gnu.org>
 
        * w32fns.c (Fx_show_tip): Add 3 to the 5th arg of SetWindowPos.
index e3b65c1..5b42a00 100644 (file)
@@ -3003,13 +3003,17 @@ allocate_frame ()
 struct Lisp_Process *
 allocate_process ()
 {
-  EMACS_INT len = VECSIZE (struct Lisp_Process);
-  struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_PROCESS);
+  /* Memory-footprint of the object in nb of Lisp_Object fields.  */
+  EMACS_INT memlen = VECSIZE (struct Lisp_Process);
+  /* Size if we only count the actual Lisp_Object fields (which need to be
+     traced by the GC).  */
+  EMACS_INT lisplen = PSEUDOVECSIZE (struct Lisp_Process, pid);
+  struct Lisp_Vector *v = allocate_vectorlike (memlen, MEM_TYPE_PROCESS);
   EMACS_INT i;
 
-  for (i = 0; i < len; ++i)
+  for (i = 0; i < lisplen; ++i)
     v->contents[i] = Qnil;
-  v->size = len;
+  v->size = lisplen;
 
   return (struct Lisp_Process *) v;
 }
@@ -5558,6 +5562,10 @@ mark_object (arg)
          if (size & PSEUDOVECTOR_FLAG)
            size &= PSEUDOVECTOR_SIZE_MASK;
 
+         /* Note that this size is not the memory-footprint size, but only
+            the number of Lisp_Object fields that we should trace.
+            The distinction is used e.g. by Lisp_Process which places extra
+            non-Lisp_Object fields at the end of the structure.  */
          for (i = 0; i < size; i++) /* and then mark its elements */
            mark_object (ptr->contents[i]);
        }
index 66cb227..08c515d 100644 (file)
@@ -414,10 +414,10 @@ update_status (p)
      struct Lisp_Process *p;
 {
   union { int i; WAITTYPE wt; } u;
-  u.i = XFASTINT (p->raw_status_low) + (XFASTINT (p->raw_status_high) << 16);
+  eassert (p->raw_status_new);
+  u.i = p->raw_status;
   p->status = status_convert (u.wt);
-  p->raw_status_low = Qnil;
-  p->raw_status_high = Qnil;
+  p->raw_status_new = 0;
 }
 
 /*  Convert a process status word in Unix format to
@@ -619,11 +619,10 @@ make_process (name)
 
   XSETINT (p->infd, -1);
   XSETINT (p->outfd, -1);
-  XSETFASTINT (p->pid, 0);
   XSETFASTINT (p->tick, 0);
   XSETFASTINT (p->update_tick, 0);
-  p->raw_status_low = Qnil;
-  p->raw_status_high = Qnil;
+  p->pid = 0;
+  p->raw_status_new = 0;
   p->status = Qrun;
   p->mark = Fmake_marker ();
 
@@ -789,8 +788,7 @@ nil, indicating the current buffer's process.  */)
   process = get_process (process);
   p = XPROCESS (process);
 
-  p->raw_status_low = Qnil;
-  p->raw_status_high = Qnil;
+  p->raw_status_new = 0;
   if (NETCONN1_P (p))
     {
       p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
@@ -840,7 +838,7 @@ nil, indicating the current buffer's process.  */)
     return process;
 
   p = XPROCESS (process);
-  if (!NILP (p->raw_status_low))
+  if (p->raw_status_new)
     update_status (p);
   status = p->status;
   if (CONSP (status))
@@ -865,7 +863,7 @@ If PROCESS has not yet exited or died, return 0.  */)
      register Lisp_Object process;
 {
   CHECK_PROCESS (process);
-  if (!NILP (XPROCESS (process)->raw_status_low))
+  if (XPROCESS (process)->raw_status_new)
     update_status (XPROCESS (process));
   if (CONSP (XPROCESS (process)->status))
     return XCAR (XCDR (XPROCESS (process)->status));
@@ -880,7 +878,9 @@ For a network connection, this value is nil.  */)
      register Lisp_Object process;
 {
   CHECK_PROCESS (process);
-  return XPROCESS (process)->pid;
+  return (XPROCESS (process)->pid
+         ? make_fixnum_or_float (XPROCESS (process)->pid)
+         : Qnil);
 }
 
 DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
@@ -1362,7 +1362,7 @@ list_processes_1 (query_only)
       Finsert (1, &p->name);
       Findent_to (i_status, minspace);
 
-      if (!NILP (p->raw_status_low))
+      if (p->raw_status_new)
        update_status (p);
       symbol = p->status;
       if (CONSP (p->status))
@@ -1734,7 +1734,7 @@ start_process_unwind (proc)
     abort ();
 
   /* Was PROC started successfully?  */
-  if (XINT (XPROCESS (proc)->pid) <= 0)
+  if (XPROCESS (proc)->pid <= 0)
     remove_process (proc);
 
   return Qnil;
@@ -1945,7 +1945,7 @@ create_process (process, new_argv, current_dir)
      in the table after this function has returned; if it does
      it might cause call-process to hang and subsequent asynchronous
      processes to get their return values scrambled.  */
-  XSETINT (XPROCESS (process)->pid, -1);
+  XPROCESS (process)->pid = -1;
 
   BLOCK_INPUT;
 
@@ -2136,7 +2136,7 @@ create_process (process, new_argv, current_dir)
   else
     {
       /* vfork succeeded.  */
-      XSETFASTINT (XPROCESS (process)->pid, pid);
+      XPROCESS (process)->pid = pid;
 
 #ifdef WINDOWSNT
       register_child (pid, inchannel);
@@ -3349,7 +3349,7 @@ usage: (make-network-process &rest ARGS)  */)
     p->kill_without_query = Qt;
   if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
     p->command = Qt;
-  p->pid = Qnil;
+  p->pid = 0;
   XSETINT (p->infd, inch);
   XSETINT (p->outfd, outch);
   if (is_server && socktype == SOCK_STREAM)
@@ -4065,7 +4065,7 @@ server_accept_connection (server, channel)
   p->sentinel = ps->sentinel;
   p->filter = ps->filter;
   p->command = Qnil;
-  p->pid = Qnil;
+  p->pid = 0;
   XSETINT (p->infd, s);
   XSETINT (p->outfd, s);
   p->status = Qrun;
@@ -4365,9 +4365,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
 
       /* Don't wait for output from a non-running process.  Just
          read whatever data has already been received.  */
-      if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
+      if (wait_proc && wait_proc->raw_status_new)
        update_status (wait_proc);
-      if (wait_proc != 0
+      if (wait_proc
          && ! EQ (wait_proc->status, Qrun)
          && ! EQ (wait_proc->status, Qconnect))
        {
@@ -4751,7 +4751,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                  /* Preserve status of processes already terminated.  */
                  XSETINT (XPROCESS (proc)->tick, ++process_tick);
                  deactivate_process (proc);
-                 if (!NILP (XPROCESS (proc)->raw_status_low))
+                 if (XPROCESS (proc)->raw_status_new)
                    update_status (XPROCESS (proc));
                  if (EQ (XPROCESS (proc)->status, Qrun))
                    XPROCESS (proc)->status
@@ -5288,7 +5288,7 @@ send_process (proc, buf, len, object)
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
 #endif /* VMS */
 
-  if (! NILP (p->raw_status_low))
+  if (p->raw_status_new)
     update_status (p);
   if (! EQ (p->status, Qrun))
     error ("Process %s not running", SDATA (p->name));
@@ -5552,8 +5552,7 @@ send_process (proc, buf, len, object)
       proc = process_sent_to;
       p = XPROCESS (proc);
 #endif
-      p->raw_status_low = Qnil;
-      p->raw_status_high = Qnil;
+      p->raw_status_new = 0;
       p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
       XSETINT (p->tick, ++process_tick);
       deactivate_process (proc);
@@ -5668,7 +5667,7 @@ return t unconditionally.  */)
 
   gid = emacs_get_tty_pgrp (p);
 
-  if (gid == XFASTINT (p->pid))
+  if (gid == p->pid)
     return Qnil;
   return Qt;
 }
@@ -5715,7 +5714,7 @@ process_send_signal (process, signo, current_group, nomsg)
   /* If we are using pgrps, get a pgrp number and make it negative.  */
   if (NILP (current_group))
     /* Send the signal to the shell's process group.  */
-    gid = XFASTINT (p->pid);
+    gid = p->pid;
   else
     {
 #ifdef SIGNALS_VIA_CHARACTERS
@@ -5834,7 +5833,7 @@ process_send_signal (process, signo, current_group, nomsg)
       if (gid == -1)
        /* If we can't get the information, assume
           the shell owns the tty.  */
-       gid = XFASTINT (p->pid);
+       gid = p->pid;
 
       /* It is not clear whether anything really can set GID to -1.
         Perhaps on some system one of those ioctls can or could do so.
@@ -5844,12 +5843,12 @@ process_send_signal (process, signo, current_group, nomsg)
 #else  /* ! defined (TIOCGPGRP ) */
       /* Can't select pgrps on this system, so we know that
         the child itself heads the pgrp.  */
-      gid = XFASTINT (p->pid);
+      gid = p->pid;
 #endif /* ! defined (TIOCGPGRP ) */
 
       /* If current_group is lambda, and the shell owns the terminal,
         don't send any signal.  */
-      if (EQ (current_group, Qlambda) && gid == XFASTINT (p->pid))
+      if (EQ (current_group, Qlambda) && gid == p->pid)
        return;
     }
 
@@ -5857,8 +5856,7 @@ process_send_signal (process, signo, current_group, nomsg)
     {
 #ifdef SIGCONT
     case SIGCONT:
-      p->raw_status_low = Qnil;
-      p->raw_status_high = Qnil;
+      p->raw_status_new = 0;
       p->status = Qrun;
       XSETINT (p->tick, ++process_tick);
       if (!nomsg)
@@ -5877,7 +5875,7 @@ process_send_signal (process, signo, current_group, nomsg)
 #endif
     case SIGKILL:
 #ifdef VMS
-      sys$forcex (&(XFASTINT (p->pid)), 0, 1);
+      sys$forcex (&(p->pid), 0, 1);
       whoosh:
 #endif
       flush_pending_output (XINT (p->infd));
@@ -5889,7 +5887,7 @@ process_send_signal (process, signo, current_group, nomsg)
      obvious alternative.  */
   if (no_pgrp)
     {
-      kill (XFASTINT (p->pid), signo);
+      kill (p->pid, signo);
       return;
     }
 
@@ -5902,7 +5900,7 @@ process_send_signal (process, signo, current_group, nomsg)
     }
   else
     {
-      gid = - XFASTINT (p->pid);
+      gid = - p->pid;
       kill (gid, signo);
     }
 #else /* ! defined (TIOCSIGSEND) */
@@ -6022,11 +6020,17 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
      (process, sigcode)
      Lisp_Object process, sigcode;
 {
-  Lisp_Object pid;
+  pid_t pid;
 
   if (INTEGERP (process))
     {
-      pid = process;
+      pid = XINT (process);
+      goto got_it;
+    }
+
+  if (FLOATP (process))
+    {
+      pid = (pid_t) XFLOAT (process);
       goto got_it;
     }
 
@@ -6035,8 +6039,8 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
       Lisp_Object tem;
       if (tem = Fget_process (process), NILP (tem))
        {
-         pid = Fstring_to_number (process, make_number (10));
-         if (XINT (pid) != 0)
+         pid = XINT (Fstring_to_number (process, make_number (10)));
+         if (pid > 0)
            goto got_it;
        }
       process = tem;
@@ -6049,7 +6053,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
 
   CHECK_PROCESS (process);
   pid = XPROCESS (process)->pid;
-  if (!INTEGERP (pid) || XINT (pid) <= 0)
+  if (pid <= 0)
     error ("Cannot signal process %s", SDATA (XPROCESS (process)->name));
 
  got_it:
@@ -6168,7 +6172,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
 
 #undef handle_signal
 
-  return make_number (kill (XINT (pid), XINT (sigcode)));
+  return make_number (kill (pid, XINT (sigcode)));
 }
 
 DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
@@ -6192,7 +6196,7 @@ text to PROCESS after you call this function.  */)
   coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
 
   /* Make sure the process is really alive.  */
-  if (! NILP (XPROCESS (proc)->raw_status_low))
+  if (XPROCESS (proc)->raw_status_new)
     update_status (XPROCESS (proc));
   if (! EQ (XPROCESS (proc)->status, Qrun))
     error ("Process %s not running", SDATA (XPROCESS (proc)->name));
@@ -6217,7 +6221,7 @@ text to PROCESS after you call this function.  */)
         for communication with the subprocess, call shutdown to cause EOF.
         (In some old system, shutdown to socketpair doesn't work.
         Then we just can't win.)  */
-      if (NILP (XPROCESS (proc)->pid)
+      if (XPROCESS (proc)->pid == 0
          || XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd))
        shutdown (XINT (XPROCESS (proc)->outfd), 1);
       /* In case of socketpair, outfd == infd, so don't close it.  */
@@ -6354,7 +6358,7 @@ sigchld_handler (signo)
        {
          proc = XCDR (XCAR (tail));
          p = XPROCESS (proc);
-         if (GC_EQ (p->childp, Qt) && XINT (p->pid) == pid)
+         if (GC_EQ (p->childp, Qt) && p->pid == pid)
            break;
          p = 0;
        }
@@ -6366,7 +6370,7 @@ sigchld_handler (signo)
          {
            proc = XCDR (XCAR (tail));
            p = XPROCESS (proc);
-           if (GC_INTEGERP (p->pid) && XINT (p->pid) == -1)
+           if (p->pid == -1)
              break;
            p = 0;
          }
@@ -6379,8 +6383,8 @@ sigchld_handler (signo)
 
          XSETINT (p->tick, ++process_tick);
          u.wt = w;
-         XSETINT (p->raw_status_low, u.i & 0xffff);
-         XSETINT (p->raw_status_high, u.i >> 16);
+         p->raw_status = u.i;
+         p->raw_status_new = 1;
 
          /* If process has terminated, stop waiting for its output.  */
          if ((WIFSIGNALED (w) || WIFEXITED (w))
@@ -6577,7 +6581,7 @@ status_notify (deleting_process)
          buffer = p->buffer;
 
          /* Get the text to use for the message.  */
-         if (!NILP (p->raw_status_low))
+         if (p->raw_status_new)
            update_status (p);
          msg = status_message (p);
 
index 9625556..c4b4281 100644 (file)
@@ -51,8 +51,6 @@ struct Lisp_Process
     Lisp_Object log;
     /* Buffer that output is going to */
     Lisp_Object buffer;
-    /* Number of this process */
-    Lisp_Object pid;
     /* t if this is a real child process.
        For a net connection, it is a plist based on the arguments to make-network-process.  */
     Lisp_Object childp;
@@ -63,10 +61,6 @@ struct Lisp_Process
     /* Non-nil means kill silently if Emacs is exited.
        This is the inverse of the `query-on-exit' flag.  */
     Lisp_Object kill_without_query;
-    /* Record the process status in the raw form in which it comes from `wait'.
-       This is to avoid consing in a signal handler.  */
-    Lisp_Object raw_status_low;
-    Lisp_Object raw_status_high;
     /* Symbol indicating status of process.
        This may be a symbol: run, open, or closed.
        Or it may be a list, whose car is stop, exit or signal
@@ -112,6 +106,19 @@ struct Lisp_Process
     Lisp_Object read_output_delay;
     /* Skip reading this process on next read.  */
     Lisp_Object read_output_skip;
+
+    /* After this point, there are no Lisp_Objects any more.  */
+
+    /* Number of this process.
+       allocate_process assumes this is the first non-Lisp_Object field.
+       A value 0 is used for pseudo-processes such as network connections.  */
+    pid_t pid;
+    /* Record the process status in the raw form in which it comes from `wait'.
+       This is to avoid consing in a signal handler.  The `raw_status_new'
+       flag indicates that `raw_status' contains a new status that still
+       needs to be synced to `status'.  */
+    int raw_status_new : 1;
+    int raw_status;
 };
 
 /* Every field in the preceding structure except for the first two