aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Tromey2012-08-18 19:59:47 -0600
committerTom Tromey2012-08-18 19:59:47 -0600
commitb3c78ffa31af4fb96cc18da887e2f2a1e68f5e09 (patch)
tree18d4319fc883400ed308786357d5628e9e67d384 /src
parentf52cfea0dcea4ae9599d4a775901ca06a0517f56 (diff)
downloademacs-b3c78ffa31af4fb96cc18da887e2f2a1e68f5e09.tar.gz
emacs-b3c78ffa31af4fb96cc18da887e2f2a1e68f5e09.zip
refactor systhread.h
This refactors systhread.h to move the notion of a "lisp mutex" into thread.c. This lets us make make the global lock and post_acquire_global_lock static.
Diffstat (limited to 'src')
-rw-r--r--src/systhread.c61
-rw-r--r--src/systhread.h18
-rw-r--r--src/thread.c154
-rw-r--r--src/thread.h16
4 files changed, 121 insertions, 128 deletions
diff --git a/src/systhread.c b/src/systhread.c
index 968620bcd1c..666641c24da 100644
--- a/src/systhread.c
+++ b/src/systhread.c
@@ -78,67 +78,6 @@ sys_cond_destroy (sys_cond_t *cond)
78 pthread_cond_destroy (cond); 78 pthread_cond_destroy (cond);
79} 79}
80 80
81void
82lisp_mutex_init (lisp_mutex_t *mutex)
83{
84 mutex->owner = NULL;
85 mutex->count = 0;
86 /* A lisp "mutex" is really a condition variable. */
87 pthread_cond_init (&mutex->condition, NULL);
88}
89
90void
91lisp_mutex_lock (lisp_mutex_t *mutex)
92{
93 struct thread_state *self;
94
95 if (mutex->owner == NULL)
96 {
97 mutex->owner = current_thread;
98 mutex->count = 1;
99 return;
100 }
101 if (mutex->owner == current_thread)
102 {
103 ++mutex->count;
104 return;
105 }
106
107 self = current_thread;
108 self->wait_condvar = &mutex->condition;
109 while (mutex->owner != NULL && EQ (self->error_symbol, Qnil))
110 pthread_cond_wait (&mutex->condition, &global_lock);
111 self->wait_condvar = NULL;
112
113 post_acquire_global_lock (self);
114
115 mutex->owner = self;
116 mutex->count = 1;
117}
118
119void
120lisp_mutex_unlock (lisp_mutex_t *mutex)
121{
122 struct thread_state *self = current_thread;
123
124 if (mutex->owner != current_thread)
125 error ("blah");
126
127 if (--mutex->count > 0)
128 return;
129
130 mutex->owner = NULL;
131 pthread_cond_broadcast (&mutex->condition);
132
133 post_acquire_global_lock (self);
134}
135
136void
137lisp_mutex_destroy (lisp_mutex_t *mutex)
138{
139 sys_cond_destroy (&mutex->condition);
140}
141
142sys_thread_t 81sys_thread_t
143sys_thread_self (void) 82sys_thread_self (void)
144{ 83{
diff --git a/src/systhread.h b/src/systhread.h
index bf9358c21c6..790b385b7ff 100644
--- a/src/systhread.h
+++ b/src/systhread.h
@@ -23,19 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 23
24#include <pthread.h> 24#include <pthread.h>
25 25
26/* A mutex in lisp is represented by a pthread condition variable.
27 The pthread mutex associated with this condition variable is the
28 global lock.
29
30 Using a condition variable lets us implement interruptibility for
31 lisp mutexes. */
32typedef struct
33{
34 struct thread_state *owner;
35 unsigned int count;
36 pthread_cond_t condition;
37} lisp_mutex_t;
38
39/* A system mutex is just a pthread mutex. This is only used for the 26/* A system mutex is just a pthread mutex. This is only used for the
40 GIL. */ 27 GIL. */
41typedef pthread_mutex_t sys_mutex_t; 28typedef pthread_mutex_t sys_mutex_t;
@@ -64,11 +51,6 @@ extern void sys_cond_signal (sys_cond_t *);
64extern void sys_cond_broadcast (sys_cond_t *); 51extern void sys_cond_broadcast (sys_cond_t *);
65extern void sys_cond_destroy (sys_cond_t *); 52extern void sys_cond_destroy (sys_cond_t *);
66 53
67extern void lisp_mutex_init (lisp_mutex_t *);
68extern void lisp_mutex_lock (lisp_mutex_t *);
69extern void lisp_mutex_unlock (lisp_mutex_t *);
70extern void lisp_mutex_destroy (lisp_mutex_t *);
71
72extern sys_thread_t sys_thread_self (void); 54extern sys_thread_t sys_thread_self (void);
73extern int sys_thread_equal (sys_thread_t, sys_thread_t); 55extern int sys_thread_equal (sys_thread_t, sys_thread_t);
74 56
diff --git a/src/thread.c b/src/thread.c
index e8e43c5e402..9c39b84eb50 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -30,12 +30,119 @@ struct thread_state *current_thread = &primary_thread;
30 30
31static struct thread_state *all_threads = &primary_thread; 31static struct thread_state *all_threads = &primary_thread;
32 32
33sys_mutex_t global_lock; 33static sys_mutex_t global_lock;
34 34
35Lisp_Object Qthreadp, Qmutexp; 35Lisp_Object Qthreadp, Qmutexp;
36 36
37 37
38 38
39static void
40release_global_lock (void)
41{
42 sys_mutex_unlock (&global_lock);
43}
44
45/* You must call this after acquiring the global lock.
46 acquire_global_lock does it for you. */
47static void
48post_acquire_global_lock (struct thread_state *self)
49{
50 Lisp_Object buffer;
51
52 if (self != current_thread)
53 {
54 unbind_for_thread_switch ();
55 current_thread = self;
56 rebind_for_thread_switch ();
57 }
58
59 /* We need special handling to re-set the buffer. */
60 XSETBUFFER (buffer, self->m_current_buffer);
61 self->m_current_buffer = 0;
62 set_buffer_internal (XBUFFER (buffer));
63
64 if (!EQ (current_thread->error_symbol, Qnil))
65 {
66 Lisp_Object sym = current_thread->error_symbol;
67 Lisp_Object data = current_thread->error_data;
68
69 current_thread->error_symbol = Qnil;
70 current_thread->error_data = Qnil;
71 Fsignal (sym, data);
72 }
73}
74
75static void
76acquire_global_lock (struct thread_state *self)
77{
78 sys_mutex_lock (&global_lock);
79 post_acquire_global_lock (self);
80}
81
82
83
84static void
85lisp_mutex_init (lisp_mutex_t *mutex)
86{
87 mutex->owner = NULL;
88 mutex->count = 0;
89 sys_cond_init (&mutex->condition);
90}
91
92static void
93lisp_mutex_lock (lisp_mutex_t *mutex)
94{
95 struct thread_state *self;
96
97 if (mutex->owner == NULL)
98 {
99 mutex->owner = current_thread;
100 mutex->count = 1;
101 return;
102 }
103 if (mutex->owner == current_thread)
104 {
105 ++mutex->count;
106 return;
107 }
108
109 self = current_thread;
110 self->wait_condvar = &mutex->condition;
111 while (mutex->owner != NULL && EQ (self->error_symbol, Qnil))
112 sys_cond_wait (&mutex->condition, &global_lock);
113 self->wait_condvar = NULL;
114
115 post_acquire_global_lock (self);
116
117 mutex->owner = self;
118 mutex->count = 1;
119}
120
121static void
122lisp_mutex_unlock (lisp_mutex_t *mutex)
123{
124 struct thread_state *self = current_thread;
125
126 if (mutex->owner != current_thread)
127 error ("blah");
128
129 if (--mutex->count > 0)
130 return;
131
132 mutex->owner = NULL;
133 sys_cond_broadcast (&mutex->condition);
134
135 post_acquire_global_lock (self);
136}
137
138static void
139lisp_mutex_destroy (lisp_mutex_t *mutex)
140{
141 sys_cond_destroy (&mutex->condition);
142}
143
144
145
39DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0, 146DEFUN ("make-mutex", Fmake_mutex, Smake_mutex, 0, 1, 0,
40 doc: /* Create a mutex. 147 doc: /* Create a mutex.
41A mutex provides a synchronization point for threads. 148A mutex provides a synchronization point for threads.
@@ -146,51 +253,6 @@ finalize_one_mutex (struct Lisp_Mutex *mutex)
146 253
147 254
148 255
149static void
150release_global_lock (void)
151{
152 sys_mutex_unlock (&global_lock);
153}
154
155/* You must call this after acquiring the global lock.
156 acquire_global_lock does it for you. */
157void
158post_acquire_global_lock (struct thread_state *self)
159{
160 Lisp_Object buffer;
161
162 if (self != current_thread)
163 {
164 unbind_for_thread_switch ();
165 current_thread = self;
166 rebind_for_thread_switch ();
167 }
168
169 /* We need special handling to re-set the buffer. */
170 XSETBUFFER (buffer, self->m_current_buffer);
171 self->m_current_buffer = 0;
172 set_buffer_internal (XBUFFER (buffer));
173
174 if (!EQ (current_thread->error_symbol, Qnil))
175 {
176 Lisp_Object sym = current_thread->error_symbol;
177 Lisp_Object data = current_thread->error_data;
178
179 current_thread->error_symbol = Qnil;
180 current_thread->error_data = Qnil;
181 Fsignal (sym, data);
182 }
183}
184
185static void
186acquire_global_lock (struct thread_state *self)
187{
188 sys_mutex_lock (&global_lock);
189 post_acquire_global_lock (self);
190}
191
192
193
194struct select_args 256struct select_args
195{ 257{
196 select_func *func; 258 select_func *func;
diff --git a/src/thread.h b/src/thread.h
index 9db3c795653..32ef48f63ff 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -187,6 +187,19 @@ struct thread_state
187 struct thread_state *next_thread; 187 struct thread_state *next_thread;
188}; 188};
189 189
190/* A mutex in lisp is represented by a pthread condition variable.
191 The system mutex associated with this condition variable is the
192 global lock.
193
194 Using a condition variable lets us implement interruptibility for
195 lisp mutexes. */
196typedef struct
197{
198 struct thread_state *owner;
199 unsigned int count;
200 sys_cond_t condition;
201} lisp_mutex_t;
202
190struct Lisp_Mutex 203struct Lisp_Mutex
191{ 204{
192 struct vectorlike_header header; 205 struct vectorlike_header header;
@@ -198,9 +211,6 @@ struct Lisp_Mutex
198 211
199extern struct thread_state *current_thread; 212extern struct thread_state *current_thread;
200 213
201extern sys_mutex_t global_lock;
202extern void post_acquire_global_lock (struct thread_state *);
203
204extern void unmark_threads (void); 214extern void unmark_threads (void);
205extern void finalize_one_thread (struct thread_state *state); 215extern void finalize_one_thread (struct thread_state *state);
206extern void finalize_one_mutex (struct Lisp_Mutex *); 216extern void finalize_one_mutex (struct Lisp_Mutex *);