diff options
-rw-r--r-- | config.mak.in | 2 | ||||
-rw-r--r-- | configure.ac | 37 | ||||
-rw-r--r-- | gs/Makefile.in | 2 | ||||
-rw-r--r-- | gs/base/gp_psync.c | 70 | ||||
-rw-r--r-- | gs/configure.ac | 37 |
5 files changed, 108 insertions, 40 deletions
diff --git a/config.mak.in b/config.mak.in index ccb84aee8..d962dda20 100644 --- a/config.mak.in +++ b/config.mak.in | |||
@@ -17,7 +17,7 @@ CC=@CC@ | |||
17 | CCAUX=@CC@ | 17 | CCAUX=@CC@ |
18 | 18 | ||
19 | CONFDEFS?=@HAVE_MKSTEMP@ @HAVE_SSE2@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_SYS_TIME_H@ @HAVE_FSEEKO@ @HAVE_INTTYPES@ @HAVE_MKSTEMP64@ \ | 19 | CONFDEFS?=@HAVE_MKSTEMP@ @HAVE_SSE2@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_SYS_TIME_H@ @HAVE_FSEEKO@ @HAVE_INTTYPES@ @HAVE_MKSTEMP64@ \ |
20 | @HAVE_FILE64@ @HAVE_PREAD_PWRITE@ | 20 | @HAVE_FILE64@ @HAVE_PREAD_PWRITE@ @RECURSIVE_MUTEXATTR@ |
21 | 21 | ||
22 | ACCFLAGS?=@GCFLAGS@ | 22 | ACCFLAGS?=@GCFLAGS@ |
23 | 23 | ||
diff --git a/configure.ac b/configure.ac index 44b725256..5da03cab1 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -460,25 +460,36 @@ AC_SUBST(HAVE_PREAD_PWRITE) | |||
460 | SYNC="nosync" | 460 | SYNC="nosync" |
461 | PTHREAD_LIBS="" | 461 | PTHREAD_LIBS="" |
462 | 462 | ||
463 | # if you haven't got pread/pwrite, we can't use multithreading | 463 | AC_ARG_ENABLE([threading], AC_HELP_STRING([--disable-threading], |
464 | if test "x$HAVE_PREAD_PWRITE" != "x"; then | 464 | [disable support for multithreaded rendering])) |
465 | 465 | ||
466 | case `uname` in | ||
467 | MINGW*) | ||
468 | AC_MSG_WARN([disabling support for pthreads......]) | ||
469 | ;; | ||
470 | *) | ||
471 | AC_CHECK_LIB(pthread, pthread_create, [ | ||
472 | SYNC=posync; | ||
473 | PTHREAD_LIBS="-lpthread" | ||
474 | ]) | ||
475 | ;; | ||
476 | esac | ||
477 | 466 | ||
467 | # if you haven't got pread/pwrite, we can't use multithreading | ||
468 | if test "x$HAVE_PREAD_PWRITE" != "x"; then | ||
469 | if test "$enable_fontconfig" != "no"; then | ||
470 | case `uname` in | ||
471 | MINGW*) | ||
472 | AC_MSG_WARN([disabling support for pthreads......]) | ||
473 | ;; | ||
474 | *) | ||
475 | AC_CHECK_LIB(pthread, pthread_create, [ | ||
476 | SYNC=posync; | ||
477 | PTHREAD_LIBS="-lpthread" | ||
478 | ]) | ||
479 | AC_TRY_COMPILE([#include <pthread.h>], | ||
480 | [static int k = PTHREAD_MUTEX_RECURSIVE;], | ||
481 | [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE"], | ||
482 | [AC_TRY_COMPILE([#include <pthread.h>], | ||
483 | [static int k = PTHREAD_MUTEX_RECURSIVE_NP;], | ||
484 | [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE_NP"])]) | ||
485 | ;; | ||
486 | esac | ||
487 | fi | ||
478 | fi | 488 | fi |
479 | 489 | ||
480 | AC_SUBST(SYNC) | 490 | AC_SUBST(SYNC) |
481 | AC_SUBST(PTHREAD_LIBS) | 491 | AC_SUBST(PTHREAD_LIBS) |
492 | AC_SUBST(RECURSIVE_MUTEXATTR) | ||
482 | 493 | ||
483 | AC_PATH_X | 494 | AC_PATH_X |
484 | 495 | ||
diff --git a/gs/Makefile.in b/gs/Makefile.in index c13462266..68f3dc598 100644 --- a/gs/Makefile.in +++ b/gs/Makefile.in | |||
@@ -142,7 +142,7 @@ GENOPT= | |||
142 | # -DHAVE_SSE2 | 142 | # -DHAVE_SSE2 |
143 | # use sse2 intrinsics | 143 | # use sse2 intrinsics |
144 | 144 | ||
145 | CAPOPT= @HAVE_MKSTEMP@ @HAVE_FILE64@ @HAVE_FSEEKO@ @HAVE_MKSTEMP64@ @HAVE_FONTCONFIG@ @HAVE_LIBIDN@ @HAVE_SETLOCALE@ @HAVE_SSE2@ @HAVE_DBUS@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_STRERROR@ @HAVE_PREAD_PWRITE@ | 145 | CAPOPT= @HAVE_MKSTEMP@ @HAVE_FILE64@ @HAVE_FSEEKO@ @HAVE_MKSTEMP64@ @HAVE_FONTCONFIG@ @HAVE_LIBIDN@ @HAVE_SETLOCALE@ @HAVE_SSE2@ @HAVE_DBUS@ @HAVE_BSWAP32@ @HAVE_BYTESWAP_H@ @HAVE_STRERROR@ @HAVE_PREAD_PWRITE@ @RECURSIVE_MUTEXATTR@ |
146 | 146 | ||
147 | # Define the name of the executable file. | 147 | # Define the name of the executable file. |
148 | 148 | ||
diff --git a/gs/base/gp_psync.c b/gs/base/gp_psync.c index 60f697763..6ddf26653 100644 --- a/gs/base/gp_psync.c +++ b/gs/base/gp_psync.c | |||
@@ -128,13 +128,20 @@ gp_semaphore_signal(gp_semaphore * sema) | |||
128 | /* Monitor supports enter/leave semantics */ | 128 | /* Monitor supports enter/leave semantics */ |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * We need PTHREAD_MUTEX_RECURSIVE behavior, but this isn't totally portable | 131 | * We need PTHREAD_MUTEX_RECURSIVE behavior, but this isn't |
132 | * so we implement it in a more portable fashion, keeping track of the | 132 | * supported on all pthread platforms, so if it's available |
133 | * owner thread using 'pthread_self()' | 133 | * we'll use it, otherwise we'll emulate it. |
134 | * GS_RECURSIVE_MUTEXATTR is set by the configure script | ||
135 | * on Unix-like machines to the attribute setting for | ||
136 | * PTHREAD_MUTEX_RECURSIVE - on linux this is usually | ||
137 | * PTHREAD_MUTEX_RECURSIVE_NP | ||
134 | */ | 138 | */ |
135 | typedef struct gp_pthread_recursive_s { | 139 | typedef struct gp_pthread_recursive_s { |
136 | pthread_mutex_t mutex; /* actual mutex */ | 140 | pthread_mutex_t mutex; /* actual mutex */ |
141 | #ifndef GS_RECURSIVE_MUTEXATTR | ||
137 | pthread_t self_id; /* owner */ | 142 | pthread_t self_id; /* owner */ |
143 | int lcount; | ||
144 | #endif | ||
138 | } gp_pthread_recursive_t; | 145 | } gp_pthread_recursive_t; |
139 | 146 | ||
140 | uint | 147 | uint |
@@ -148,12 +155,32 @@ gp_monitor_open(gp_monitor * mona) | |||
148 | { | 155 | { |
149 | pthread_mutex_t *mon; | 156 | pthread_mutex_t *mon; |
150 | int scode; | 157 | int scode; |
158 | pthread_mutexattr_t attr; | ||
159 | pthread_mutexattr_t *attrp = NULL; | ||
151 | 160 | ||
152 | if (!mona) | 161 | if (!mona) |
153 | return -1; /* monitors are not movable */ | 162 | return -1; /* monitors are not movable */ |
154 | mon = &((gp_pthread_recursive_t *)mona)->mutex; | 163 | |
164 | |||
165 | #ifdef GS_RECURSIVE_MUTEXATTR | ||
166 | attrp = &attr; | ||
167 | scode = pthread_mutexattr_init(attrp); | ||
168 | if (scode < 0) goto done; | ||
169 | |||
170 | scode = pthread_mutexattr_settype(attrp, GS_RECURSIVE_MUTEXATTR); | ||
171 | if (scode < 0) { | ||
172 | goto done; | ||
173 | } | ||
174 | #else | ||
155 | ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ | 175 | ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ |
156 | scode = pthread_mutex_init(mon, NULL); | 176 | ((gp_pthread_recursive_t *)mona)->lcount = 0; |
177 | #endif | ||
178 | |||
179 | mon = &((gp_pthread_recursive_t *)mona)->mutex; | ||
180 | scode = pthread_mutex_init(mon, attrp); | ||
181 | if (attrp) | ||
182 | (void)pthread_mutexattr_destroy(attrp); | ||
183 | done: | ||
157 | return SEM_ERROR_CODE(scode); | 184 | return SEM_ERROR_CODE(scode); |
158 | } | 185 | } |
159 | 186 | ||
@@ -173,29 +200,48 @@ gp_monitor_enter(gp_monitor * mona) | |||
173 | pthread_mutex_t * const mon = (pthread_mutex_t *)mona; | 200 | pthread_mutex_t * const mon = (pthread_mutex_t *)mona; |
174 | int scode; | 201 | int scode; |
175 | 202 | ||
203 | #ifdef GS_RECURSIVE_MUTEXATTR | ||
204 | scode = pthread_mutex_lock(mon); | ||
205 | #else | ||
176 | if ((scode = pthread_mutex_trylock(mon)) == 0) { | 206 | if ((scode = pthread_mutex_trylock(mon)) == 0) { |
177 | ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); | 207 | ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); |
178 | return SEM_ERROR_CODE(scode); | 208 | ((gp_pthread_recursive_t *)mona)->lcount++; |
179 | } else { | 209 | } else { |
180 | if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) | 210 | if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) { |
181 | return 0; | 211 | ((gp_pthread_recursive_t *)mona)->lcount++; |
212 | scode = 0; | ||
213 | } | ||
182 | else { | 214 | else { |
183 | /* we were not the owner, wait */ | 215 | /* we were not the owner, wait */ |
184 | scode = pthread_mutex_lock(mon); | 216 | scode = pthread_mutex_lock(mon); |
185 | ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); | 217 | ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); |
186 | return SEM_ERROR_CODE(scode); | 218 | ((gp_pthread_recursive_t *)mona)->lcount++; |
187 | } | 219 | } |
188 | } | 220 | } |
221 | #endif | ||
222 | return SEM_ERROR_CODE(scode); | ||
189 | } | 223 | } |
190 | 224 | ||
191 | int | 225 | int |
192 | gp_monitor_leave(gp_monitor * mona) | 226 | gp_monitor_leave(gp_monitor * mona) |
193 | { | 227 | { |
194 | pthread_mutex_t * const mon = (pthread_mutex_t *)mona; | 228 | pthread_mutex_t * const mon = (pthread_mutex_t *)mona; |
195 | int scode; | 229 | int scode = 0; |
196 | 230 | ||
197 | scode = pthread_mutex_unlock(mon); | 231 | #ifdef GS_RECURSIVE_MUTEXATTR |
198 | ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ | 232 | scode = pthread_mutex_lock(mon); |
233 | #else | ||
234 | if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) { | ||
235 | if ((--((gp_pthread_recursive_t *)mona)->lcount) == 0) { | ||
236 | scode = pthread_mutex_unlock(mon); | ||
237 | ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ | ||
238 | |||
239 | } | ||
240 | } | ||
241 | else { | ||
242 | scode = -1 /* should be EPERM */; | ||
243 | } | ||
244 | #endif | ||
199 | return SEM_ERROR_CODE(scode); | 245 | return SEM_ERROR_CODE(scode); |
200 | } | 246 | } |
201 | 247 | ||
diff --git a/gs/configure.ac b/gs/configure.ac index 5f64dd221..233129a90 100644 --- a/gs/configure.ac +++ b/gs/configure.ac | |||
@@ -498,26 +498,37 @@ AC_SUBST(HAVE_PREAD_PWRITE) | |||
498 | 498 | ||
499 | SYNC="nosync" | 499 | SYNC="nosync" |
500 | PTHREAD_LIBS="" | 500 | PTHREAD_LIBS="" |
501 | RECURSIVE_MUTEXATTR="" | ||
502 | |||
503 | AC_ARG_ENABLE([threading], AC_HELP_STRING([--disable-threading], | ||
504 | [disable support for multithreaded rendering])) | ||
501 | 505 | ||
502 | # if you haven't got pread/pwrite, we can't use multithreading | 506 | # if you haven't got pread/pwrite, we can't use multithreading |
503 | if test "x$HAVE_PREAD_PWRITE" != "x"; then | 507 | if test "x$HAVE_PREAD_PWRITE" != "x"; then |
504 | 508 | if test "$enable_fontconfig" != "no"; then | |
505 | case `uname` in | 509 | case `uname` in |
506 | MINGW*) | 510 | MINGW*) |
507 | AC_MSG_WARN([disabling support for pthreads......]) | 511 | AC_MSG_WARN([disabling support for pthreads......]) |
508 | ;; | 512 | ;; |
509 | *) | 513 | *) |
510 | AC_CHECK_LIB(pthread, pthread_create, [ | 514 | AC_CHECK_LIB(pthread, pthread_create, [ |
511 | SYNC=posync; | 515 | SYNC=posync; |
512 | PTHREAD_LIBS="-lpthread" | 516 | PTHREAD_LIBS="-lpthread" |
513 | ]) | 517 | ]) |
514 | ;; | 518 | AC_TRY_COMPILE([#include <pthread.h>], |
515 | esac | 519 | [static int k = PTHREAD_MUTEX_RECURSIVE;], |
516 | 520 | [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE"], | |
521 | [AC_TRY_COMPILE([#include <pthread.h>], | ||
522 | [static int k = PTHREAD_MUTEX_RECURSIVE_NP;], | ||
523 | [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE_NP"])]) | ||
524 | ;; | ||
525 | esac | ||
526 | fi | ||
517 | fi | 527 | fi |
518 | 528 | ||
519 | AC_SUBST(SYNC) | 529 | AC_SUBST(SYNC) |
520 | AC_SUBST(PTHREAD_LIBS) | 530 | AC_SUBST(PTHREAD_LIBS) |
531 | AC_SUBST(RECURSIVE_MUTEXATTR) | ||
521 | 532 | ||
522 | AC_MSG_CHECKING([for local trio library source]) | 533 | AC_MSG_CHECKING([for local trio library source]) |
523 | if test -f $srcdir/trio/trio.h; then | 534 | if test -f $srcdir/trio/trio.h; then |