{"thread":{"id":"22435","subject":"threaded-grep cause msys build failure","startedAt":"2010-01-29T10:27:02Z","lastAt":"2010-01-30T10:50:04Z","messageCount":10,"participants":["Zoltán Füzesi","Johannes Sixt","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"132946","messageId":"9ab80d151001290227u386616c5o6c825ff10d37f9fd@mail.gmail.com","threadId":"22435","inReplyTo":null,"subject":"threaded-grep cause msys build failure","fromName":"Zoltán Füzesi","fromEmail":"zfuzesi@eaglet.hu","sentAt":"2010-01-29T10:27:02Z","receivedAt":"2010-01-29T10:27:02Z","isPatch":false,"sender":{"key":"zfuzesi@eaglet.hu","avatar":null},"body":"Hi,\n\nBuilding git in msys environment fails:\n...\n    LINK git.exe\nbuiltin-grep.o: In function `wait_all':\nD:\\devel\\msysgit\\git/builtin-grep.c:260: undefined reference to\n`pthread_cond_broadcast'\ncollect2: ld returned 1 exit status\nmake: *** [git.exe] Error 1\n\nI guess compat/win32/pthread.c misses pthread_cond_broadcast implementation.\n\nZé\n"},{"id":"132954","messageId":"4B62CEAB.5050608@viscovery.net","threadId":"22435","inReplyTo":"9ab80d151001290227u386616c5o6c825ff10d37f9fd@mail.gmail.com","subject":"Re: threaded-grep cause msys build failure","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-29T12:03:55Z","receivedAt":"2010-01-29T12:03:55Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Zoltán Füzesi schrieb:\n> Building git in msys environment fails:\n> ...\n>     LINK git.exe\n> builtin-grep.o: In function `wait_all':\n> D:\\devel\\msysgit\\git/builtin-grep.c:260: undefined reference to\n> `pthread_cond_broadcast'\n\nUse this. I'll try to find a better solution over the weekend.\n\ndiff --git a/Makefile b/Makefile\nindex c591d70..bbee373 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -183,6 +183,9 @@ all::\n # Define THREADED_DELTA_SEARCH if you have pthreads and wish to exploit\n # parallel delta searching when packing objects.\n #\n+# Define THREADED_GREP if you have pthreads and wish to exploit a\n+# parallelized grep.\n+#\n # Define INTERNAL_QSORT to use Git's implementation of qsort(), which\n # is a simplified version of the merge sort used in glibc. This is\n # recommended if Git triggers O(n^2) behavior in your platform's qsort().\n@@ -723,11 +726,13 @@ ifeq ($(uname_S),Linux)\n \tNO_STRLCPY = YesPlease\n \tNO_MKSTEMPS = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n endif\n ifeq ($(uname_S),GNU/kFreeBSD)\n \tNO_STRLCPY = YesPlease\n \tNO_MKSTEMPS = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n endif\n ifeq ($(uname_S),UnixWare)\n \tCC = cc\n@@ -782,6 +787,7 @@ ifeq ($(uname_S),Darwin)\n \tendif\n \tNO_MEMMEM = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n \tUSE_ST_TIMESPEC = YesPlease\n endif\n ifeq ($(uname_S),SunOS)\n@@ -795,6 +801,7 @@ ifeq ($(uname_S),SunOS)\n \tNO_MKSTEMPS = YesPlease\n \tNO_REGEX = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n \tifeq ($(uname_R),5.7)\n \t\tNEEDS_RESOLV = YesPlease\n \t\tNO_IPV6 = YesPlease\n@@ -851,6 +858,7 @@ ifeq ($(uname_S),FreeBSD)\n \tDIR_HAS_BSD_GROUP_SEMANTICS = YesPlease\n \tUSE_ST_TIMESPEC = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n \tifeq ($(shell expr \"$(uname_R)\" : '4\\.'),2)\n \t\tPTHREAD_LIBS = -pthread\n \t\tNO_UINTMAX_T = YesPlease\n@@ -865,6 +873,7 @@ ifeq ($(uname_S),OpenBSD)\n \tBASIC_CFLAGS += -I/usr/local/include\n \tBASIC_LDFLAGS += -L/usr/local/lib\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n endif\n ifeq ($(uname_S),NetBSD)\n \tifeq ($(shell expr \"$(uname_R)\" : '[01]\\.'),2)\n@@ -873,6 +882,7 @@ ifeq ($(uname_S),NetBSD)\n \tBASIC_CFLAGS += -I/usr/pkg/include\n \tBASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n \tUSE_ST_TIMESPEC = YesPlease\n \tNO_MKSTEMPS = YesPlease\n endif\n@@ -889,6 +899,7 @@ ifeq ($(uname_S),AIX)\n \tBASIC_CFLAGS += -D_LARGE_FILES\n \tifneq ($(shell expr \"$(uname_V)\" : '[1234]'),1)\n \t\tTHREADED_DELTA_SEARCH = YesPlease\n+\t\tTHREADED_GREP = YesPlease\n \telse\n \t\tNO_PTHREADS = YesPlease\n \tendif\n@@ -916,6 +927,7 @@ ifeq ($(uname_S),IRIX)\n \tSHELL_PATH = /usr/gnu/bin/bash\n \tNEEDS_LIBGEN = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n endif\n ifeq ($(uname_S),IRIX64)\n \tNO_SETENV=YesPlease\n@@ -935,6 +947,7 @@ ifeq ($(uname_S),IRIX64)\n \tSHELL_PATH=/usr/gnu/bin/bash\n \tNEEDS_LIBGEN = YesPlease\n \tTHREADED_DELTA_SEARCH = YesPlease\n+\tTHREADED_GREP = YesPlease\n endif\n ifeq ($(uname_S),HP-UX)\n \tNO_IPV6=YesPlease\n@@ -1334,6 +1347,7 @@ endif\n\n ifdef NO_PTHREADS\n \tTHREADED_DELTA_SEARCH =\n+\tTHREADED_GREP =\n \tBASIC_CFLAGS += -DNO_PTHREADS\n else\n \tEXTLIBS += $(PTHREAD_LIBS)\n@@ -1341,6 +1355,11 @@ endif\n\n ifdef THREADED_DELTA_SEARCH\n \tBASIC_CFLAGS += -DTHREADED_DELTA_SEARCH\n+endif\n+ifdef THREADED_GREP\n+\tBASIC_CFLAGS += -DTHREADED_GREP\n+endif\n+ifneq (,$(THREADED_GREP)$(THREADED_DELTA_SEARCH))\n \tLIB_OBJS += thread-utils.o\n endif\n ifdef DIR_HAS_BSD_GROUP_SEMANTICS\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex 9bd467c..911d0da 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -16,7 +16,7 @@\n #include \"quote.h\"\n #include \"dir.h\"\n\n-#ifndef NO_PTHREADS\n+#ifdef THREADED_GREP\n #include \"thread-utils.h\"\n #include <pthread.h>\n #endif\n@@ -28,7 +28,7 @@ static char const * const grep_usage[] = {\n\n static int use_threads = 1;\n\n-#ifndef NO_PTHREADS\n+#ifdef THREADED_GREP\n #define THREADS 8\n static pthread_t threads[THREADS];\n\n@@ -274,7 +274,7 @@ static int wait_all(void)\n\n \treturn hit;\n }\n-#else /* !NO_PTHREADS */\n+#else /* THREADED_GREP */\n #define read_sha1_lock()\n #define read_sha1_unlock()\n\n@@ -439,7 +439,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,\n\n \tname = strbuf_detach(&pathbuf, NULL);\n\n-#ifndef NO_PTHREADS\n+#ifdef THREADED_GREP\n \tif (use_threads) {\n \t\tgrep_sha1_async(opt, name, sha1);\n \t\treturn 0;\n@@ -501,7 +501,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)\n \t\tstrbuf_addstr(&buf, filename);\n \tname = strbuf_detach(&buf, NULL);\n\n-#ifndef NO_PTHREADS\n+#ifdef THREADED_GREP\n \tif (use_threads) {\n \t\tgrep_file_async(opt, name, filename);\n \t\treturn 0;\n@@ -902,7 +902,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)\n \tif ((opt.regflags != REG_NEWLINE) && opt.fixed)\n \t\tdie(\"cannot mix --fixed-strings and regexp\");\n\n-#ifndef NO_PTHREADS\n+#ifdef THREADED_GREP\n \tif (online_cpus() == 1 || !grep_threads_ok(&opt))\n \t\tuse_threads = 0;\n\n-- \n1.7.0.rc0.1096.g3300c.dirty\n"},{"id":"132980","messageId":"1264793213-8805-1-git-send-email-zfuzesi@eaglet.hu","threadId":"22435","inReplyTo":"4B62CEAB.5050608@viscovery.net","subject":"[RFC/PATCH] MSVC: Windows-native implementation of pthread_cond_broadcast","fromName":"Zoltán Füzesi","fromEmail":"zfuzesi@eaglet.hu","sentAt":"2010-01-29T19:26:53Z","receivedAt":"2010-01-29T19:26:53Z","isPatch":true,"sender":{"key":"zfuzesi@eaglet.hu","avatar":null},"body":"Threaded grep feature relies on this function, but its implementation was\nmissing from the Win32 Pthreads API.\n\nSigned-off-by: Zoltán Füzesi <zfuzesi@eaglet.hu>\n---\nJohannes, how about this? I haven't tested it.\n\n compat/win32/pthread.c |   12 ++++++++++++\n compat/win32/pthread.h |    2 ++\n 2 files changed, 14 insertions(+), 0 deletions(-)\n\ndiff --git a/compat/win32/pthread.c b/compat/win32/pthread.c\nindex 631c0a4..498b552 100644\n--- a/compat/win32/pthread.c\n+++ b/compat/win32/pthread.c\n@@ -108,3 +108,15 @@ int pthread_cond_signal(pthread_cond_t *cond)\n \telse\n \t\treturn 0;\n }\n+\n+int pthread_cond_broadcast(pthread_cond_t *cond)\n+{\n+\tLONG prev_count;\n+\twhile (cond->waiters) {\n+\t\tif (!ReleaseSemaphore(cond->sema, 1, &prev_count))\n+\t\t\treturn err_win_to_posix(GetLastError());\n+\t\tif (prev_count == LONG_MAX - 1)\n+\t\t\tbreak;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/compat/win32/pthread.h b/compat/win32/pthread.h\nindex b8e1bcb..11426f5 100644\n--- a/compat/win32/pthread.h\n+++ b/compat/win32/pthread.h\n@@ -44,6 +44,8 @@ extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);\n \n extern int pthread_cond_signal(pthread_cond_t *cond);\n \n+extern int pthread_cond_broadcast(pthread_cond_t *cond);\n+\n /*\n  * Simple thread creation implementation using pthread API\n  */\n-- \n1.7.0.rc0.48.gdace5.dirty\n"},{"id":"132982","messageId":"201001292102.49105.j6t@kdbg.org","threadId":"22435","inReplyTo":"1264793213-8805-1-git-send-email-zfuzesi@eaglet.hu","subject":"Re: [RFC/PATCH] MSVC: Windows-native implementation of pthread_cond_broadcast","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-01-29T20:02:49Z","receivedAt":"2010-01-29T20:02:49Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Freitag, 29. Januar 2010, Zoltán Füzesi wrote:\n> Johannes, how about this? I haven't tested it.\n\nNeither have I, but I do not expect that it work: You neither modify the \nwaiters count nor do you wait for it to be modified; IOW, you have a busy \nloop. cond_broadcast is not that trivial. I hope to send a patch tonight.\n\n-- Hannes\n"},{"id":"132984","messageId":"alpine.DEB.1.00.1001292111350.3749@intel-tinevez-2-302","threadId":"22435","inReplyTo":"1264793213-8805-1-git-send-email-zfuzesi@eaglet.hu","subject":"Re: [RFC/PATCH] MSVC: Windows-native implementation of pthread_cond_broadcast","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-29T20:13:10Z","receivedAt":"2010-01-29T20:13:10Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 29 Jan 2010, Zoltán Füzesi wrote:\n\n> Johannes, how about this?\n\nDo you really mean me?\n\n> I haven't tested it.\n\nThen why the hell do you address me????\n\nSeriously again, please test first before you post this. Once you have \nreal proof that it works as you intend it, I will be _happy_ to have a \nlook and most likely merge it into 4msysgit.git.  Before you tested it, I \nwill be just annoyed.\n\nThanks for your work,\nDscho"},{"id":"133023","messageId":"201001292316.03858.j6t@kdbg.org","threadId":"22435","inReplyTo":"201001292102.49105.j6t@kdbg.org","subject":"[PATCH] Windows: a minimal pthread_cond_broadcast","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-01-29T22:16:03Z","receivedAt":"2010-01-29T22:16:03Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"[Cc msysgit list]\n\nOn Freitag, 29. Januar 2010, Johannes Sixt wrote:\n> cond_broadcast is not that trivial.\n\n... except when it can be tailor-made for a particular use-case.\nWhat do people think about this?\n\nI had implemented a full-blown pthread_cond_broadcast, taking ACE as\nan example, but I had doubts about its correctness. Then I noticed that\nwe do not need a complete implementation anyway. So here we go...\n\n--- 8< ---\nFrom: Johannes Sixt <j6t@kdbg.org>\nSubject: [PATCH] Windows: a minimal pthread_cond_broadcast\n\nThis is not an implementation, but more a fake of pthread_cond_broadcast.\nIt is sufficient for the only call site in builtin-grep.c that we have\nat this time. It works because the threads that wake up due to this call\ndo not call pthread_cond_wait anymore and terminate.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n compat/win32/pthread.c |   10 ++++++++++\n compat/win32/pthread.h |    4 +---\n 2 files changed, 11 insertions(+), 3 deletions(-)\n\ndiff --git a/compat/win32/pthread.c b/compat/win32/pthread.c\nindex 631c0a4..7b5cac1 100644\n--- a/compat/win32/pthread.c\n+++ b/compat/win32/pthread.c\n@@ -108,3 +108,13 @@ int pthread_cond_signal(pthread_cond_t *cond)\n \telse\n \t\treturn 0;\n }\n+\n+/*\n+ * FIXME: This is a fake implementation that is tailored for the only\n+ * user that we currently have.\n+ */\n+int pthread_cond_broadcast(pthread_cond_t *cond)\n+{\n+\tReleaseSemaphore(cond->sema, cond->waiters, NULL);\n+\treturn 0;\n+}\ndiff --git a/compat/win32/pthread.h b/compat/win32/pthread.h\nindex b8e1bcb..7c360d5 100644\n--- a/compat/win32/pthread.h\n+++ b/compat/win32/pthread.h\n@@ -37,12 +37,10 @@ typedef struct {\n } pthread_cond_t;\n \n extern int pthread_cond_init(pthread_cond_t *cond, const void *unused);\n-\n extern int pthread_cond_destroy(pthread_cond_t *cond);\n-\n extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);\n-\n extern int pthread_cond_signal(pthread_cond_t *cond);\n+extern int pthread_cond_broadcast(pthread_cond_t *cond);\n \n /*\n  * Simple thread creation implementation using pthread API\n-- \n1.6.6.264.ga6155\n"},{"id":"133042","messageId":"201001300054.05610.j6t@kdbg.org","threadId":"22435","inReplyTo":"201001292316.03858.j6t@kdbg.org","subject":"[PATCH] Implement pthread_cond_broadcast on Windows","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-01-29T23:54:05Z","receivedAt":"2010-01-29T23:54:05Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"See http://www.cse.wustl.edu/~schmidt/win32-cv-1.html, section \"The\nSignalObjectAndWait solution\". But note that this implementation does not\nuse SignalObjectAndWait (which is needed to achieve fairness, but we do\nnot need fairness).\n\nNote that our implementations of pthread_cond_broadcast and\npthread_cond_signal require that they are invoked with the mutex held that\nis used in the pthread_cond_wait calls.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n Junio,\n\n please queue this patch for 1.7.0-rc1 even though it has not undergone\n a lot of review - the result is better than a git that does not even\n build on Windows.\n\n I had another look at this complete implementation of p_c_b and am now\n convinced that it is correct, but an extra set of eye-balls is always\n appreciated. I've Cc'd people who had shown interest in pthreads on\n Windows in the past.\n\n -- Hannes\n\n compat/win32/pthread.c |  100 ++++++++++++++++++++++++++++++++++++++++++-----\n compat/win32/pthread.h |    9 ++--\n 2 files changed, 94 insertions(+), 15 deletions(-)\n\ndiff --git a/compat/win32/pthread.c b/compat/win32/pthread.c\nindex 631c0a4..e592084 100644\n--- a/compat/win32/pthread.c\n+++ b/compat/win32/pthread.c\n@@ -52,24 +52,38 @@ int win32_pthread_join(pthread_t *thread, void **value_ptr)\n int pthread_cond_init(pthread_cond_t *cond, const void *unused)\n {\n \tcond->waiters = 0;\n+\tcond->was_broadcast = 0;\n+\tInitializeCriticalSection(&cond->waiters_lock);\n \n \tcond->sema = CreateSemaphore(NULL, 0, LONG_MAX, NULL);\n \tif (!cond->sema)\n \t\tdie(\"CreateSemaphore() failed\");\n+\n+\tcond->continue_broadcast = CreateEvent(NULL,\t/* security */\n+\t\t\t\tFALSE,\t\t\t/* auto-reset */\n+\t\t\t\tFALSE,\t\t\t/* not signaled */\n+\t\t\t\tNULL);\t\t\t/* name */\n+\tif (!cond->continue_broadcast)\n+\t\tdie(\"CreateEvent() failed\");\n+\n \treturn 0;\n }\n \n int pthread_cond_destroy(pthread_cond_t *cond)\n {\n \tCloseHandle(cond->sema);\n-\tcond->sema = NULL;\n-\n+\tCloseHandle(cond->continue_broadcast);\n+\tDeleteCriticalSection(&cond->waiters_lock);\n \treturn 0;\n }\n \n int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)\n {\n-\tInterlockedIncrement(&cond->waiters);\n+\tint last_waiter;\n+\n+\tEnterCriticalSection(&cond->waiters_lock);\n+\tcond->waiters++;\n+\tLeaveCriticalSection(&cond->waiters_lock);\n \n \t/*\n \t * Unlock external mutex and wait for signal.\n@@ -82,22 +96,52 @@ int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex)\n \t/* let's wait - ignore return value */\n \tWaitForSingleObject(cond->sema, INFINITE);\n \n-\t/* we're done waiting, so make sure we decrease waiters count */\n-\tInterlockedDecrement(&cond->waiters);\n-\n+\t/*\n+\t * Decrease waiters count. If we are the last waiter, then we must\n+\t * notify the broadcasting thread that it can continue.\n+\t * But if we continued due to cond_signal, we do not have to do that\n+\t * because the signaling thread knows that only one waiter continued.\n+\t */\n+\tEnterCriticalSection(&cond->waiters_lock);\n+\tcond->waiters--;\n+\tlast_waiter = cond->was_broadcast && cond->waiters == 0;\n+\tLeaveCriticalSection(&cond->waiters_lock);\n+\n+\tif (last_waiter) {\n+\t\t/*\n+\t\t * cond_broadcast was issued while mutex was held. This means\n+\t\t * that all other waiters have continued, but are contending\n+\t\t * for the mutex at the end of this function because the\n+\t\t * broadcasting thread did not leave cond_broadcast, yet.\n+\t\t * (This is so that it can be sure that each waiter has\n+\t\t * consumed exactly one slice of the semaphor.)\n+\t\t * The last waiter must tell the broadcasting thread that it\n+\t\t * can go on.\n+\t\t */\n+\t\tSetEvent(cond->continue_broadcast);\n+\t\t/*\n+\t\t * Now we go on to contend with all other waiters for\n+\t\t * the mutex. Auf in den Kampf!\n+\t\t */\n+\t}\n \t/* lock external mutex again */\n \tEnterCriticalSection(mutex);\n \n \treturn 0;\n }\n \n+/*\n+ * IMPORTANT: This implementation requires that pthread_cond_signal\n+ * is called while the mutex is held that is used in the corresponding\n+ * pthread_cond_wait calls!\n+ */\n int pthread_cond_signal(pthread_cond_t *cond)\n {\n-\t/*\n-\t * Access to waiters count is atomic; see \"Interlocked Variable Access\"\n-\t * http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx\n-\t */\n-\tint have_waiters = cond->waiters > 0;\n+\tint have_waiters;\n+\t\n+\tEnterCriticalSection(&cond->waiters_lock);\n+\thave_waiters = cond->waiters > 0;\n+\tLeaveCriticalSection(&cond->waiters_lock);\n \n \t/*\n \t * Signal only when there are waiters\n@@ -108,3 +152,37 @@ int pthread_cond_signal(pthread_cond_t *cond)\n \telse\n \t\treturn 0;\n }\n+\n+/*\n+ * DOUBLY IMPORTANT: This implementation requires that pthread_cond_broadcast\n+ * is called while the mutex is held that is used in the corresponding\n+ * pthread_cond_wait calls!\n+ */\n+int pthread_cond_broadcast(pthread_cond_t *cond)\n+{\n+\tEnterCriticalSection(&cond->waiters_lock);\n+\n+\tif ((cond->was_broadcast = cond->waiters > 0)) {\n+\t\t/* wake up all waiters */\n+\t\tReleaseSemaphore(cond->sema, cond->waiters, NULL);\n+\t\tLeaveCriticalSection(&cond->waiters_lock);\n+\t\t/*\n+\t\t * At this point all waiters continue. Each one takes its\n+\t\t * slice of the semaphor. Now it's our turn to wait: Since\n+\t\t * the external mutex is held, no thread can leave cond_wait,\n+\t\t * yet. For this reason, we can be sure that no thread gets\n+\t\t * a chance to eat *more* than one slice. OTOH, it means\n+\t\t * that the last waiter must send us a wake-up.\n+\t\t */\n+\t\tWaitForSingleObject(cond->continue_broadcast, INFINITE);\n+\t\t/*\n+\t\t * Since the external mutex is held, no thread can enter\n+\t\t * cond_wait, and, hence, it is safe to reset this flag\n+\t\t * without cond->waiters_lock held.\n+\t\t */\n+\t\tcond->was_broadcast = 0;\n+\t} else {\n+\t\tLeaveCriticalSection(&cond->waiters_lock);\n+\t}\n+\treturn 0;\n+}\ndiff --git a/compat/win32/pthread.h b/compat/win32/pthread.h\nindex b8e1bcb..c72f100 100644\n--- a/compat/win32/pthread.h\n+++ b/compat/win32/pthread.h\n@@ -32,17 +32,18 @@\n  * See also: http://www.cse.wustl.edu/~schmidt/win32-cv-1.html\n  */\n typedef struct {\n-\tvolatile LONG waiters;\n+\tLONG waiters;\n+\tint was_broadcast;\n+\tCRITICAL_SECTION waiters_lock;\n \tHANDLE sema;\n+\tHANDLE continue_broadcast;\n } pthread_cond_t;\n \n extern int pthread_cond_init(pthread_cond_t *cond, const void *unused);\n-\n extern int pthread_cond_destroy(pthread_cond_t *cond);\n-\n extern int pthread_cond_wait(pthread_cond_t *cond, CRITICAL_SECTION *mutex);\n-\n extern int pthread_cond_signal(pthread_cond_t *cond);\n+extern int pthread_cond_broadcast(pthread_cond_t *cond);\n \n /*\n  * Simple thread creation implementation using pthread API\n-- \n1.6.6.264.ga6155\n"},{"id":"133065","messageId":"alpine.DEB.1.00.1001300328070.3749@intel-tinevez-2-302","threadId":"22435","inReplyTo":"201001300054.05610.j6t@kdbg.org","subject":"Re: [PATCH] Implement pthread_cond_broadcast on Windows","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-30T02:28:43Z","receivedAt":"2010-01-30T02:28:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jan 2010, Johannes Sixt wrote:\n\n> See http://www.cse.wustl.edu/~schmidt/win32-cv-1.html, section \"The\n> SignalObjectAndWait solution\". But note that this implementation does not\n> use SignalObjectAndWait (which is needed to achieve fairness, but we do\n> not need fairness).\n> \n> Note that our implementations of pthread_cond_broadcast and\n> pthread_cond_signal require that they are invoked with the mutex held that\n> is used in the pthread_cond_wait calls.\n> \n> Signed-off-by: Johannes Sixt <j6t@kdbg.org>\n> ---\n>  Junio,\n> \n>  please queue this patch for 1.7.0-rc1 even though it has not undergone\n>  a lot of review - the result is better than a git that does not even\n>  build on Windows.\n\nAs you Cc:ed the msysGit list, do you want this in 4msysgit.git, too?\n\nCiao,\nDscho\n"},{"id":"133110","messageId":"201001301030.36395.j6t@kdbg.org","threadId":"22435","inReplyTo":"alpine.DEB.1.00.1001300328070.3749@intel-tinevez-2-302","subject":"Re: [PATCH] Implement pthread_cond_broadcast on Windows","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-01-30T09:30:36Z","receivedAt":"2010-01-30T09:30:36Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Samstag, 30. Januar 2010, Johannes Schindelin wrote:\n> Hi,\n>\n> On Sat, 30 Jan 2010, Johannes Sixt wrote:\n> > See http://www.cse.wustl.edu/~schmidt/win32-cv-1.html, section \"The\n> > SignalObjectAndWait solution\". But note that this implementation does not\n> > use SignalObjectAndWait (which is needed to achieve fairness, but we do\n> > not need fairness).\n> >\n> > Note that our implementations of pthread_cond_broadcast and\n> > pthread_cond_signal require that they are invoked with the mutex held\n> > that is used in the pthread_cond_wait calls.\n> >\n> > Signed-off-by: Johannes Sixt <j6t@kdbg.org>\n> > ---\n> >  Junio,\n> >\n> >  please queue this patch for 1.7.0-rc1 even though it has not undergone\n> >  a lot of review - the result is better than a git that does not even\n> >  build on Windows.\n>\n> As you Cc:ed the msysGit list, do you want this in 4msysgit.git, too?\n\nI hope some clever people on the msysgit list can say aye or nay to this \npatch. If you intend to release an msysgit that contains 5b594f4 (Threaded \ngrep), then you need *something*, otherwise the build fails. Whether you get \nthat something via upstream or apply it directly is of course secondary, but \nI prefer the former. ;)\n\n-- Hannes\n"},{"id":"133111","messageId":"alpine.DEB.1.00.1001301149030.4985@pacific.mpi-cbg.de","threadId":"22435","inReplyTo":"201001301030.36395.j6t@kdbg.org","subject":"Re: [PATCH] Implement pthread_cond_broadcast on Windows","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-30T10:50:04Z","receivedAt":"2010-01-30T10:50:04Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 30 Jan 2010, Johannes Sixt wrote:\n\n> On Samstag, 30. Januar 2010, Johannes Schindelin wrote:\n>\n> > On Sat, 30 Jan 2010, Johannes Sixt wrote:\n> > > See http://www.cse.wustl.edu/~schmidt/win32-cv-1.html, section \"The \n> > > SignalObjectAndWait solution\". But note that this implementation \n> > > does not use SignalObjectAndWait (which is needed to achieve \n> > > fairness, but we do not need fairness).\n> > >\n> > > Note that our implementations of pthread_cond_broadcast and \n> > > pthread_cond_signal require that they are invoked with the mutex \n> > > held that is used in the pthread_cond_wait calls.\n> > >\n> > > Signed-off-by: Johannes Sixt <j6t@kdbg.org>\n> > > ---\n> > >  Junio,\n> > >\n> > >  please queue this patch for 1.7.0-rc1 even though it has not \n> > >  undergone a lot of review - the result is better than a git that \n> > >  does not even build on Windows.\n> >\n> > As you Cc:ed the msysGit list, do you want this in 4msysgit.git, too?\n> \n> I hope some clever people on the msysgit list can say aye or nay to this \n> patch. If you intend to release an msysgit that contains 5b594f4 \n> (Threaded grep), then you need *something*, otherwise the build fails. \n> Whether you get that something via upstream or apply it directly is of \n> course secondary, but I prefer the former. ;)\n\nOkay, I will just merge mingw.git's master, then, once you say that the \nfix is in.\n\nCiao,\nDscho\n"}]}