[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: multi CPU's



On Sat, Apr 08, 2000 at 10:34:18AM +0300, Eray Ozkural wrote:
> Andreas Bombe wrote:
> > > Though I'm pretty sure those preprocessor symbols are then scattered
> > > all over the megs of source code. But that seems to be less than 1000.
> > > [I've checked].
> > 
> > That's the Linux design philosophy.  Put the necessary #ifdefs into
> > header files to define macros which to avoid #ifdefs in the actual C
> > files.  That means that your count is multiplied by the count of each
> >         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > macro use.
> ^^^^^^^^^^^^
> 
> Ha ha ha! Excuse me? Do you suggest that cpp makes multiple passes to
> further expand preprocessor symbols once again. I hadn't heard this before :)

Me neither.  "Multiplied" was probably the wrong word to use here.

> So let's see, I write
> 
> <<
> #include <stdio.h>
> #define ENTER_SUCKY #ifdef __SUCKY__
> #define EXIT_SUCKY #endif
> 
> ENTER_SUCKY
> printf("I suck completely\n");
> EXIT_SUCKY
> >>
> in a file called suck.c

No, what I meant is that macros or inlines are defined conditionally
one way or the other.  So the one #ifdef used in the header really
influences the many instances of the macro/inline function being
called.
 
To pick out just one simple example:

#define smp_processor_id()                      0

and if SMP is enabled

#define smp_processor_id() (current->processor)


So everywhere smp_processor_id() is called the code is different,
without there being an "#ifdef CONFIG_SMP" anywhere near the code.  If
you just count occurances of CONFIG_SMP you will catch the definition,
but that is only seen by the preprocessor.  The compiler will not see
the #ifdef but the lots of places that changed because of that.


> > 
> > [1] Modules must always be compiled with the same compiler and kernel
> >     options as the kernel used.  Otherwise you really ask for
> >     problems.  Don't install separately downloaded binary modules.
> > 
> 
> Yep, yep, yep, I guess. It's so easy to make your MT code blow up.  That's
> why I think there should be this standard kernel-image binary with SMP support
> in it. For convenience.
> 
> OTOH, what you say if of course 100% correct. If there's a macro that handles
> some SMP stuff, and that macro is used in every device driver and alike, then
> there'd be an explosion which would surprise me. But I didn't see such a
> magic preprocessor macro.

Sorry?  I talked about spin locks.  At some point every driver which
tries to work on SMP will need them, and they are conditionally
defined.

> The extensive inlining would be a problem, because
> it could cause code explosion. [Which you mentioned as (a) ] Check this:
> 
> you know where this beast comes from :)
> 
> extern inline void down(struct semaphore * sem)
> {
>         __asm__ __volatile__(
>                 "# atomic down operation\n\t"
> #ifdef __SMP__
>                 "lock ; "
> #endif
>                 "decl (%0)\n\t"     /* --sem->count */
>                 "js 2f\n"
>                 "1:\n"
>                 ".section .text.lock,\"ax\"\n"
>                 "2:\tcall __down_failed\n\t"
>                 "jmp 1b\n"
>                 ".previous"
>                 :/* no outputs */
>                 :"c" (sem)
>                 :"memory");
> }
> 
> that #ifdef there inside the inline causes the effect you're talking about.
> But again, that change ain't much.

Then let's look at spin locks.  The following is defined on UP kernels:

#define spin_lock_init(lock)    do { } while(0)                                             
#define spin_lock(lock)         (void)(lock) /* Not "unused variable". */                   
#define spin_is_locked(lock)    (0)                                                         
#define spin_trylock(lock)      ({1; })                                                     
#define spin_unlock_wait(lock)  do { } while(0)                                             
#define spin_unlock(lock)       do { } while(0)                                             


And this is on x86 SMP (I stripped the SPINLOCK_DEBUG code to make it
a bit more readable):


#define spin_lock_init(x)       do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)                  
#define spin_unlock_wait(x)     do { barrier(); } while(((volatile spinlock_t *)(x))->lock) 
#define spin_is_locked(x)       ((x)->lock != 0)                                            
                                                                                            
#define spin_lock_string \                                                                  
        "\n1:\t" \                                                                          
        "lock ; btsl $0,%0\n\t" \                                                           
        "jc 2f\n" \                                                                         
        ".section .text.lock,\"ax\"\n" \                                                    
        "2:\t" \                                                                            
        "testb $1,%0\n\t" \                                                                 
        "rep;nop\n\t" \                                                                     
        "jne 2b\n\t" \                                                                      
        "jmp 1b\n" \                                                                        
        ".previous"                                                                         

#define spin_unlock_string \                                                                
        "lock ; btrl $0,%0"                                                                 

extern inline void spin_lock(spinlock_t *lock)                                              
{                                                                                           
        __asm__ __volatile__(                                                               
                spin_lock_string                                                            
                :"=m" (__dummy_lock(lock)));                                                
}                                                                                           
                                                                                            
extern inline void spin_unlock(spinlock_t *lock)                                            
{                                                                                           
        __asm__ __volatile__(                                                               
                spin_unlock_string                                                          
                :"=m" (__dummy_lock(lock)));                                                
}                                                                                           
                                                                                            
#define spin_trylock(lock) ({ !test_and_set_bit(0,(lock)); })                               


Now that looks quite a bit different, doesn't it?


> exa@borg:/usr/src/linux$ grep -e down\(.*\) -r . | wc -l
>     626

Semaphores aren't that common.  Searching just the drivers
subdirectories (of 2.3.99-pre3) for most forms of spin locks gives a
slightly higher count:

[andreasb@storm drivers]$  grep -e 'spin_\(un\)*lock' -r . | wc -l
   3348

> In light of this, let me suggest the following. The 192KB estimate (which
> is perhaps excessive wrt how it was thought) is inaccurate, so my new estimate
> is 768KB. That will be compressed, so it makes ~384K. If that's achievable,
> then still my point holds.

If I understood you right you want to make binary diffs.  Now given
that the Linux kernel image is also compressed there will be a lot
more differences in the binary.  My whole kernel compressed image is
less than 768 kB, what would the point be in not just creating
separate kernel packages?

-- 
 Andreas E. Bombe <andreas.bombe@munich.netsurf.de>    DSA key 0x04880A44
http://home.pages.de/~andreas.bombe/    http://linux1394.sourceforge.net/


Reply to: