Mail Archives: cygwin/2001/04/10/16:41:22
----- Original Message -----
From: "René Mřller Fonseca" <fonseca AT mip DOT sdu DOT dk>
To: "Robert Collins" <robert DOT collins AT itdomain DOT com DOT au>
Cc: <cygwin AT cygwin DOT com>
Sent: Tuesday, April 10, 2001 7:05 PM
Subject: Re: contribution soapbox(was Re: G++ guru's please comment -
Re: FW: pthread_create problem in Cygwin 1.1.8-2])
> Hi again,
>
> I wasn't aware of the Interlocked functions.
>
> I just examined the documentation for InterlockedIncrement and it
states
> that the variables must be aligned on a 32-bit boundary.
>
> On Solaris the error code EINVAL is returned if either once_control or
> init_routine is NULL. You should consider returning EINVAL (or other
> appropriate error code) if once_contol isn't 32 bit aligned.
>
> >>>>
> int __pthread_once (pthread_once_t * once_control, void
(*init_routine)
> (void))
> {
> if ((once_control & 0x03) != 0) { // must be checked before use of
> Interlocked...
> return EINVAL;
> }
> if (InterlockedDecrement(once_control)!=0)
> {
> InterlockIncrement(once_control);
> return 0;
> }
> init_routine();
> /* cancel test will go here when canceability states are
implemneted
> */
> /* if (init_routine was canceled)
> InterlockIncrement(once_control); */
> return 0;
> }
> <<<<
>
> I do not understand why other threads should not block until
> init_routine has been completed. The few uses of pthread_once that I
> have seen allocate resources and initializes variables that are
required
> to be correct after pthread_once has completed, for the following code
> the work correctly. If a thread could return from pthread_once without
> an error and before init_routine was invoked then the code wouldn't
> work. I can't direct you to the code I'm refering to 'cause I can't
> remember where I seen it, sorry.
What if the init_routine deadlocks? If the other threads are blocked the
program cannot cancel the init routine. Blocking each thread that
chooses to call pthread_once makes more sense to me.
I'm happy to make the function behave compatibly with (insert open
source O/S name here). If you write a small test program, and run on
linux/*BSD and report back with the results and the test program, I'll
adjust the code. Until then, my call is "other threads don't block".
And no, I can't just look at the BSD/Linux source code and decide -
cygwin itself isn't open source compatible because of the need to
release a commercial variant. Thus the need for test cases.
> I did a man pthread_once on a machine running Irix 6.5. and came up
with
> this:
>
> >>>>>
> C SYNOPSIS
> #include <pthread.h>
>
> int pthread_once(pthread_once_t *once, void (*init)(void));
>
> DESCRIPTION
> The pthread_once() function ensures that the function init is
> called
> exactly once for all callers using the once initialization
> variable.
> This variable is initialized with the constant PTHREAD_ONCE_INIT.
> While
> init is being executed all callers of pthread_once() will wait.
The doc's I'm coding off
(http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_once.html)
don't mention the wait. As I've indicated I'm happy to change what's
written to be more compatible. I would appreciate an actual test result
and test program. Also for efficiency I think only calls to pthread_once
with the same once parameter should block. Calls with a different once
parameter should proceed uninhibited. (If you do a test prog, that would
be a good test - have two separate once variables and see whether both
callers hit the init routine at the same time).
> If a thread is cancelled while executing the init function [see
> pthread_setcancelstate()], then pthread_once() will permit
another
> thread
> (possibly waiting) to make the call.
> <<<<<
>
> I have also found this:
>
http://lithos.gat.com/software/alpha/AA-Q2DPC-TKT1_html/thrd0152.html#pt
_once_44
>
> The man page for pthread_once for Solaris 8 doesn't mention anything
> about the blocking behaviour.
>
> René
>
In fact, looking at it, I'll change this to block all threads that call
pthread_once with the same once variable. However I would really
appreciate a test case with multiple once variables to see if a global
block is needed, or a block per once variable.
Rob
--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -