Skip to content

<locale>: Unnecessary locking around classic locale #3030

@jsimmons

Description

@jsimmons

When retrieving the classic locale the current code calls _Init which takes a lock regardless of initialization state.

Expanded here, the code looks like the following.

_MRTIMP2_PURE const locale& __CLRCALL_PURE_OR_CDECL locale::classic() { // get reference to "C" locale
    //_Init();
    {
          locale::_Locimp* ptr = nullptr;
      
          _BEGIN_LOCK(_LOCK_LOCALE) // prevent double initialization
      
          // this function just returns a global variable
          // ptr = _Getgloballocale();
          ptr = global_locale;
      
          if (ptr == nullptr) { // create new locales
              _Setgloballocale(ptr = _Locimp::_New_Locimp());
              ptr->_Catmask = all; // set current locale to "C"
              ptr->_Name    = "C";
      
              _Locimp::_Clocptr = ptr; // set classic to match
              _Locimp::_Clocptr->_Incref();
              ::new (&classic_locale) locale(_Locimp::_Clocptr);
          }
      
          // this is always false in the classic() codepath
          //if (_Do_incref) {
          //    ptr->_Incref();
          //}
      
          _END_LOCK()
          //return ptr;
    }
    return classic_locale;
}

This means that every call to classic() is locking and unlocking a mutex, despite that after its initialization the pointer must always be valid. This can cause huge performance issues in specific scenarios, for example https://twitter.com/aras_p/status/1558063800145813505 shows a measured ~500x performance penalty in some blender loading code due to contention on this lock.

A fast path that avoids locking (by checking whether global_locale is valid, and directly returning before entering the critical section) should drastically improve performance in this and other similar situations.

https://github.com/microsoft/STL/blob/5e7cac7f679/stl/src/locale0.cpp#L138-L141

Metadata

Metadata

Assignees

No one assigned

    Labels

    fixedSomething works now, yay!performanceMust go faster

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions