src/hb-blob.cc | 2 src/hb-face.cc | 2 src/hb-font.cc | 4 + src/hb-unicode.cc | 2 test/api/Makefile.am | 6 + test/api/test-multithread.c | 142 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 158 insertions(+)
New commits: commit 90a0f9fa0c020c268ac3ba31c7f1337eed85f35e Author: Behdad Esfahbod <[email protected]> Date: Wed Sep 26 15:03:07 2018 -0400 Make TSan happy with make_immutable() diff --git a/src/hb-blob.cc b/src/hb-blob.cc index fca3c910..f0952665 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -293,6 +293,8 @@ hb_blob_make_immutable (hb_blob_t *blob) { if (hb_object_is_inert (blob)) return; + if (blob->immutable) + return; blob->immutable = true; } diff --git a/src/hb-face.cc b/src/hb-face.cc index 19eea4d3..fbab18aa 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -325,6 +325,8 @@ hb_face_make_immutable (hb_face_t *face) { if (unlikely (hb_object_is_inert (face))) return; + if (face->immutable) + return; face->immutable = true; } diff --git a/src/hb-font.cc b/src/hb-font.cc index 9dcf6c12..77762f2d 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -586,6 +586,8 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) { if (unlikely (hb_object_is_inert (ffuncs))) return; + if (ffuncs->immutable) + return; ffuncs->immutable = true; } @@ -1444,6 +1446,8 @@ hb_font_make_immutable (hb_font_t *font) { if (unlikely (hb_object_is_inert (font))) return; + if (font->immutable) + return; if (font->parent) hb_font_make_immutable (font->parent); diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index bb1cd682..0e8b520d 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -308,6 +308,8 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) { if (unlikely (hb_object_is_inert (ufuncs))) return; + if (ufuncs->immutable) + return; ufuncs->immutable = true; } commit 34d5a2595331c568ae524057d031c9d5d2573978 Author: Behdad Esfahbod <[email protected]> Date: Wed Sep 26 15:02:21 2018 -0400 Fix test-multithread and increase num_threads to 30 What were you thinking? ;) diff --git a/test/api/test-multithread.c b/test/api/test-multithread.c index 3a0d8845..b9bcdf86 100644 --- a/test/api/test-multithread.c +++ b/test/api/test-multithread.c @@ -78,7 +78,7 @@ int main (int argc, char **argv) { int i; - int num_threads = 1; // FIXME: Increase this and fix the issue + int num_threads = 30; // FIXME: Increase this and fix the issue pthread_t *threads = calloc (num_threads, sizeof (pthread_t)); hb_buffer_t **buffers = calloc (num_threads, sizeof (hb_buffer_t *)); @@ -99,42 +99,38 @@ main (int argc, char **argv) /* Let them loose! */ pthread_mutex_unlock (&mutex); + hb_buffer_t *ref_buffer = hb_buffer_create (); + fill_the_buffer (ref_buffer); + for (i = 0; i < num_threads; i++) { pthread_join (threads[i], NULL); - - hb_buffer_t *ref_buffer = hb_buffer_create (); - fill_the_buffer (ref_buffer); - - for (i = 0; i < num_threads; i++) + hb_buffer_t *buffer = buffers[i]; + hb_buffer_diff_flags_t diff = hb_buffer_diff (ref_buffer, buffer, (hb_codepoint_t) -1, 0); + if (diff) { - hb_buffer_t *buffer = buffers[i]; - hb_buffer_diff_flags_t diff = hb_buffer_diff (ref_buffer, buffer, (hb_codepoint_t) -1, 0); - if (diff) - { - fprintf (stderr, "One of the buffers (%d) was different from the reference.\n", i); - char out[255]; - - hb_buffer_serialize_glyphs (buffer, 0, hb_buffer_get_length (ref_buffer), - out, sizeof (out), NULL, - font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, - HB_BUFFER_SERIALIZE_FLAG_DEFAULT); - fprintf (stderr, "Actual: %s\n", out); - - hb_buffer_serialize_glyphs (ref_buffer, 0, hb_buffer_get_length (ref_buffer), - out, sizeof (out), NULL, - font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, - HB_BUFFER_SERIALIZE_FLAG_DEFAULT); - fprintf (stderr, "Expected: %s\n", out); - - return 1; - } - hb_buffer_destroy (buffer); + fprintf (stderr, "One of the buffers (%d) was different from the reference.\n", i); + char out[255]; + + hb_buffer_serialize_glyphs (buffer, 0, hb_buffer_get_length (ref_buffer), + out, sizeof (out), NULL, + font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, + HB_BUFFER_SERIALIZE_FLAG_DEFAULT); + fprintf (stderr, "Actual: %s\n", out); + + hb_buffer_serialize_glyphs (ref_buffer, 0, hb_buffer_get_length (ref_buffer), + out, sizeof (out), NULL, + font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, + HB_BUFFER_SERIALIZE_FLAG_DEFAULT); + fprintf (stderr, "Expected: %s\n", out); + + return 1; } - - hb_buffer_destroy (ref_buffer); + hb_buffer_destroy (buffer); } + hb_buffer_destroy (ref_buffer); + free (buffers); free (threads); commit 8bb73dad7f3279e1f1362cf9a137504e8ef08985 Author: Ebrahim Byagowi <[email protected]> Date: Wed Sep 26 20:50:51 2018 +0330 Add a multithreaded test (#1184) diff --git a/test/api/Makefile.am b/test/api/Makefile.am index d92e9669..1c0f92c1 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -76,6 +76,12 @@ TEST_PROGS += \ test-ot-tag \ $(NULL) +if HAVE_PTHREAD +TEST_PROGS += test-multithread +test_multithread_CFLAGS = $(CFLAGS) $(PTHREAD_CFLAGS) +test_multithread_LDADD = $(LDADD) $(PTHREAD_LIBS) +endif + if HAVE_FREETYPE TEST_PROGS += \ test-ot-math \ diff --git a/test/api/test-multithread.c b/test/api/test-multithread.c new file mode 100644 index 00000000..3a0d8845 --- /dev/null +++ b/test/api/test-multithread.c @@ -0,0 +1,146 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#include <pthread.h> + +#include <hb.h> +#include <hb-ot.h> + +const char *text = "طرحنَما"; +const char *path = +#if defined(__linux__) + "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; +#elif defined(_WIN32) || defined(_WIN64) + "C:\\Windows\\Fonts\\tahoma.ttf"; +#elif __APPLE__ + "/Library/Fonts/Tahoma.ttf"; +#endif + +int num_iters = 200; + +hb_font_t *font; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static void +fill_the_buffer(hb_buffer_t *buffer) +{ + hb_buffer_add_utf8 (buffer, text, sizeof (text), 0, sizeof (text)); + hb_buffer_guess_segment_properties (buffer); + hb_shape (font, buffer, NULL, 0); +} + +static void * +thread_func (void *data) +{ + hb_buffer_t *buffer = (hb_buffer_t *) data; + + pthread_mutex_lock (&mutex); + pthread_mutex_unlock (&mutex); + + int i; + for (i = 0; i < num_iters; i++) + { + hb_buffer_clear_contents (buffer); + fill_the_buffer (buffer); + } + + return 0; +} + +int +main (int argc, char **argv) +{ + int i; + int num_threads = 1; // FIXME: Increase this and fix the issue + pthread_t *threads = calloc (num_threads, sizeof (pthread_t)); + hb_buffer_t **buffers = calloc (num_threads, sizeof (hb_buffer_t *)); + + pthread_mutex_lock (&mutex); + + hb_blob_t *blob = hb_blob_create_from_file (path); + hb_face_t *face = hb_face_create (blob, 0); + font = hb_font_create (face); + hb_ot_font_set_funcs (font); + + for (i = 0; i < num_threads; i++) + { + hb_buffer_t *buffer = hb_buffer_create (); + buffers[i] = buffer; + pthread_create (&threads[i], NULL, thread_func, buffer); + } + + /* Let them loose! */ + pthread_mutex_unlock (&mutex); + + for (i = 0; i < num_threads; i++) + { + pthread_join (threads[i], NULL); + + hb_buffer_t *ref_buffer = hb_buffer_create (); + fill_the_buffer (ref_buffer); + + for (i = 0; i < num_threads; i++) + { + hb_buffer_t *buffer = buffers[i]; + hb_buffer_diff_flags_t diff = hb_buffer_diff (ref_buffer, buffer, (hb_codepoint_t) -1, 0); + if (diff) + { + fprintf (stderr, "One of the buffers (%d) was different from the reference.\n", i); + char out[255]; + + hb_buffer_serialize_glyphs (buffer, 0, hb_buffer_get_length (ref_buffer), + out, sizeof (out), NULL, + font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, + HB_BUFFER_SERIALIZE_FLAG_DEFAULT); + fprintf (stderr, "Actual: %s\n", out); + + hb_buffer_serialize_glyphs (ref_buffer, 0, hb_buffer_get_length (ref_buffer), + out, sizeof (out), NULL, + font, HB_BUFFER_SERIALIZE_FORMAT_TEXT, + HB_BUFFER_SERIALIZE_FLAG_DEFAULT); + fprintf (stderr, "Expected: %s\n", out); + + return 1; + } + hb_buffer_destroy (buffer); + } + + hb_buffer_destroy (ref_buffer); + } + + free (buffers); + free (threads); + + hb_font_destroy (font); + hb_face_destroy (face); + hb_blob_destroy (blob); + + return 0; +} _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
