aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/emacs.c1
-rw-r--r--src/lisp.h2
-rw-r--r--src/systhread.c189
-rw-r--r--src/systhread.h80
-rw-r--r--src/thread.c9
-rw-r--r--src/thread.h4
7 files changed, 286 insertions, 1 deletions
diff --git a/src/Makefile.in b/src/Makefile.in
index 2d1bdd097ef..01034ca98d5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -336,7 +336,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
336 eval.o floatfns.o fns.o font.o print.o lread.o \ 336 eval.o floatfns.o fns.o font.o print.o lread.o \
337 syntax.o $(UNEXEC_OBJ) bytecode.o \ 337 syntax.o $(UNEXEC_OBJ) bytecode.o \
338 process.o gnutls.o callproc.o \ 338 process.o gnutls.o callproc.o \
339 region-cache.o sound.o atimer.o thread.o \ 339 region-cache.o sound.o atimer.o thread.o systhread.o \
340 doprnt.o intervals.o textprop.o composite.o xml.o \ 340 doprnt.o intervals.o textprop.o composite.o xml.o \
341 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) 341 $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
342obj = $(base_obj) $(NS_OBJC_OBJ) 342obj = $(base_obj) $(NS_OBJC_OBJ)
diff --git a/src/emacs.c b/src/emacs.c
index e1acd365e29..443fe594795 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1270,6 +1270,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1270 } 1270 }
1271 1271
1272 init_alloc (); 1272 init_alloc ();
1273 init_threads ();
1273 1274
1274 if (do_initial_setlocale) 1275 if (do_initial_setlocale)
1275 { 1276 {
diff --git a/src/lisp.h b/src/lisp.h
index a6665320da6..b0ed9be9f07 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -29,6 +29,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
29 29
30#include <intprops.h> 30#include <intprops.h>
31 31
32#include "systhread.h"
33
32INLINE_HEADER_BEGIN 34INLINE_HEADER_BEGIN
33#ifndef LISP_INLINE 35#ifndef LISP_INLINE
34# define LISP_INLINE INLINE 36# define LISP_INLINE INLINE
diff --git a/src/systhread.c b/src/systhread.c
new file mode 100644
index 00000000000..b7147c4fc95
--- /dev/null
+++ b/src/systhread.c
@@ -0,0 +1,189 @@
1/* System thread definitions
2 Copyright (C) 2012 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19#include <config.h>
20#include <setjmp.h>
21#include "lisp.h"
22
23#ifdef HAVE_PTHREAD
24
25#include <sched.h>
26
27void
28sys_mutex_init (sys_mutex_t *mutex)
29{
30 pthread_mutex_init (mutex, NULL);
31}
32
33void
34sys_mutex_lock (sys_mutex_t *mutex)
35{
36 pthread_mutex_lock (mutex);
37}
38
39void
40sys_mutex_unlock (sys_mutex_t *mutex)
41{
42 pthread_mutex_unlock (mutex);
43}
44
45void
46sys_mutex_destroy (sys_mutex_t *mutex)
47{
48 pthread_mutex_destroy (mutex);
49}
50
51void
52sys_cond_init (sys_cond_t *cond)
53{
54 pthread_cond_init (cond, NULL);
55}
56
57void
58sys_cond_wait (sys_cond_t *cond, sys_mutex_t *mutex)
59{
60 pthread_cond_wait (cond, mutex);
61}
62
63void
64sys_cond_signal (sys_cond_t *cond)
65{
66 pthread_cond_signal (cond);
67}
68
69void
70sys_cond_broadcast (sys_cond_t *cond)
71{
72 pthread_cond_broadcast (cond);
73}
74
75void
76sys_cond_destroy (sys_cond_t *cond)
77{
78 pthread_cond_destroy (cond);
79}
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 while (mutex->owner != NULL /* && EQ (self->error_symbol, Qnil) */)
109 pthread_cond_wait (&mutex->condition, &global_lock);
110
111#if 0
112 if (!EQ (self->error_symbol, Qnil))
113 {
114 Lisp_Object error_symbol = self->error_symbol;
115 Lisp_Object data = self->error_data;
116 self->error_symbol = Qnil;
117 self->error_data = Qnil;
118 Fsignal (error_symbol, error_data);
119 }
120#endif
121
122 mutex->owner = self;
123 mutex->count = 1;
124}
125
126void
127lisp_mutex_unlock (lisp_mutex_t *mutex)
128{
129 struct thread_state *self = current_thread;
130
131 if (mutex->owner != current_thread)
132 error ("blah");
133
134 if (--mutex->count > 0)
135 return;
136
137 mutex->owner = NULL;
138 pthread_cond_broadcast (&mutex->condition);
139
140 post_acquire_global_lock (self);
141}
142
143void
144lisp_mutex_destroy (lisp_mutex_t *mutex)
145{
146 sys_cond_destroy (&mutex->condition);
147}
148
149sys_thread_t
150sys_thread_self (void)
151{
152 return pthread_self ();
153}
154
155int
156sys_thread_equal (sys_thread_t one, sys_thread_t two)
157{
158 return pthread_equal (one, two);
159}
160
161int
162sys_thread_create (sys_thread_t *thread_ptr, thread_creation_function *func,
163 void *arg)
164{
165 pthread_attr_t attr;
166 int result = 0;
167
168 if (pthread_attr_init (&attr))
169 return 0;
170
171 if (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED))
172 result = pthread_create (thread_ptr, &attr, func, arg) == 0;
173
174 pthread_attr_destroy (&attr);
175
176 return result;
177}
178
179void
180sys_thread_yield (void)
181{
182 sched_yield ();
183}
184
185#else
186
187#error port me
188
189#endif
diff --git a/src/systhread.h b/src/systhread.h
new file mode 100644
index 00000000000..bf9358c21c6
--- /dev/null
+++ b/src/systhread.h
@@ -0,0 +1,80 @@
1/* System thread definitions
2 Copyright (C) 2012 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19#ifndef SYSTHREAD_H
20#define SYSTHREAD_H
21
22#ifdef HAVE_PTHREAD
23
24#include <pthread.h>
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
40 GIL. */
41typedef pthread_mutex_t sys_mutex_t;
42
43typedef pthread_cond_t sys_cond_t;
44
45/* A system thread. */
46typedef pthread_t sys_thread_t;
47
48#else
49
50#error port me
51
52#endif
53
54typedef void *(thread_creation_function) (void *);
55
56extern void sys_mutex_init (sys_mutex_t *);
57extern void sys_mutex_lock (sys_mutex_t *);
58extern void sys_mutex_unlock (sys_mutex_t *);
59extern void sys_mutex_destroy (sys_mutex_t *);
60
61extern void sys_cond_init (sys_cond_t *);
62extern void sys_cond_wait (sys_cond_t *, sys_mutex_t *);
63extern void sys_cond_signal (sys_cond_t *);
64extern void sys_cond_broadcast (sys_cond_t *);
65extern void sys_cond_destroy (sys_cond_t *);
66
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);
73extern int sys_thread_equal (sys_thread_t, sys_thread_t);
74
75extern int sys_thread_create (sys_thread_t *, thread_creation_function *,
76 void *);
77
78extern void sys_thread_yield (void);
79
80#endif /* SYSTHREAD_H */
diff --git a/src/thread.c b/src/thread.c
index ba2d66320fa..19faa1bafae 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -27,6 +27,8 @@ struct thread_state *current_thread = &the_only_thread;
27 27
28struct thread_state *all_threads = &the_only_thread; 28struct thread_state *all_threads = &the_only_thread;
29 29
30sys_mutex_t global_lock;
31
30static void 32static void
31mark_one_thread (struct thread_state *thread) 33mark_one_thread (struct thread_state *thread)
32{ 34{
@@ -103,3 +105,10 @@ unmark_threads (void)
103 if (iter->m_byte_stack_list) 105 if (iter->m_byte_stack_list)
104 unmark_byte_stack (iter->m_byte_stack_list); 106 unmark_byte_stack (iter->m_byte_stack_list);
105} 107}
108
109void
110init_threads (void)
111{
112 sys_mutex_init (&global_lock);
113 sys_mutex_lock (&global_lock);
114}
diff --git a/src/thread.h b/src/thread.h
index 6d61d0e5fcf..020346b9af2 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -140,6 +140,10 @@ struct thread_state
140 140
141extern struct thread_state *current_thread; 141extern struct thread_state *current_thread;
142 142
143extern sys_mutex_t global_lock;
144
143extern void unmark_threads (void); 145extern void unmark_threads (void);
144 146
147extern void init_threads (void);
148
145#endif /* THREAD_H */ 149#endif /* THREAD_H */