Thread: Shutdown of Threads

  1. #31
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, that is correct. If all the code in "doing stuff that doesn't use quit" is known to the compiler [e.g you are processing arrays that have been read from file by some other thread], then the compiler can safely see that quit is not being changed by the code - so it can safely assume that quit can be kept in a register. Since the compiler doesn't understand that quit is modified by ANOTHER THREAD, it will not see how it can possibly change by the code inside your while-loop.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  2. #32
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    thank you very much

    but that's to me a very strange way to make things work.
    having a compiler who doesn't know about multithreading??
    i am astonished

    i understand this is one of the several prices to pay by working in the open source world

    i would like also a reply by codeplug at my post #30
    Last edited by mynickmynick; 07-18-2008 at 03:26 AM.

  3. #33
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mynickmynick View Post
    thank you very much

    but that's to me a very strange way to make things work.
    having a compiler who doesn't know about multithreading??
    i am astonished

    i understand this is one of the several prices to pay by working in the open source world

    i would like also a reply by codeplug
    Well, if it's any consolation, Windows compilers from MS and Intel, and all other C & C++ compilers that I'm personally aware of, are completely ignorant as to the existence of threads. To the compiler "CreateThread" or whatever it may be called is just another function call - it happens to take a function pointer, but other than that, it's just like any other regular (opaque) function in the world.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #34
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> i would like also a reply by codeplug at my post #30
    reply: <what matsp said>

    >> but that's to me a very strange way to make things work.
    Learning the "how's" and "why's" things can go wrong in multi-threaded programming is good for knowing how to avoid them.....In this case the "how to avoid" is: Use proper synchronization methods for access (read and write) to shared memory.

    gg

  5. #35
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Can I also point out that the reason that the scenario where the compiler should know about threads and sharing data is very difficult to scope out. Global variables may well be "modified out of the compilers understanding" for many other reasons than what we have discussed here (signals, asynchronous calls, or DMA if we are working on drivers, etc), and under more complex scenarios (where the variable isn't a straight forward global, but for example through a pointer indirection).

    This makes the compilers job of understanding what is going on even harder - because the compiler would have to know so much more about what may or may not happen. Of course, we could make the compiler take the cautious approach and ALWAYS re-read anything that could possibly be accessed by external sources [that is, just about anything that isn't on the stack], but that would cause the compiler to generate much slower code. We want the compiler to generate as good as possible code for the current scenario.

    Yes, it means, as a programmer, we need to know more about how the code hangs together. That's the price we pay for NOT having to tell the compiler EVERY TIME it's safe to assume that "nothing else touches this" - because that is the rare case, rather than the common case.

    Optimize for the common case, make the rare special case the one where it's not so performant, and most of your customers will be happy. I'll buy that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #36
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post
    Global variables may well be "modified out of the compilers understanding" for many other reasons than what we have discussed here (signals, --
    Mats
    I agree.
    But that contradicts point (1) and (3) of your post #29
    (
    I probably did not explain in #28 that quit is a global variable? or it was not clear the
    reference to http://cboard.cprogramming.com/showthread.php?t=105260
    )
    where you say quit might be stored on a register once for all iterations.
    Beacuse a signal handler could go and modify quit. So a good compiler should not do that.

    So please again:
    (3)
    what are situations in which a compiler might decide to place a variable in a register and not update in successive iterations of a loop??

    thank you for support
    Last edited by mynickmynick; 07-18-2008 at 09:38 AM.

  7. #37
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by Codeplug View Post
    >> [b]

    >> but that's to me a very strange way to make things work.
    Learning the "how's" and "why's" things can go wrong in multi-threaded programming is good for knowing how to avoid them.....In this case the "how to avoid" is: Use proper synchronization methods for access (read and write) to shared memory.

    gg
    sorry but, in my little SW experience, i disagree
    i think things should be conceived in a unified way, where everything is taken into account together. A programming environment has to be unified. Not with things going on together for some special.. do not know how to say in English.. Tetris or "astrological" coincidence.
    To me signal handling and multithreading is BASIC part of a programming situation and so they should affect in basic ways compiler implementations.
    The fact they affect it only as a side effect of being lock() a function seems quite strange and I must say not very convincing

    thank you very much for support

  8. #38
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mynickmynick View Post
    I agree.
    But that contradicts point (1) and (3) of your post #29
    (
    I probably did not explain in #28 that quit is a global variable? or it was not clear the
    reference to correction2 of http://cboard.cprogramming.com/showthread.php?t=105260
    )
    where you say quit might be stored on a register once for all iterations.
    Beacuse a signal handler could go and modify quit. So a good compiler should not do that.

    So please again:
    (3)
    what are situations in which a compiler might decide to place a variable in a register and not update in successive iterations of a loop??

    thank you for support
    Yes, so if you use signals to modify variables, you ALSO need to use volatile or other lock mechanisms.

    So for 3: The compiler will decide to place a variable in a register when all the code within a loop is known to the compiler, and doesn't update the variable in question. It does not know if signal handlers, threads or DMA updates the variable - if you know that may happen, then you need to make sure that the compiler does the right thing - that's YOUR decision, not the compilers. This is because the COMMON case is that global variables are only used by one thread, with no DMA, signals or other asynchronous events.

    Obviously, calling a function that the compiler doesn't have the source available for, "anything" can happen in that black box, so the compiler must take a "safe" approach. In gcc, you could also use __asm__ __volatile__("nop" :::"memory") - this would tell the compiler that "global variables may have been updated". [I haven't tried that out, it's just to the best of my understanding].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #39
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post
    Yes, so if you use signals to modify variables, you ALSO need to use volatile or other lock mechanisms.

    --
    Mats

    so you confirm that if I have in a single thread

    Code:
    int quit;
    
    function()
    {
    
    while (!quit)
    {
       a++; 
    }
    
    }
    
    signalhandler()
    {
     quit++;
    
    }
    the compiler might decide to store the quit only once in a register and to prevent that i MUST
    define quit as
    volatile int quit;//(global)

    basically any variable modified by signal handlers must be volatile ??
    so signal handlers should do as little as possible otherwise very difficult to think about all possible side effects of signals+compilerNotTakingThemIntoAccount
    It is not very convincing. I guess compiler does not store a global variable on a register once.
    I guess that optimization is done only for local stack variables not visible by signal handlers like in a

    Code:
    function()
    {
      int addvalue=2;
    
    while (..)
    {
       a[i]+=addvalue;
       i++;
    }
    
    
    }
    In this (stupid) case probably addvalue ios stored once for all iterations on a register

    But in the previous example I guess quit should not be stored on a register once (being volatile or not)

    thank you for support
    Last edited by mynickmynick; 07-18-2008 at 09:58 AM.

  10. #40
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, if it's modified outside of the flow that the compiler understands in any way, thread, signal, interrupt, DMA, asynchronous calls, or whatever it may be, the compiler will think that it's not going to change, and you need either opaque function calls or a volatile. [and as discussed earlier, volatile is not sufficient to guarantee more complex operations correctness].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #41
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    Quote Originally Posted by matsp View Post
    Yes, if it's modified outside of the flow that the compiler understands in any way, thread, signal, interrupt, DMA, asynchronous calls, or whatever it may be, the compiler will think that it's not going to change, and you need either opaque function calls or a volatile. [and as discussed earlier, volatile is not sufficient to guarantee more complex operations correctness].

    --
    Mats
    please reread my previous message (I changed it while you were reading)
    summary:
    (1)I guess only stack variables can be optimized by keeping them on a regsister once for all iterations
    (2) it seems to me it is not necessary to declare volatile vars used by a signal handler
    if you disagree please give links to this

    what are asyncronous calls??

  12. #42
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    I can understand for multithreading, but signal handling is old as UNIX so I believe gcc takes it into account and never optimize globals on a register once for all iterations
    Might be it does it for stack variables as examplified above
    Please give me links on this topic!!

  13. #43
    Alessio Stella
    Join Date
    May 2008
    Location
    Italy, Bologna
    Posts
    251
    otherwise I must consider signalhandlers as simple as possible (only setting some flag and then returning, with the big job done by the main ordinary program flow)

  14. #44
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    gcc does not understand signal handlers:
    Code:
    #include <signal.h>
    #include <stdio.h>
    
    
    int signalfired;
    
    void sighandler(int s)
    {
      signalfired = 1;
    }
    
    
    int main()
    {
      int i = 0;
      signal(SIGABRT, sighandler);
      while(!signalfired)
        {
          i++;
          if ((i & 15) == 0)
    	printf("&#37;d\n", i);
        }
      printf("Signal caught\n");
      return 0;
    }
    generates:
    Code:
    	movl	$_sighandler, %edx
    	xorl	%ebx, %ebx
    	movl	%edx, 4(%esp)
    	call	_signal
    L10:
    	movl	_signalfired, %eax
    L9:
    	testl	%eax, %eax
    	jne	L8
    	incl	%ebx
    	testb	$15, %bl
    	jne	L9
    	movl	%ebx, 4(%esp)
    	movl	$LC0, (%esp)
    	call	_printf
    	jmp	L10
    It jumps back to L10 to re-read the signalfired variable only when we call printf. Taking out the printf in the above C code gets this:
    Code:
    	call	_signal
    	movl	_signalfired, %eax
    	.p2align 4,,15
    L8:
    	testl	%eax, %eax
    	je	L8
    So, the entire loop is just checking the register eax, which is not updated in the loop itself!

    Edit: Note that in the beginning of this [or the other closely related] thread there is a mention of "sig_atomic_t", which is the type you SHOULD USE for communication between signal handlers and general code - although I can't make my gcc-mingw work with that either.

    --
    Mats
    Last edited by matsp; 07-21-2008 at 02:42 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 10-17-2008, 11:28 AM
  2. Yet another n00b in pthreads ...
    By dimis in forum C++ Programming
    Replies: 14
    Last Post: 04-07-2008, 12:43 AM
  3. Classes and Threads
    By Halloko in forum Windows Programming
    Replies: 9
    Last Post: 10-23-2005, 05:27 AM
  4. problem with win32 threads
    By pdmarshall in forum C++ Programming
    Replies: 6
    Last Post: 07-29-2004, 02:39 PM
  5. Block and wake up certain threads
    By Spark in forum C Programming
    Replies: 9
    Last Post: 06-01-2002, 03:39 AM