Thread: bit operation question

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    47

    bit operation question

    Hi guys!

    I was curious a function is doing the following bit operations:
    Code:
    /**********************************************************************
    
    Function    : hw_update_pageref
    Description : when a memory access occurs, the hardware update the reference 
    and dirty bits for the appropriate page.  We simulate this by an
    update when the page is found (in TLB or page table).
    Inputs      : page - page number
    op - read (0) or write (1)
    Outputs     : 0 if successful, -1 otherwise
    
    ***********************************************************************/
    
    int hw_update_pageref( ptentry_t *ptentry, int op )
    {
        ptentry->bits |= REFBIT;
        ptentry->bits |= WSREFBIT;
    
        if ( op ) {   /* write */
            ptentry->bits |= DIRTYBIT;
        }
    
        return 0;
    }
    bits is an int by the way.

    And Here are the following constants I'm working with:
    Code:
    /* bitmasks */
    #define VALIDBIT          0x1
    #define REFBIT            0x2
    #define DIRTYBIT          0x4
    #define WSBITS            0x38    /* 3 bits for working set references -- highest is set at ref */
    #define WSREFBIT          0x20

    Basically that "bits" field is keeping track of all of those things, validbit, refbit, dirtybit, and working set bits, and workingrefbit.


    So what I want to do is ONLY change the VALID BIT, from 0x1 to 0x0, to show its not valid.

    Can I see if BITS has the valid bet set by simply doing:
    Code:
    int result = ptentry->bits & VALIDBIT;  //should return 0x1 or 0x0 right?
    if(result == VALIDBIT)
    {  
             ptentry->bits = ptentry->bits ^ VALIDBIT  //bit XOR operator so if it was 0x1 ^ 0x1 == 0x0 right?
    }
    basically if i have 0x1 I want to switch it to 0x0,
    also it would be nice to know how to switch it back to 0x1, so i can make it valid again if I need to.


    One other bit question, if I want to shift certian bits to the right (only the working set bits WSBITS), can I do the following:
    Code:
     /* if the page is valid, age the 3 working set bits (shift them right) */
            if (( wsbits = ( ptentry->bits & WSBITS ))) {
                wset++;   /* a page is in working set */
    
                /* age the wsbits */
                /* BIT AGING HERE */
                wsbits = wsbits >> 1;
                //now add back into ptentry->bits
                 ptentry->bits = ptentry->bits | wsbits;
            }

    Thanks!
    Last edited by mr_coffee; 04-07-2009 at 02:47 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Sep 2008
    Posts
    47
    excellent, thank you, i didn't find this googling, great tutorial! after reading it, it seems like everyhting I wrote makes sense.
    Hm...i'm not so sure if this is right though:
    Code:
    int pt_invalidate_mapping( int pid, int page )
    {
        /* Task #3 */
    
        unsigned int vbitresult = current_pt[page].bits & VALIDBIT;
        if(vbitresult == VALIDBIT) //if the validbit is 0x1, set it to 0x0
        {
            current_pt[page].bits = current_pt[page].bits ^ VALIDBIT;
        }
        current_pt[page].frame = -1;   //also set frame to invalid
    
            return 0;
    }

    if valid bit is 0x1, isn't that equal in binary, 1000
    and if there are more bits in bits (which there will be) by me doing bits ^ VALIDBIT if bits is:
    bits == 1000 1100 1001 1101, if I apply 1000 to that with ^ wouldnt it append 0's and do somthing like:
    1000 1100 1001 1101
    1000 0000 0000 0000
    __________________
    0000 1000 1001 1101


    OOoo it does work!
    Last edited by mr_coffee; 04-07-2009 at 03:36 PM.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It works, indeed. I would however prefer to do invalidate as this:
    Code:
    int pt_invalidate_mapping( int pid, int page )
    {
        /* Task #3 */
    
        current_pt[page].bits &=  ~VALIDBIT;
        current_pt[page].frame = -1;   //also set frame to invalid
    
        return 0;
    }
    There is no need to check if the page is valid and do something different if it wasn't. We just clear the valid-bit whether it is set or not. This works by anding with the inverse of VALIDBIT, so if it's bit zero, we get:
    Code:
    bits = 1000 1101 0001 1101
    mask = 1111 1111 1111 1110   // Inverse of 0000 0000 0000 0001 using ~ operator. 
    & oparator gives:
    bits = 1000 1101 0001 1100   //  Valid bit is now clear.
    Making the code simple like this helps in many ways:
    1. It's faster.
    2. There are fewer race-conditions where something may change whilst you are operating on the entry. (But for complete safety, you would need locks of some sort).
    3. It's shorter and easier to understand (once you understand the basic principle) - shorter code is less likely to have bugs, statistically speaking.

    --
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 12-04-2008, 08:15 PM
  2. Bit Shifting Question
    By loko in forum C Programming
    Replies: 10
    Last Post: 09-13-2005, 04:07 PM
  3. quick question about bit manipulation
    By PJYelton in forum C++ Programming
    Replies: 7
    Last Post: 01-10-2003, 01:18 AM
  4. 16 bit or 32 bit
    By Juganoo in forum C Programming
    Replies: 9
    Last Post: 12-19-2002, 07:24 AM
  5. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM