Menu

Function CrcGenerateTable() at \C\7zCrc.c

foxpat
2014-12-06
2014-12-09
  • foxpat

    foxpat - 2014-12-06

    CrcGenerateTable() at \C\7zCrc.c
    populates the global structure
    UInt32 g_CrcTable[256 * CRC_NUM_TABLES];

    Shouldn't this function use a flag for skipping recalculating the tables when the tables were already calculated probably from some other thread?

    Shouldn't be a good idea checking this proposed "populated crc table" flag on crc functions like g_CrcUpdate() and trigger the crc table creation from there if needed?

    Thanks.

     
  • Igor Pavlov

    Igor Pavlov - 2014-12-06

    Yes, that code needs accurate programming.
    Call it once in C code.
    I just use
    CPP\Common\CRC.cpp
    in all C++ code projects that use CRC32.

    • Shouldn't be a good idea checking this proposed "populated crc table" flag on crc functions like g_CrcUpdate() and trigger the crc table creation from there if needed?

    I don't want to get multithreading difficulties of such code (LOCKS and so on). Look: two threads can read flag at same time. So they both will fill array.

     
  • foxpat

    foxpat - 2014-12-06

    OK I just wanted to check if I was missing something.

    About the flag it's true 2 threads could read it FALSE at the same time w/o synchronization but that will just trigger two simultaneous populate actions thing that does not represents a problem as the "update" of the table values are atomic operations. After this non-harmful "collision" both threads will set the flag to TRUE and the table will not be created again.

    Thanks Igor.

     
  • foxpat

    foxpat - 2014-12-08

    Hi Igor, I've seen CRC.cpp also uses CrcGenerateTable()

    I think this mod is even better than a flag

    void MY_FAST_CALL CrcGenerateTable()
    {
    UInt32 i;

    //mod
    if (g_CrcTable[sizeof(g_CrcTable)/sizeof(g_CrcTable[0]) - 1] != 0 )
    return; //the table is already populated
    //mod
    ...

    }


    what do you think?

     
  • Igor Pavlov

    Igor Pavlov - 2014-12-08

    What exact cases do you see problem?
    CRC.cpp calls CrcGenerateTable().
    Who calls it second time?

     
  • foxpat

    foxpat - 2014-12-08

    Extracting a file from a 7z file requires the CRC table populated.
    In my extraction function if I do not call CrcGenerateTable() the thing crashes.

    Then if I'm extracting several files or extracting from different threads that table gets created every time I call my extraction routine (I use C++)

    Am I missing something?

     
  • Igor Pavlov

    Igor Pavlov - 2014-12-08

    You can add CRC.cpp to your project.

     
  • foxpat

    foxpat - 2014-12-08

    I saw it!
    CRC.cpp instantiates a global structure whose constructor calls CrcGenerateTable() only once. I wasn't including CRC.cpp.

    My problem now is that some optimization might be removing the "unused" structure then the constructor is never called.

    Thanks Igor

     
  • Igor Pavlov

    Igor Pavlov - 2014-12-08
    • My problem now is that some optimization might be removing the "unused" structure then the constructor is never called.

    What type of optimization do you mean?
    Note that I use such register/init trick in many places:
    different CRCs, AES tables, I register all codecs and archive handlers with such constructors.

    The only possible problem, that some programmer can remove such init file from project.

     
  • foxpat

    foxpat - 2014-12-08

    ok it seems it is not an optimization defined by me; the CRC.cpp file in debug mode has no optimization at all but the linker does not include a structure that is not used (sure it is a linker optimization).
    I'm aware you use the registration trick specially with coders; e.g. registerArc7z() then just using that dummy function somewhere the linker does include the coder definition; OK I do not see registerCRC() and the linker kills the structure and the constructor is never called.

     
  • Igor Pavlov

    Igor Pavlov - 2014-12-08

    What compiler?

     
  • foxpat

    foxpat - 2014-12-08

    VS2008 Professional
    I think this is the linker parameter;

    Linker/Optimization/[Default]
    Optimization:Enable the elimination of functions or data that is never referenced.
    /OPT:REF or /OPT:/NOREF

    of-course I want to remove not used referenced; many times version n is compiled with some code for the version n+1 that the linker removes when linking version n

    I already had this problem with the coders. Your trick is nice but it has this problem.

     
  • Igor Pavlov

    Igor Pavlov - 2014-12-09

    I use /OPT:REF in all compilers in all projects.
    So why I have no any problem?
    Please check these problems again, make more investigations of problems and write here about any conclusions.
    Check different VC versions, if required.

    It's important to solve such problem.

     
  • foxpat

    foxpat - 2014-12-09

    OK, I'll go deeper on this.
    I'll let you know.

    Thanks Igor

     

    Last edit: foxpat 2014-12-09

Log in to post a comment.