emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] test-concurrency ae31a7f 2/2: Merge with remote rep


From: Tino Calancha
Subject: [Emacs-diffs] test-concurrency ae31a7f 2/2: Merge with remote rep
Date: Thu, 15 Dec 2016 06:03:34 +0000 (UTC)

branch: test-concurrency
commit ae31a7fac5c1cb8d5d3cb3238d15a5e3b791fd69
Merge: afd162d 828b456
Author: Tino Calancha <address@hidden>
Commit: Tino Calancha <address@hidden>

    Merge with remote rep
---
 doc/lispref/elisp.texi   |    3 ++
 doc/lispref/objects.texi |   69 ++++++++++++++++++++++++++++++++++++++++++++
 src/lisp.h               |    2 ++
 src/regex.c              |    1 +
 src/thread.c             |   71 +++++++++++++++++++++++-----------------------
 src/xgselect.c           |    3 ++
 6 files changed, 114 insertions(+), 35 deletions(-)

diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 415dbe6..4a53a0c 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -349,6 +349,9 @@ Editing Types
 * Window Configuration Type::  Recording the way a frame is subdivided.
 * Frame Configuration Type::   Recording the status of all frames.
 * Process Type::            A subprocess of Emacs running on the underlying OS.
+* Thread Type::             A thread of Emacs Lisp execution.
+* Mutex Type::              An exclusive lock for thread synchronization.
+* Condition Variable Type::    Condition variable for thread synchronization.
 * Stream Type::             Receive or send characters.
 * Keymap Type::             What function a keystroke invokes.
 * Overlay Type::            How an overlay is represented.
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index a76fbb1..5e608bc 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -1410,6 +1410,9 @@ editing.
 * Window Configuration Type::   Recording the way a frame is subdivided.
 * Frame Configuration Type::    Recording the status of all frames.
 * Process Type::        A subprocess of Emacs running on the underlying OS.
+* Thread Type::         A thread of Emacs Lisp execution.
+* Mutex Type::          An exclusive lock for thread synchronization.
+* Condition Variable Type::     Condition variable for thread synchronization.
 * Stream Type::         Receive or send characters.
 * Keymap Type::         What function a keystroke invokes.
 * Overlay Type::        How an overlay is represented.
@@ -1625,6 +1628,63 @@ giving the name of the process:
 return information about, send input or signals to, and receive output
 from processes.
 
address@hidden Thread Type
address@hidden Thread Type
+
+  A @dfn{thread} in Emacs represents a separate thread of Emacs Lisp
+execution.  It runs its own Lisp program, has its own current buffer,
+and can have subprocesses locked to it, i.e.@: subprocesses whose
+output only this thread can accept.  @xref{Threads}.
+
+  Thread objects have no read syntax.  They print in hash notation,
+giving the name of the thread (if it has been given a name) or its
+address in core:
+
address@hidden
address@hidden
+(all-threads)
+    @result{} (#<thread 0176fc40>)
address@hidden group
address@hidden example
+
address@hidden Mutex Type
address@hidden Mutex Type
+
+  A @dfn{mutex} is an exclusive lock that threads can own and disown,
+in order to synchronize between them.  @xref{Mutexes}.
+
+  Mutex objects have no read syntax.  They print in hash notation,
+giving the name of the mutex (if it has been given a name) or its
+address in core:
+
address@hidden
address@hidden
+(make-mutex "my-mutex")
+    @result{} #<mutex my-mutex>
+(make-mutex)
+    @result{} #<mutex 01c7e4e0>
address@hidden group
address@hidden example
+
address@hidden Condition Variable Type
address@hidden Condition Variable Type
+
+  A @dfn{condition variable} is a device for a more complex thread
+synchronization than the one supported by a mutex.  A thread can wait
+on a condition variable, to be woken up when some other thread
+notifies the condition.
+
+  Condition variable objects have no read syntax.  They print in hash
+notation, giving the name of the condition variable (if it has been
+given a name) or its address in core:
+
address@hidden
address@hidden
+(make-condition-variable (make-mutex))
+    @result{} #<condvar 01c45ae8>
address@hidden group
address@hidden example
+
 @node Stream Type
 @subsection Stream Type
 
@@ -1830,6 +1890,9 @@ with references to further information.
 @item commandp
 @xref{Interactive Call, commandp}.
 
address@hidden condition-variable-p
address@hidden Variables, condition-variable-p}.
+
 @item consp
 @xref{List-related Predicates, consp}.
 
@@ -1875,6 +1938,9 @@ with references to further information.
 @item markerp
 @xref{Predicates on Markers, markerp}.
 
address@hidden mutexp
address@hidden, mutexp}.
+
 @item wholenump
 @xref{Predicates on Numbers, wholenump}.
 
@@ -1908,6 +1974,9 @@ with references to further information.
 @item syntax-table-p
 @xref{Syntax Tables, syntax-table-p}.
 
address@hidden threadp
address@hidden Thread Functions, threadp}.
+
 @item vectorp
 @xref{Vectors, vectorp}.
 
diff --git a/src/lisp.h b/src/lisp.h
index 72ea50d..3c7c3dd 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -845,6 +845,7 @@ enum pvec_type
   PVEC_THREAD,
   PVEC_MUTEX,
   PVEC_CONDVAR,
+
   /* These should be last, check internal_equal to see why.  */
   PVEC_COMPILED,
   PVEC_CHAR_TABLE,
@@ -3229,6 +3230,7 @@ union specbinding
     } bt;
   };
 
+/* These 3 are defined as macros in thread.h.  */
 /* extern union specbinding *specpdl; */
 /* extern union specbinding *specpdl_ptr; */
 /* extern ptrdiff_t specpdl_size; */
diff --git a/src/regex.c b/src/regex.c
index e7231d3..f1686cf 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -1140,6 +1140,7 @@ print_double_string (re_char *where, re_char *string1, 
ssize_t size1,
 #endif /* not DEBUG */
 
 #ifndef emacs
+
 /* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
    also be assigned to arbitrarily: each pattern buffer stores its own
    syntax, so it can be changed between regex compilations.  */
diff --git a/src/thread.c b/src/thread.c
index dda2629..ae2ce3d 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -144,7 +144,7 @@ static int
 lisp_mutex_unlock (lisp_mutex_t *mutex)
 {
   if (mutex->owner != current_thread)
-    error ("blah");
+    error ("Cannot unlock mutex owned by another thread");
 
   if (--mutex->count > 0)
     return 0;
@@ -301,7 +301,7 @@ finalize_one_mutex (struct Lisp_Mutex *mutex)
 DEFUN ("make-condition-variable",
        Fmake_condition_variable, Smake_condition_variable,
        1, 2, 0,
-       doc: /* Make a condition variable.
+       doc: /* Make a condition variable associated with MUTEX.
 A condition variable provides a way for a thread to sleep while
 waiting for a state change.
 
@@ -355,27 +355,27 @@ condition_wait_callback (void *arg)
 }
 
 DEFUN ("condition-wait", Fcondition_wait, Scondition_wait, 1, 1, 0,
-       doc: /* Wait for the condition variable to be notified.
-CONDITION is the condition variable to wait on.
+       doc: /* Wait for the condition variable COND to be notified.
+COND is the condition variable to wait on.
 
-The mutex associated with CONDITION must be held when this is called.
+The mutex associated with COND must be held when this is called.
 It is an error if it is not held.
 
-This releases the mutex and waits for CONDITION to be notified or for
+This releases the mutex and waits for COND to be notified or for
 this thread to be signalled with `thread-signal'.  When
-`condition-wait' returns, the mutex will again be locked by this
-thread.  */)
-  (Lisp_Object condition)
+`condition-wait' returns, COND's mutex will again be locked by
+this thread.  */)
+  (Lisp_Object cond)
 {
   struct Lisp_CondVar *cvar;
   struct Lisp_Mutex *mutex;
 
-  CHECK_CONDVAR (condition);
-  cvar = XCONDVAR (condition);
+  CHECK_CONDVAR (cond);
+  cvar = XCONDVAR (cond);
 
   mutex = XMUTEX (cvar->mutex);
   if (!lisp_mutex_owned_p (&mutex->mutex))
-    error ("fixme");
+    error ("Condition variable's mutex is not held by current thread");
 
   flush_stack_call_func (condition_wait_callback, cvar);
 
@@ -409,28 +409,28 @@ condition_notify_callback (void *arg)
 }
 
 DEFUN ("condition-notify", Fcondition_notify, Scondition_notify, 1, 2, 0,
-       doc: /* Notify a condition variable.
-This wakes a thread waiting on CONDITION.
+       doc: /* Notify COND, a condition variable.
+This wakes a thread waiting on COND.
 If ALL is non-nil, all waiting threads are awoken.
 
-The mutex associated with CONDITION must be held when this is called.
+The mutex associated with COND must be held when this is called.
 It is an error if it is not held.
 
-This releases the mutex when notifying CONDITION.  When
+This releases COND's mutex when notifying COND.  When
 `condition-notify' returns, the mutex will again be locked by this
 thread.  */)
-  (Lisp_Object condition, Lisp_Object all)
+  (Lisp_Object cond, Lisp_Object all)
 {
   struct Lisp_CondVar *cvar;
   struct Lisp_Mutex *mutex;
   struct notify_args args;
 
-  CHECK_CONDVAR (condition);
-  cvar = XCONDVAR (condition);
+  CHECK_CONDVAR (cond);
+  cvar = XCONDVAR (cond);
 
   mutex = XMUTEX (cvar->mutex);
   if (!lisp_mutex_owned_p (&mutex->mutex))
-    error ("fixme");
+    error ("Condition variable's mutex is not held by current thread");
 
   args.cvar = cvar;
   args.all = !NILP (all);
@@ -440,26 +440,26 @@ thread.  */)
 }
 
 DEFUN ("condition-mutex", Fcondition_mutex, Scondition_mutex, 1, 1, 0,
-       doc: /* Return the mutex associated with CONDITION.  */)
-  (Lisp_Object condition)
+       doc: /* Return the mutex associated with condition variable COND.  */)
+  (Lisp_Object cond)
 {
   struct Lisp_CondVar *cvar;
 
-  CHECK_CONDVAR (condition);
-  cvar = XCONDVAR (condition);
+  CHECK_CONDVAR (cond);
+  cvar = XCONDVAR (cond);
 
   return cvar->mutex;
 }
 
 DEFUN ("condition-name", Fcondition_name, Scondition_name, 1, 1, 0,
-       doc: /* Return the name of CONDITION.
-If no name was given when CONDITION was created, return nil.  */)
-  (Lisp_Object condition)
+       doc: /* Return the name of condition variable COND.
+If no name was given when COND was created, return nil.  */)
+  (Lisp_Object cond)
 {
   struct Lisp_CondVar *cvar;
 
-  CHECK_CONDVAR (condition);
-  cvar = XCONDVAR (condition);
+  CHECK_CONDVAR (cond);
+  cvar = XCONDVAR (cond);
 
   return cvar->name;
 }
@@ -540,7 +540,7 @@ mark_one_thread (struct thread_state *thread)
 
   mark_object (thread->m_last_thing_searched);
 
-  if (thread->m_saved_last_thing_searched)
+  if (!NILP (thread->m_saved_last_thing_searched))
     mark_object (thread->m_saved_last_thing_searched);
 }
 
@@ -678,7 +678,7 @@ finalize_one_thread (struct thread_state *state)
 DEFUN ("make-thread", Fmake_thread, Smake_thread, 1, 2, 0,
        doc: /* Start a new thread and run FUNCTION in it.
 When the function exits, the thread dies.
-If NAME is given, it names the new thread.  */)
+If NAME is given, it must be a string; it names the new thread.  */)
   (Lisp_Object function, Lisp_Object name)
 {
   sys_thread_t thr;
@@ -843,8 +843,9 @@ thread_join_callback (void *arg)
 }
 
 DEFUN ("thread-join", Fthread_join, Sthread_join, 1, 1, 0,
-       doc: /* Wait for a thread to exit.
-This blocks the current thread until THREAD exits.
+       doc: /* Wait for THREAD to exit.
+This blocks the current thread until THREAD exits or until
+the current thread is signaled.
 It is an error for a thread to try to join itself.  */)
   (Lisp_Object thread)
 {
@@ -854,7 +855,7 @@ It is an error for a thread to try to join itself.  */)
   tstate = XTHREAD (thread);
 
   if (tstate == current_thread)
-    error ("cannot join current thread");
+    error ("Cannot join current thread");
 
   if (thread_alive_p (tstate))
     flush_stack_call_func (thread_join_callback, tstate);
@@ -863,7 +864,7 @@ It is an error for a thread to try to join itself.  */)
 }
 
 DEFUN ("all-threads", Fall_threads, Sall_threads, 0, 0, 0,
-       doc: /* Return a list of all threads.  */)
+       doc: /* Return a list of all the live threads.  */)
   (void)
 {
   Lisp_Object result = Qnil;
diff --git a/src/xgselect.c b/src/xgselect.c
index e418e1a..2f23764 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -76,6 +76,9 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set 
*efds,
 
   if (gfds_size < n_gfds)
     {
+      /* Avoid using SAFE_NALLOCA, as that implicitly refers to the
+        current thread.  Using xnmalloc avoids thread-switching
+        problems here.  */
       gfds = xnmalloc (n_gfds, sizeof *gfds);
       must_free = 1;
       gfds_size = n_gfds;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]