diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-11-21 14:23:45 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-11-23 10:01:25 +0000 |
commit | cb44c9ae591ae5cdfda932f04bf321932a0e1d0f (patch) | |
tree | 4fe8f3d70d6f951ee8cd50c96bc4dc732179a7f0 | |
parent | 30afe6fa458cef7a6f84020de5bd15d8ae164521 (diff) | |
download | mupdf-cb44c9ae591ae5cdfda932f04bf321932a0e1d0f.tar.xz |
Convert mudraw and muraster to use mu-threads.
Saves having the same threading code repeatedly.
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | include/mupdf/fitz/system.h | 5 | ||||
-rw-r--r-- | platform/win32/mupdf.sln | 21 | ||||
-rw-r--r-- | source/tools/mudraw.c | 283 | ||||
-rw-r--r-- | source/tools/muraster.c | 364 |
5 files changed, 209 insertions, 476 deletions
@@ -73,6 +73,7 @@ ALL_DIR += $(OUT)/cbz ALL_DIR += $(OUT)/html ALL_DIR += $(OUT)/gprf ALL_DIR += $(OUT)/tools +ALL_DIR += $(OUT)/helper ALL_DIR += $(OUT)/platform/x11 ALL_DIR += $(OUT)/platform/x11/curl ALL_DIR += $(OUT)/platform/gl @@ -82,6 +83,7 @@ FITZ_HDR := include/mupdf/fitz.h $(wildcard include/mupdf/fitz/*.h) PDF_HDR := include/mupdf/pdf.h $(wildcard include/mupdf/pdf/*.h) SVG_HDR := include/mupdf/svg.h HTML_HDR := include/mupdf/html.h +THREAD_HDR := include/mupdf/helper/mu-threads.h FITZ_SRC := $(wildcard source/fitz/*.c) PDF_SRC := $(wildcard source/pdf/*.c) @@ -90,6 +92,7 @@ SVG_SRC := $(wildcard source/svg/*.c) CBZ_SRC := $(wildcard source/cbz/*.c) HTML_SRC := $(wildcard source/html/*.c) GPRF_SRC := $(wildcard source/gprf/*.c) +THREAD_SRC := source/helper/mu-threads.c FITZ_SRC_HDR := $(wildcard source/fitz/*.h) PDF_SRC_HDR := $(wildcard source/pdf/*.h) source/pdf/pdf-name-table.h @@ -105,6 +108,7 @@ SVG_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(SVG_SRC)))) CBZ_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(CBZ_SRC)))) HTML_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(HTML_SRC)))) GPRF_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(GPRF_SRC)))) +THREAD_OBJ := $(subst source/, $(OUT)/, $(addsuffix .o, $(basename $(THREAD_SRC)))) $(FITZ_OBJ) : $(FITZ_HDR) $(FITZ_SRC_HDR) $(PDF_OBJ) : $(FITZ_HDR) $(PDF_HDR) $(PDF_SRC_HDR) @@ -113,6 +117,7 @@ $(SVG_OBJ) : $(FITZ_HDR) $(SVG_HDR) $(SVG_SRC_HDR) $(CBZ_OBJ) : $(FITZ_HDR) $(HTML_OBJ) : $(FITZ_HDR) $(HTML_HDR) $(HTML_SRC_HDR) $(GPRF_OBJ) : $(FITZ_HDR) $(GPRF_HDR) $(GPRF_SRC_HDR) +$(THREAD_OBJ) : $(THREAD_HDR) # --- Generated embedded font files --- @@ -154,12 +159,15 @@ $(FONT_GEN_SIL) : $(FONT_BIN_SIL) MUPDF_LIB = $(OUT)/libmupdf.a THIRD_LIB = $(OUT)/libmupdfthird.a +THREAD_LIB = $(OUT)/libmuthreads.a MUPDF_OBJ := $(FITZ_OBJ) $(FONT_OBJ) $(PDF_OBJ) $(XPS_OBJ) $(SVG_OBJ) $(CBZ_OBJ) $(HTML_OBJ) $(GPRF_OBJ) THIRD_OBJ := $(FREETYPE_OBJ) $(HARFBUZZ_OBJ) $(JBIG2DEC_OBJ) $(JPEG_OBJ) $(JPEGXR_OBJ) $(LURATECH_OBJ) $(MUJS_OBJ) $(OPENJPEG_OBJ) $(ZLIB_OBJ) +THREAD_OBJ := $(THREAD_OBJ) $(MUPDF_LIB) : $(MUPDF_OBJ) $(THIRD_LIB) : $(THIRD_OBJ) +$(THREAD_LIB) : $(THREAD_OBJ) INSTALL_LIBS := $(MUPDF_LIB) $(THIRD_LIB) @@ -265,13 +273,13 @@ MUTOOL_OBJ += $(addprefix $(OUT)/tools/, pdfclean.o pdfcreate.o pdfextract.o pdf $(MUTOOL_OBJ): $(FITZ_HDR) $(PDF_HDR) MUTOOL_LIB = $(OUT)/libmutools.a $(MUTOOL_LIB) : $(MUTOOL_OBJ) -$(MUTOOL) : $(MUTOOL_LIB) $(MUPDF_LIB) $(THIRD_LIB) +$(MUTOOL) : $(MUTOOL_LIB) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB) $(LINK_CMD) MURASTER := $(OUT)/muraster MURASTER_OBJ := $(addprefix $(OUT)/tools/, muraster.o) $(MURASTER_OBJ): $(FITZ_HDR) -$(MURASTER) : $(MURASTER_OBJ) $(MUPDF_LIB) $(THIRD_LIB) +$(MURASTER) : $(MURASTER_OBJ) $(MUPDF_LIB) $(THIRD_LIB) $(THREAD_LIB) $(LINK_CMD) MJSGEN := $(OUT)/mjsgen diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h index 1723824f..3fe4311a 100644 --- a/include/mupdf/fitz/system.h +++ b/include/mupdf/fitz/system.h @@ -81,6 +81,11 @@ #define fz_jmp_buf jmp_buf #endif +#ifndef _MSC_VER +/* For gettimeofday */ +#include <sys/time.h> +#endif + #ifdef _MSC_VER /* Microsoft Visual C */ /* MSVC up to VS2012 */ diff --git a/platform/win32/mupdf.sln b/platform/win32/mupdf.sln index 723b8dea..998b8186 100644 --- a/platform/win32/mupdf.sln +++ b/platform/win32/mupdf.sln @@ -10,20 +10,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libthirdparty", "libthirdpa EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmupdf", "libmupdf.vcproj", "{5F615F91-DFF8-4F05-BF48-6222B7D86519}" ProjectSection(ProjectDependencies) = postProject - {B0091365-C9BA-4F40-AE2B-EF93702871B2} = {B0091365-C9BA-4F40-AE2B-EF93702871B2} - {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} - {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526} {52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22} + {A5053AA7-02E5-4903-B596-04F17AEB1526} = {A5053AA7-02E5-4903-B596-04F17AEB1526} + {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} = {5EDCF4FD-0291-4FB9-8D96-D58957CA5E3C} + {B0091365-C9BA-4F40-AE2B-EF93702871B2} = {B0091365-C9BA-4F40-AE2B-EF93702871B2} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mudraw", "mudraw.vcproj", "{0B51171B-B10E-4EAC-8FFA-19226A1828A3}" ProjectSection(ProjectDependencies) = postProject + {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mutool", "mutool.vcproj", "{00811970-815B-4F64-BC9D-219078B1F3AA}" ProjectSection(ProjectDependencies) = postProject {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} + {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generated", "generated.vcproj", "{A5053AA7-02E5-4903-B596-04F17AEB1526}" @@ -32,8 +34,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcurl", "..\..\thirdparty EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf-curl", "mupdf-curl.vcproj", "{27B53E5C-ACAB-423C-854E-BECE56D73544}" ProjectSection(ProjectDependencies) = postProject - {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588} + {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mujstest", "mujstest.vcproj", "{21E28758-E4D2-4B84-8EC5-B631CEE66B30}" @@ -45,8 +47,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libglfw", "libglfw.vcproj", EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mupdf-gl", "mupdf-gl.vcproj", "{CE3A76A8-A28F-4991-8FB9-C9453D922037}" ProjectSection(ProjectDependencies) = postProject - {A1B75D29-9F5C-4A0F-B368-322A10477D0C} = {A1B75D29-9F5C-4A0F-B368-322A10477D0C} {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} + {A1B75D29-9F5C-4A0F-B368-322A10477D0C} = {A1B75D29-9F5C-4A0F-B368-322A10477D0C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libfonts", "libfonts.vcproj", "{52DCAB29-C8EE-4422-954C-29AFA6B33E22}" @@ -57,20 +59,21 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "muraster", "muraster.vcproj", "{0FDC74D7-D18C-45CE-94D6-EDFCC5A0CDF2}" ProjectSection(ProjectDependencies) = postProject {52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22} + {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javaviewerlib", "javaviewerlib.vcproj", "{3DB35F2D-9679-4DED-BA0C-240A4E6E6674}" ProjectSection(ProjectDependencies) = postProject - {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} {52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22} + {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javaviewer", "javaviewer.vcproj", "{FB8DC595-90A5-44D6-9FFF-2BDFA912FD8C}" ProjectSection(ProjectDependencies) = postProject - {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} - {3DB35F2D-9679-4DED-BA0C-240A4E6E6674} = {3DB35F2D-9679-4DED-BA0C-240A4E6E6674} {52DCAB29-C8EE-4422-954C-29AFA6B33E22} = {52DCAB29-C8EE-4422-954C-29AFA6B33E22} + {3DB35F2D-9679-4DED-BA0C-240A4E6E6674} = {3DB35F2D-9679-4DED-BA0C-240A4E6E6674} + {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libluratech", "libluratech.vcproj", "{B0091365-C9BA-4F40-AE2B-EF93702871B2}" @@ -79,8 +82,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmuthreads", "libmuthread EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mu-office-lib", "mu-office-lib.vcproj", "{FFF91365-C9BA-4F40-AE2B-EF93702871B2}" ProjectSection(ProjectDependencies) = postProject - {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} = {DE21FA8A-FC8A-47E0-87E4-DCE8808BFC9B} + {5F615F91-DFF8-4F05-BF48-6222B7D86519} = {5F615F91-DFF8-4F05-BF48-6222B7D86519} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mu-office-test", "mu-office-test.vcproj", "{FB51171B-B10E-4EAC-8FFA-19226A1828A3}" diff --git a/source/tools/mudraw.c b/source/tools/mudraw.c index 0b091fee..20122563 100644 --- a/source/tools/mudraw.c +++ b/source/tools/mudraw.c @@ -5,18 +5,7 @@ #include "mupdf/fitz.h" #include "mupdf/pdf.h" /* for pdf output */ -#ifdef _MSC_VER -#include <winsock2.h> -#include <windows.h> -#define MUDRAW_THREADS 1 -#else -#include <sys/time.h> -#ifdef HAVE_PTHREADS -#define MUDRAW_THREADS 2 -#include <pthread.h> -#include <semaphore.h> -#endif -#endif +#include "mupdf/helpers/mu-threads.h" /* Enable for helpful threading debug */ /* #define DEBUG_THREADS(A) do { printf A; fflush(stdout); } while (0) */ @@ -131,144 +120,18 @@ static const format_cs_table_t format_cs_table[] = a multi-threaded option. In the absence, of such, we degrade nicely. */ -#ifdef MUDRAW_THREADS -#if MUDRAW_THREADS == 1 - -/* Windows threads */ -#define SEMAPHORE HANDLE -#define SEMAPHORE_INIT(A) do { A = CreateSemaphore(NULL, 0, 1, NULL); } while (0) -#define SEMAPHORE_FIN(A) do { CloseHandle(A); } while (0) -#define SEMAPHORE_TRIGGER(A) do { (void)ReleaseSemaphore(A, 1, NULL); } while (0) -#define SEMAPHORE_WAIT(A) do { (void)WaitForSingleObject(A, INFINITE); } while (0) -#define THREAD HANDLE -#define THREAD_INIT(A,B,C) do { A = CreateThread(NULL, 0, B, C, 0, NULL); } while (0) -#define THREAD_FIN(A) do { CloseHandle(A); } while (0) -#define THREAD_RETURN_TYPE DWORD WINAPI -#define THREAD_RETURN() return 0 -#define MUTEX CRITICAL_SECTION -#define MUTEX_INIT(A) do { InitializeCriticalSection(&A); } while (0) -#define MUTEX_FIN(A) do { DeleteCriticalSection(&A); } while (0) -#define MUTEX_LOCK(A) do { EnterCriticalSection(&A); } while (0) -#define MUTEX_UNLOCK(A) do { LeaveCriticalSection(&A); } while (0) - -#elif MUDRAW_THREADS == 2 - -/* - PThreads - without working unnamed semaphores. - - Neither ios nor OSX supports unnamed semaphores. - Named semaphores are a pain to use, so we implement - our own semaphores using condition variables and - mutexes. -*/ +#ifndef DISABLE_MUTHREADS -typedef struct -{ - int count; - pthread_mutex_t mutex; - pthread_cond_t cond; -} my_semaphore_t; - -int -my_semaphore_open(my_semaphore_t *sem) -{ - int scode; - - sem->count = 0; - scode = pthread_mutex_init(&sem->mutex, NULL); - if (scode == 0) - { - scode = pthread_cond_init(&sem->cond, NULL); - if (scode) - pthread_mutex_destroy(&sem->mutex); - } - if (scode) - memset(sem, 0, sizeof(*sem)); - return scode; -} - -int -my_semaphore_close(my_semaphore_t *sem) -{ - int scode, scode2; - - scode = pthread_cond_destroy(&sem->cond); - scode2 = pthread_mutex_destroy(&sem->mutex); - if (scode == 0) - scode = scode2; - return scode; -} - -int -my_semaphore_wait(my_semaphore_t *sem) -{ - int scode, scode2; - - scode = pthread_mutex_lock(&sem->mutex); - if (scode) - return scode; - while (sem->count == 0) { - scode = pthread_cond_wait(&sem->cond, &sem->mutex); - if (scode) - break; - } - if (scode == 0) - --sem->count; - scode2 = pthread_mutex_unlock(&sem->mutex); - if (scode == 0) - scode = scode2; - return scode; -} - -int -my_semaphore_signal(my_semaphore_t * sem) -{ - int scode, scode2; - - scode = pthread_mutex_lock(&sem->mutex); - if (scode) - return scode; - if (sem->count++ == 0) - scode = pthread_cond_signal(&sem->cond); - scode2 = pthread_mutex_unlock(&sem->mutex); - if (scode == 0) - scode = scode2; - return scode; -} - -#define SEMAPHORE my_semaphore_t -#define SEMAPHORE_INIT(A) do { (void)my_semaphore_open(&A); } while (0) -#define SEMAPHORE_FIN(A) do { (void)my_semaphore_close(&A); } while (0) -#define SEMAPHORE_TRIGGER(A) do { (void)my_semaphore_signal(&A); } while (0) -#define SEMAPHORE_WAIT(A) do { (void)my_semaphore_wait(&A); } while (0) -#define THREAD pthread_t -#define THREAD_INIT(A,B,C) do { (void)pthread_create(&A, NULL, B, C); } while (0) -#define THREAD_FIN(A) do { void *res; (void)pthread_join(A, &res); } while (0) -#define THREAD_RETURN_TYPE void * -#define THREAD_RETURN() return NULL -#define MUTEX pthread_mutex_t -#define MUTEX_INIT(A) do { (void)pthread_mutex_init(&A, NULL); } while (0) -#define MUTEX_FIN(A) do { (void)pthread_mutex_destroy(&A); } while (0) -#define MUTEX_LOCK(A) do { (void)pthread_mutex_lock(&A); } while (0) -#define MUTEX_UNLOCK(A) do { (void)pthread_mutex_unlock(&A); } while (0) - -#else -#error Unknown MUDRAW_THREADS setting -#endif - -#define LOCKS_INIT() init_mudraw_locks() -#define LOCKS_FIN() fin_mudraw_locks() - -static MUTEX mutexes[FZ_LOCK_MAX]; +static mu_mutex mutexes[FZ_LOCK_MAX]; static void mudraw_lock(void *user, int lock) { - MUTEX_LOCK(mutexes[lock]); + mu_lock_mutex(&mutexes[lock]); } static void mudraw_unlock(void *user, int lock) { - MUTEX_UNLOCK(mutexes[lock]); + mu_unlock_mutex(&mutexes[lock]); } static fz_locks_context mudraw_locks = @@ -276,37 +139,30 @@ static fz_locks_context mudraw_locks = NULL, mudraw_lock, mudraw_unlock }; -static fz_locks_context *init_mudraw_locks(void) +static void fin_mudraw_locks(void) { int i; for (i = 0; i < FZ_LOCK_MAX; i++) - MUTEX_INIT(mutexes[i]); - - return &mudraw_locks; + mu_destroy_mutex(&mutexes[i]); } -static void fin_mudraw_locks(void) +static fz_locks_context *init_mudraw_locks(void) { int i; + int failed = 0; for (i = 0; i < FZ_LOCK_MAX; i++) - MUTEX_FIN(mutexes[i]); -} + failed |= mu_create_mutex(&mutexes[i]); -#else + if (failed) + { + fin_mudraw_locks(); + return NULL; + } -/* Null Threads implementation */ -#define SEMAPHORE int -#define THREAD int -#define SEMAPHORE_INIT(A) do { A = 0; } while (0) -#define SEMAPHORE_FIN(A) do { A = 0; } while (0) -#define SEMAPHORE_TRIGGER(A) do { A = 0; } while (0) -#define SEMAPHORE_WAIT(A) do { A = 0; } while (0) -#define THREAD_INIT(A,B,C) do { A = 0; (void)C; } while (0) -#define THREAD_FIN(A) do { A = 0; } while (0) -#define LOCKS_INIT() NULL -#define LOCKS_FIN() do { } while (0) + return &mudraw_locks; +} #endif @@ -320,9 +176,9 @@ typedef struct worker_t { fz_pixmap *pix; fz_bitmap *bit; fz_cookie cookie; - SEMAPHORE start; - SEMAPHORE stop; - THREAD thread; + mu_semaphore start; + mu_semaphore stop; + mu_thread thread; } worker_t; static char *output = NULL; @@ -385,9 +241,9 @@ static struct { int active; int started; fz_context *ctx; - THREAD thread; - SEMAPHORE start; - SEMAPHORE stop; + mu_thread thread; + mu_semaphore start; + mu_semaphore stop; int pagenum; char *filename; fz_display_list *list; @@ -865,7 +721,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in workers[band].pix = fz_new_pixmap_with_bbox(ctx, colorspace, &band_ibounds, alpha); fz_set_pixmap_resolution(ctx, workers[band].pix, resolution, resolution); DEBUG_THREADS(("Worker %d, Pre-triggering band %d\n", band, band)); - SEMAPHORE_TRIGGER(workers[band].start); + mu_trigger_semaphore(&workers[band].start); ctm.f -= drawheight; } pix = workers[0].pix; @@ -908,7 +764,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in { worker_t *w = &workers[band % num_workers]; DEBUG_THREADS(("Waiting for worker %d to complete band %d\n", w->num, band)); - SEMAPHORE_WAIT(w->stop); + mu_wait_semaphore(&w->stop); pix = w->pix; bit = w->bit; w->bit = NULL; @@ -937,7 +793,7 @@ static void dodrawpage(fz_context *ctx, fz_page *page, fz_display_list *list, in w->tbounds = tbounds; memset(&w->cookie, 0, sizeof(fz_cookie)); DEBUG_THREADS(("Triggering worker %d for band %d\n", w->num, w->band)); - SEMAPHORE_TRIGGER(w->start); + mu_trigger_semaphore(&w->start); } ctm.f -= drawheight; } @@ -1059,7 +915,7 @@ static void bgprint_flush(void) if (!bgprint.active || !bgprint.started) return; - SEMAPHORE_WAIT(bgprint.stop); + mu_wait_semaphore(&bgprint.stop); bgprint.started = 0; } @@ -1165,7 +1021,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) bgprint.filename = filename; bgprint.pagenum = pagenum; bgprint.interptime = start; - SEMAPHORE_TRIGGER(bgprint.start); + mu_trigger_semaphore(&bgprint.start); } else { @@ -1267,26 +1123,25 @@ trace_realloc(void *arg, void *p_, size_t size) return &p[1]; } -#ifdef MUDRAW_THREADS -static THREAD_RETURN_TYPE worker_thread(void *arg) +#ifndef DISABLE_MUTHREADS +static void worker_thread(void *arg) { worker_t *me = (worker_t *)arg; do { DEBUG_THREADS(("Worker %d waiting\n", me->num)); - SEMAPHORE_WAIT(me->start); + mu_wait_semaphore(&me->start); DEBUG_THREADS(("Worker %d woken for band %d\n", me->num, me->band)); if (me->band >= 0) drawband(me->ctx, NULL, me->list, &me->ctm, &me->tbounds, &me->cookie, me->band * band_height, me->pix, &me->bit); DEBUG_THREADS(("Worker %d completed band %d\n", me->num, me->band)); - SEMAPHORE_TRIGGER(me->stop); + mu_trigger_semaphore(&me->stop); } while (me->band >= 0); - THREAD_RETURN(); } -static THREAD_RETURN_TYPE bgprint_worker(void *arg) +static void bgprint_worker(void *arg) { fz_cookie cookie = { 0 }; int pagenum; @@ -1296,7 +1151,7 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg) do { DEBUG_THREADS(("BGPrint waiting\n")); - SEMAPHORE_WAIT(bgprint.start); + mu_wait_semaphore(&bgprint.start); pagenum = bgprint.pagenum; DEBUG_THREADS(("BGPrint woken for pagenum %d\n", pagenum)); if (pagenum >= 0) @@ -1306,10 +1161,9 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg) dodrawpage(bgprint.ctx, bgprint.page, bgprint.list, pagenum, &cookie, start, bgprint.interptime, bgprint.filename, 1); } DEBUG_THREADS(("BGPrint completed page %d\n", pagenum)); - SEMAPHORE_TRIGGER(bgprint.stop); + mu_trigger_semaphore(&bgprint.stop); } while (pagenum >= 0); - THREAD_RETURN(); } #endif @@ -1426,6 +1280,7 @@ int mudraw_main(int argc, char **argv) int c, i; fz_context *ctx; fz_alloc_context alloc_ctx = { NULL, trace_malloc, trace_realloc, trace_free }; + fz_locks_context *locks = NULL; fz_var(doc); @@ -1479,7 +1334,7 @@ int mudraw_main(int argc, char **argv) case 'i': ignore_errors = 1; break; case 'T': -#ifdef MUDRAW_THREADS +#ifndef DISABLE_MUTHREADS num_workers = atoi(fz_optarg); break; #else fprintf(stderr, "Threads not enabled in this build\n"); @@ -1520,7 +1375,16 @@ int mudraw_main(int argc, char **argv) } } - ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), LOCKS_INIT(), (lowmemory ? 1 : FZ_STORE_DEFAULT)); +#ifndef DISABLE_MUTHREADS + locks = init_mudraw_locks(); + if (locks == NULL) + { + fprintf(stderr, "mutex initialisation failed\n"); + exit(1); + } +#endif + + ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), locks, (lowmemory ? 1 : FZ_STORE_DEFAULT)); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); @@ -1531,26 +1395,40 @@ int mudraw_main(int argc, char **argv) fz_set_graphics_aa_level(ctx, alphabits_graphics); fz_set_graphics_min_line_width(ctx, min_line_width); +#ifndef DISABLE_MUTHREADS if (bgprint.active) { + int fail = 0; bgprint.ctx = fz_clone_context(ctx); - SEMAPHORE_INIT(bgprint.start); - SEMAPHORE_INIT(bgprint.stop); - THREAD_INIT(bgprint.thread, bgprint_worker, NULL); + fail |= mu_create_semaphore(&bgprint.start); + fail |= mu_create_semaphore(&bgprint.stop); + fail |= mu_create_thread(&bgprint.thread, bgprint_worker, NULL); + if (fail) + { + fprintf(stderr, "bgprint startup failed\n"); + exit(1); + } } if (num_workers > 0) { + int fail = 0; workers = fz_calloc(ctx, num_workers, sizeof(*workers)); for (i = 0; i < num_workers; i++) { workers[i].ctx = fz_clone_context(ctx); workers[i].num = i; - SEMAPHORE_INIT(workers[i].start); - SEMAPHORE_INIT(workers[i].stop); - THREAD_INIT(workers[i].thread, worker_thread, &workers[i]); + fail |= mu_create_semaphore(&workers[i].start); + fail |= mu_create_semaphore(&workers[i].stop); + fail |= mu_create_thread(&workers[i].thread, worker_thread, &workers[i]); + } + if (fail) + { + fprintf(stderr, "worker startup failed\n"); + exit(1); } } +#endif /* DISABLE_MUTHREADS */ if (layout_css) { @@ -1813,16 +1691,17 @@ int mudraw_main(int argc, char **argv) } } +#ifndef DISABLE_MUTHREADS if (num_workers > 0) { for (i = 0; i < num_workers; i++) { workers[i].band = -1; - SEMAPHORE_TRIGGER(workers[i].start); - SEMAPHORE_WAIT(workers[i].stop); - SEMAPHORE_FIN(workers[i].start); - SEMAPHORE_FIN(workers[i].stop); - THREAD_FIN(workers[i].thread); + mu_trigger_semaphore(&workers[i].start); + mu_wait_semaphore(&workers[i].stop); + mu_destroy_semaphore(&workers[i].start); + mu_destroy_semaphore(&workers[i].stop); + mu_destroy_thread(&workers[i].thread); fz_drop_context(workers[i].ctx); } fz_free(ctx, workers); @@ -1831,16 +1710,20 @@ int mudraw_main(int argc, char **argv) if (bgprint.active) { bgprint.pagenum = -1; - SEMAPHORE_TRIGGER(bgprint.start); - SEMAPHORE_WAIT(bgprint.stop); - SEMAPHORE_FIN(bgprint.start); - SEMAPHORE_FIN(bgprint.stop); - THREAD_FIN(bgprint.thread); + mu_trigger_semaphore(&bgprint.start); + mu_wait_semaphore(&bgprint.stop); + mu_destroy_semaphore(&bgprint.start); + mu_destroy_semaphore(&bgprint.stop); + mu_destroy_thread(&bgprint.thread); fz_drop_context(bgprint.ctx); } +#endif /* DISABLE_MUTHREADS */ fz_drop_context(ctx); - LOCKS_FIN(); + +#ifndef DISABLE_MUTHREADS + fin_mudraw_locks(); +#endif /* DISABLE_MUTHREADS */ if (showmemory) { diff --git a/source/tools/muraster.c b/source/tools/muraster.c index a22ee0a8..d65074d5 100644 --- a/source/tools/muraster.c +++ b/source/tools/muraster.c @@ -16,6 +16,17 @@ /* CONFIGURATION SECTION + The first bit of configuration for this is actually in + how the muthreads helper library is built. If muthreads + does not know how to support threading on your system + then it will ensure that DISABLE_MUTHREADS is set. All + the muthreads entrypoints/types will still be defined + (as dummy types/functions), but attempting to use them + will return errors. + + Configuration options affecting threading should be + turned off if DISABLE_MUTHREADS is set. + Integrators can/should define the following MURASTER_CONFIG_ values. If not set, we'll attempt to set sensible defaults. @@ -122,32 +133,11 @@ /* #define MURASTER_CONFIG_GREY_FALLBACK 1 */ /* - MURASTER_CONFIG_THREAD_SYSTEM: - - 0 for no threading available. - - 1 for Windows (or leave undefined to autodetect) - - 2 for PThreads (or leave undefined and use HAVE_PTHREADS) - - 3 (or higher) for custom threading options. - Add your implementations further down the - file. -*/ -/* #undef MURASTER_CONFIG_THREAD_SYSTEM */ - -/* END OF CONFIGURATION SECTION */ #include "mupdf/fitz.h" - -#ifdef _MSC_VER -#include <winsock2.h> -#include <windows.h> -#else -#include <sys/time.h> -#endif +#include "mupdf/helpers/mu-threads.h" /* After this point, we convert the #defines set (or not set) @@ -155,21 +145,6 @@ these for configuration. */ -/* Detect threading */ -#ifdef MURASTER_CONFIG_THREAD_SYSTEM -#define MURASTER_THREADS MURASTER_CONFIG_THREAD_SYSTEM -#else -#ifdef _MSC_VER -#define MURASTER_THREADS 1 -#else -#ifdef HAVE_PTHREADS -#define MURASTER_THREADS 2 -#include <pthread.h> -#include <semaphore.h> -#endif -#endif -#endif - #ifdef MURASTER_CONFIG_X_RESOLUTION #define X_RESOLUTION MURASTER_CONFIG_X_RESOLUTION #else @@ -278,171 +253,16 @@ static const suffix_t suffix_table[] = #endif }; -/* - In the presence of pthreads or Windows threads, we can offer - a multi-threaded option. In the absence, of such, we degrade - nicely. -*/ -#ifdef MURASTER_THREADS -#if MURASTER_THREADS == 1 - -/* Windows threads */ -#define SEMAPHORE HANDLE -#define SEMAPHORE_INIT(A) do { A = CreateSemaphore(NULL, 0, 1, NULL); } while (0) -#define SEMAPHORE_FIN(A) do { CloseHandle(A); } while (0) -#define SEMAPHORE_TRIGGER(A) do { (void)ReleaseSemaphore(A, 1, NULL); } while (0) -#define SEMAPHORE_WAIT(A) do { (void)WaitForSingleObject(A, INFINITE); } while (0) -#define THREAD HANDLE -#define THREAD_INIT(A,B,C) do { A = CreateThread(NULL, 0, B, C, 0, NULL); } while (0) -#define THREAD_FIN(A) do { CloseHandle(A); } while (0) -#define THREAD_RETURN_TYPE DWORD WINAPI -#define THREAD_RETURN() return 0 -#define MUTEX CRITICAL_SECTION -#define MUTEX_INIT(A) do { InitializeCriticalSection(&A); } while (0) -#define MUTEX_FIN(A) do { DeleteCriticalSection(&A); } while (0) -#define MUTEX_LOCK(A) do { EnterCriticalSection(&A); } while (0) -#define MUTEX_UNLOCK(A) do { LeaveCriticalSection(&A); } while (0) - -#elif MURASTER_THREADS == 2 - -/* - PThreads - without working unnamed semaphores. - - Neither ios nor OSX supports unnamed semaphores. - Named semaphores are a pain to use, so we implement - our own sempahores using condition variables and - mutexes. -*/ - -typedef struct -{ - int count; - pthread_mutex_t mutex; - pthread_cond_t cond; -} my_semaphore_t; - -int -my_semaphore_open(my_semaphore_t *sem) -{ - int scode; - - sem->count = 0; - scode = pthread_mutex_init(&sem->mutex, NULL); - if (scode == 0) - { - scode = pthread_cond_init(&sem->cond, NULL); - if (scode) - pthread_mutex_destroy(&sem->mutex); - } - if (scode) - memset(sem, 0, sizeof(*sem)); - return scode; -} - -int -my_semaphore_close(my_semaphore_t *sem) -{ - int scode, scode2; - - scode = pthread_cond_destroy(&sem->cond); - scode2 = pthread_mutex_destroy(&sem->mutex); - if (scode == 0) - scode = scode2; - return scode; -} - -int -my_semaphore_wait(my_semaphore_t *sem) -{ - int scode, scode2; - - scode = pthread_mutex_lock(&sem->mutex); - if (scode) - return scode; - while (sem->count == 0) { - scode = pthread_cond_wait(&sem->cond, &sem->mutex); - if (scode) - break; - } - if (scode == 0) - --sem->count; - scode2 = pthread_mutex_unlock(&sem->mutex); - if (scode == 0) - scode = scode2; - return scode; -} - -int -my_semaphore_signal(my_semaphore_t * sem) -{ - int scode, scode2; - - scode = pthread_mutex_lock(&sem->mutex); - if (scode) - return scode; - if (sem->count++ == 0) - scode = pthread_cond_signal(&sem->cond); - scode2 = pthread_mutex_unlock(&sem->mutex); - if (scode == 0) - scode = scode2; - return scode; -} - -#define SEMAPHORE my_semaphore_t -#define SEMAPHORE_INIT(A) do { (void)my_semaphore_open(&A); } while (0) -#define SEMAPHORE_FIN(A) do { (void)my_semaphore_close(&A); } while (0) -#define SEMAPHORE_TRIGGER(A) do { (void)my_semaphore_signal(&A); } while (0) -#define SEMAPHORE_WAIT(A) do { (void)my_semaphore_wait(&A); } while (0) -#define THREAD pthread_t -#define THREAD_INIT(A,B,C) do { (void)pthread_create(&A, NULL, B, C); } while (0) -#define THREAD_FIN(A) do { void *res; (void)pthread_join(A, &res); } while (0) -#define THREAD_RETURN_TYPE void * -#define THREAD_RETURN() return NULL -#define MUTEX pthread_mutex_t -#define MUTEX_INIT(A) do { (void)pthread_mutex_init(&A, NULL); } while (0) -#define MUTEX_FIN(A) do { (void)pthread_mutex_destroy(&A); } while (0) -#define MUTEX_LOCK(A) do { (void)pthread_mutex_lock(&A); } while (0) -#define MUTEX_UNLOCK(A) do { (void)pthread_mutex_unlock(&A); } while (0) - -// ADD OTHER THREADING IMPLEMENTATIONS HERE. -// See the above implementations for what the different -// arguments mean. -// -//#elif MURASTER_THREADS == 3 -// -//#define SEMAPHORE /* type for a semaphore */ -//#define SEMAPHORE_INIT(A) /* init a semaphore */ -//#define SEMAPHORE_FIN(A) /* finalise a semaphore */ -//#define SEMAPHORE_TRIGGER(A) /* trigger a semaphore */ -//#define SEMAPHORE_WAIT(A) /* wait for a semaphore */ -//#define THREAD /* type for a thread */ -//#define THREAD_INIT(A,B,C) /* initialise a new thread */ -//#define THREAD_FIN(A) /* finalise a thread */ -//#define THREAD_RETURN_TYPE /* return type for the thread */ -//#define THREAD_RETURN() /* command to return from a thread */ -//#define MUTEX /* type for a mutex */ -//#define MUTEX_INIT(A) /* initialise a mutex */ -//#define MUTEX_FIN(A) /* finalise a mutex */ -//#define MUTEX_LOCK(A) /* lock a mutex */ -//#define MUTEX_UNLOCK(A) /* unlock a mutex */ - -#else -#error Unknown MURASTER_THREADS setting -#endif - -#define LOCKS_INIT() init_muraster_locks() -#define LOCKS_FIN() fin_muraster_locks() - -static MUTEX mutexes[FZ_LOCK_MAX]; +static mu_mutex mutexes[FZ_LOCK_MAX]; static void muraster_lock(void *user, int lock) { - MUTEX_LOCK(mutexes[lock]); + mu_lock_mutex(&mutexes[lock]); } static void muraster_unlock(void *user, int lock) { - MUTEX_UNLOCK(mutexes[lock]); + mu_unlock_mutex(&mutexes[lock]); } static fz_locks_context muraster_locks = @@ -450,52 +270,40 @@ static fz_locks_context muraster_locks = NULL, muraster_lock, muraster_unlock }; -static fz_locks_context *init_muraster_locks(void) +static void fin_muraster_locks(void) { int i; for (i = 0; i < FZ_LOCK_MAX; i++) - MUTEX_INIT(mutexes[i]); - - return &muraster_locks; + mu_destroy_mutex(&mutexes[i]); } -static void fin_muraster_locks(void) +static fz_locks_context *init_muraster_locks(void) { int i; + int failed = 0; for (i = 0; i < FZ_LOCK_MAX; i++) - MUTEX_FIN(mutexes[i]); -} - -#else + failed |= mu_create_mutex(&mutexes[i]); -/* Null Threads implementation */ -#define SEMAPHORE int -#define THREAD int -#define SEMAPHORE_INIT(A) do { A = 0; } while (0) -#define SEMAPHORE_FIN(A) do { A = 0; } while (0) -#define SEMAPHORE_TRIGGER(A) do { A = 0; } while (0) -#define SEMAPHORE_WAIT(A) do { A = 0; } while (0) -#define THREAD_INIT(A,B,C) do { A = 0; (void)C; } while (0) -#define THREAD_FIN(A) do { A = 0; } while (0) -#define LOCKS_INIT() NULL -#define LOCKS_FIN() do { } while (0) - -#undef MURASTER_THREADS -#define MURASTER_THREADS 0 + if (failed) + { + fin_muraster_locks(); + return NULL; + } -#endif + return &muraster_locks; +} #ifdef MURASTER_CONFIG_RENDER_THREADS #define NUM_RENDER_THREADS MURASTER_CONFIG_RENDER_THREADS -#elif MURASTER_THREADS == 0 +#elif defined(DISABLE_MUTHREADS) #define NUM_RENDER_THREADS 0 #else #define NUM_RENDER_THREADS 3 #endif -#if MURASTER_THREADS == 0 && NUM_RENDER_THREADS != 0 +#if defined(DISABLE_MUTHREADS) && NUM_RENDER_THREADS != 0 #error "Can't have MURASTER_CONFIG_RENDER_THREADS > 0 without having a threading library!" #endif @@ -507,7 +315,7 @@ static void fin_muraster_locks(void) #define BGPRINT 1 #endif -#if MURASTER_THREADS == 0 && BGPRINT != 0 +#if defined(DISABLE_MUTHREADS) && BGPRINT != 0 #error "Can't have MURASTER_CONFIG_BGPRINT > 0 without having a threading library!" #endif @@ -523,9 +331,9 @@ typedef struct worker_t { fz_pixmap *pix; fz_bitmap *bit; fz_cookie cookie; - SEMAPHORE start; - SEMAPHORE stop; - THREAD thread; + mu_semaphore start; + mu_semaphore stop; + mu_thread thread; } worker_t; static char *output = NULL; @@ -625,9 +433,9 @@ static struct { int solo; int status; fz_context *ctx; - THREAD thread; - SEMAPHORE start; - SEMAPHORE stop; + mu_thread thread; + mu_semaphore start; + mu_semaphore stop; int pagenum; char *filename; render_details render; @@ -668,7 +476,7 @@ static void usage(void) "\t-f\tfit file to page if too large\n" "\t-B -\tminimum band height (e.g. 32)\n" "\t-M -\tmax bandmemory (e.g. 655360)\n" -#if MURASTER_THREADS != 0 +#ifndef DISABLE_MUTHREADS "\t-T -\tnumber of threads to use for rendering\n" "\t-P\tparallel interpretation/rendering\n" #endif @@ -780,7 +588,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de fz_set_pixmap_resolution(ctx, w->pix, x_resolution, y_resolution); DEBUG_THREADS(("Worker %d, Pre-triggering band %d\n", band, band)); w->started = 1; - SEMAPHORE_TRIGGER(w->start); + mu_trigger_semaphore(&w->start); ctm.f -= band_height; } pix = workers[0].pix; @@ -805,7 +613,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de { worker_t *w = &workers[band % render->num_workers]; DEBUG_THREADS(("Waiting for worker %d to complete band %d\n", w->num, band)); - SEMAPHORE_WAIT(w->stop); + mu_wait_semaphore(&w->stop); w->started = 0; status = w->status; pix = w->pix; @@ -840,7 +648,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de memset(&w->cookie, 0, sizeof(fz_cookie)); DEBUG_THREADS(("Triggering worker %d for band_start= %d\n", w->num, w->band_start)); w->started = 1; - SEMAPHORE_TRIGGER(w->start); + mu_trigger_semaphore(&w->start); } ctm.f -= draw_height; } @@ -858,7 +666,7 @@ static int dodrawpage(fz_context *ctx, int pagenum, fz_cookie *cookie, render_de w->cookie.abort = 1; if (w->started) { - SEMAPHORE_WAIT(w->stop); + mu_wait_semaphore(&w->stop); w->started = 0; } fz_drop_pixmap(ctx, w->pix); @@ -1011,7 +819,7 @@ static int wait_for_bgprint_to_finish(void) if (!bgprint.active || !bgprint.started) return 0; - SEMAPHORE_WAIT(bgprint.stop); + mu_wait_semaphore(&bgprint.stop); bgprint.started = 0; return bgprint.status; } @@ -1336,7 +1144,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) } bgprint.started = 1; bgprint.solo = 1; - SEMAPHORE_TRIGGER(bgprint.start); + mu_trigger_semaphore(&bgprint.start); status = wait_for_bgprint_to_finish(); if (status != 0) { @@ -1359,7 +1167,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum) bgprint.filename = filename; bgprint.pagenum = pagenum; bgprint.interptime = start; - SEMAPHORE_TRIGGER(bgprint.start); + mu_trigger_semaphore(&bgprint.start); } else { @@ -1396,7 +1204,7 @@ finish_bgprint(fz_context *ctx) } bgprint.started = 1; bgprint.solo = 1; - SEMAPHORE_TRIGGER(bgprint.start); + mu_trigger_semaphore(&bgprint.start); status = wait_for_bgprint_to_finish(); if (status != 0) { @@ -1484,27 +1292,26 @@ trace_realloc(void *arg, void *p_, size_t size) return &p[1]; } -#if MURASTER_THREADS != 0 -static THREAD_RETURN_TYPE worker_thread(void *arg) +#ifndef DISABLE_MUTHREADS +static void worker_thread(void *arg) { worker_t *me = (worker_t *)arg; do { DEBUG_THREADS(("Worker %d waiting\n", me->num)); - SEMAPHORE_WAIT(me->start); + mu_wait_semaphore(&me->start); DEBUG_THREADS(("Worker %d woken for band_start %d\n", me->num, me->band_start)); me->status = RENDER_OK; if (me->band_start >= 0) me->status = drawband(me->ctx, NULL, me->list, &me->ctm, &me->tbounds, &me->cookie, me->band_start, me->pix, &me->bit); DEBUG_THREADS(("Worker %d completed band_start %d (status=%d)\n", me->num, me->band_start, me->status)); - SEMAPHORE_TRIGGER(me->stop); + mu_trigger_semaphore(&me->stop); } while (me->band_start >= 0); - THREAD_RETURN(); } -static THREAD_RETURN_TYPE bgprint_worker(void *arg) +static void bgprint_worker(void *arg) { fz_cookie cookie = { 0 }; int pagenum; @@ -1514,7 +1321,7 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg) do { DEBUG_THREADS(("BGPrint waiting\n")); - SEMAPHORE_WAIT(bgprint.start); + mu_wait_semaphore(&bgprint.start); pagenum = bgprint.pagenum; DEBUG_THREADS(("BGPrint woken for pagenum %d\n", pagenum)); if (pagenum >= 0) @@ -1524,10 +1331,9 @@ static THREAD_RETURN_TYPE bgprint_worker(void *arg) bgprint.status = try_render_page(bgprint.ctx, pagenum, &cookie, start, bgprint.interptime, bgprint.filename, 1, bgprint.solo, &bgprint.render); } DEBUG_THREADS(("BGPrint completed page %d\n", pagenum)); - SEMAPHORE_TRIGGER(bgprint.stop); + mu_trigger_semaphore(&bgprint.stop); } while (pagenum >= 0); - THREAD_RETURN(); } #endif @@ -1576,9 +1382,10 @@ int main(int argc, char **argv) { char *password = ""; fz_document *doc = NULL; - int c, i; + int i, c; fz_context *ctx; fz_alloc_context alloc_ctx = { NULL, trace_malloc, trace_realloc, trace_free }; + fz_locks_context *locks = NULL; fz_var(doc); @@ -1666,7 +1473,16 @@ int main(int argc, char **argv) exit(1); } - ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), LOCKS_INIT(), FZ_STORE_DEFAULT); +#ifndef DISABLE_MUTHREADS + locks = init_muraster_locks(); + if (locks == NULL) + { + fprintf(stderr, "cannot initialise mutexes\n"); + exit(1); + } +#endif + + ctx = fz_new_context((showmemory == 0 ? NULL : &alloc_ctx), locks, FZ_STORE_DEFAULT); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); @@ -1676,26 +1492,40 @@ int main(int argc, char **argv) fz_set_text_aa_level(ctx, alphabits_text); fz_set_graphics_aa_level(ctx, alphabits_graphics); +#ifndef DISABLE_MUTHREADS if (bgprint.active) { + int fail = 0; bgprint.ctx = fz_clone_context(ctx); - SEMAPHORE_INIT(bgprint.start); - SEMAPHORE_INIT(bgprint.stop); - THREAD_INIT(bgprint.thread, bgprint_worker, NULL); + fail |= mu_create_semaphore(&bgprint.start); + fail |= mu_create_semaphore(&bgprint.stop); + fail |= mu_create_thread(&bgprint.thread, bgprint_worker, NULL); + if (fail) + { + fprintf(stderr, "bgprint startup failed\n"); + exit(1); + } } if (num_workers > 0) { + int fail = 0; workers = fz_calloc(ctx, num_workers, sizeof(*workers)); for (i = 0; i < num_workers; i++) { workers[i].ctx = fz_clone_context(ctx); workers[i].num = i; - SEMAPHORE_INIT(workers[i].start); - SEMAPHORE_INIT(workers[i].stop); - THREAD_INIT(workers[i].thread, worker_thread, &workers[i]); + fail |= mu_create_semaphore(&workers[i].start); + fail |= mu_create_semaphore(&workers[i].stop); + fail |= mu_create_thread(&workers[i].thread, worker_thread, &workers[i]); + } + if (fail) + { + fprintf(stderr, "worker startup failed\n"); + exit(1); } } +#endif /* DISABLE_MUTHREADS */ if (layoutput_css) { @@ -1830,16 +1660,17 @@ int main(int argc, char **argv) fprintf(stderr, "slowest page %d: %dms\n", timing.maxpage, timing.max); } +#ifndef DISABLE_MUTHREADS if (num_workers > 0) { for (i = 0; i < num_workers; i++) { workers[i].band_start = -1; - SEMAPHORE_TRIGGER(workers[i].start); - SEMAPHORE_WAIT(workers[i].stop); - SEMAPHORE_FIN(workers[i].start); - SEMAPHORE_FIN(workers[i].stop); - THREAD_FIN(workers[i].thread); + mu_trigger_semaphore(&workers[i].start); + mu_wait_semaphore(&workers[i].stop); + mu_destroy_semaphore(&workers[i].start); + mu_destroy_semaphore(&workers[i].stop); + mu_destroy_thread(&workers[i].thread); fz_drop_context(workers[i].ctx); } fz_free(ctx, workers); @@ -1848,19 +1679,22 @@ int main(int argc, char **argv) if (bgprint.active) { bgprint.pagenum = -1; - SEMAPHORE_TRIGGER(bgprint.start); - SEMAPHORE_WAIT(bgprint.stop); - SEMAPHORE_FIN(bgprint.start); - SEMAPHORE_FIN(bgprint.stop); - THREAD_FIN(bgprint.thread); + mu_trigger_semaphore(&bgprint.start); + mu_wait_semaphore(&bgprint.stop); + mu_destroy_semaphore(&bgprint.start); + mu_destroy_semaphore(&bgprint.stop); + mu_destroy_thread(&bgprint.thread); fz_drop_context(bgprint.ctx); } +#endif /* DISABLE_MUTHREADS */ fz_drop_output(ctx, out); out = NULL; fz_drop_context(ctx); - LOCKS_FIN(); +#ifndef DISABLE_MUTHREADS + fin_muraster_locks(); +#endif /* DISABLE_MUTHREADS */ if (showmemory) { |