• Bug#1109782: unblock: 7zip/25.00+dfsg-1 (4/13)

    From Bastian Germann@21:1/5 to All on Wed Jul 23 19:40:02 2025
    [continued from previous message]

    + for (i = 0; i < GroupCount; i++)
    + printf(" %u", GroupCounts[i]);
    + printf("\n");
    + }
    + }
    + {
    + DWORD_PTR processAffinityMask, systemAffinityMask;
    + if (GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask))
    + {
    + PRF(printf("\n====== GetProcessAffinityMask : "
    + ": processAffinityMask=%x, systemAffinityMask=%x\n",
    + (UInt32)processAffinityMask, (UInt32)systemAffinityMask);)
    + }
    + else
    + printf("\n==GetProcessAffinityMask FAIL");
    + }
    +}
    +#else
    +#ifndef USE_THREADS_CreateThread
    +// #define PRF(x)
    +#endif
    +#endif
    +
    WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
    {
    /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
    @@ -72,7 +166,43 @@

    unsigned threadId;
    *p = (HANDLE)(_beginthreadex(NULL, 0, func, param, 0, &threadId));
    -
    +
    +#if 0 // 1 : for debug
    + {
    + DWORD_PTR prevMask;
    + DWORD_PTR affinity = 1 << 0;
    + prevMask = SetThreadAffinityMask(*p, (DWORD_PTR)affinity);
    + prevMask = prevMask;
    + }
    +#endif
    +#if 0 // 1 : for debug
    + {
    + /* win10: new thread will be created in same group that is assigned to parent thread
    + but affinity mask will contain all allowed threads of that group,
    + even if affinity mask of parent group is not full
    + win11: what group it will be created, if we have set
    + affinity of parent thread with ThreadGroupAffinity?
    + */
    + const
    + Func_GetThreadGroupAffinity fn =
    + (Func_GetThreadGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
    + "GetThreadGroupAffinity");
    + if (fn)
    + {
    + // BOOL wres2;
    + MY_GROUP_AFFINITY groupAffinity;
    + memset(&groupAffinity, 0, sizeof(groupAffinity));
    + /* wres2 = */ fn(*p, &groupAffinity);
    + PRF(printf("\n==Thread_Create cur = %6u GetThreadGroupAffinity(): "
    + "wres2_BOOL = %u, group=%u mask=%x\n",
    + GetCurrentThreadId(),
    + wres2,
    + groupAffinity.Group,
    + (UInt32)groupAffinity.Mask);)
    + }
    + }
    +#endif
    +
    #endif

    /* maybe we must use errno here, but probably GetLastError() is also OK. */ @@ -110,7 +240,84 @@
    */
    }
    {
    - DWORD prevSuspendCount = ResumeThread(h);
    + const DWORD prevSuspendCount = ResumeThread(h);
    + /* ResumeThread() returns:
    + 0 : was_not_suspended
    + 1 : was_resumed
    + -1 : error
    + */
    + if (prevSuspendCount == (DWORD)-1)
    + wres = GetError();
    + }
    + }
    +
    + /* maybe we must use errno here, but probably GetLastError() is also OK. */ + return wres;
    +
    + #endif
    +}
    +
    +
    +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinityMask)
    +{
    +#ifdef USE_THREADS_CreateThread
    +
    + UNUSED_VAR(group)
    + UNUSED_VAR(affinityMask)
    + return Thread_Create(p, func, param);
    +
    +#else
    +
    + /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
    + HANDLE h;
    + WRes wres;
    + unsigned threadId;
    + h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId));
    + *p = h;
    + wres = HandleToWRes(h);
    + if (h)
    + {
    + // PrintProcess_Info();
    + {
    + const
    + Func_SetThreadGroupAffinity fn =
    + (Func_SetThreadGroupAffinity) Z7_CAST_FUNC_C GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
    + "SetThreadGroupAffinity");
    + if (fn)
    + {
    + // WRes wres2;
    + MY_GROUP_AFFINITY groupAffinity, prev_groupAffinity;
    + memset(&groupAffinity, 0, sizeof(groupAffinity));
    + // groupAffinity.Mask must use only bits that supported by current group
    + // (groupAffinity.Mask = 0) means all allowed bits
    + groupAffinity.Mask = affinityMask;
    + groupAffinity.Group = (WORD)group;
    + // wres2 =
    + fn(h, &groupAffinity, &prev_groupAffinity);
    + /*
    + if (groupAffinity.Group == prev_groupAffinity.Group)
    + wres2 = wres2;
    + else
    + wres2 = wres2;
    + if (wres2 == 0)
    + {
    + wres2 = GetError();
    + PRF(printf("\n==SetThreadGroupAffinity error: %u\n", wres2);)
    + }
    + else
    + {
    + PRF(printf("\n==Thread_Create_With_Group::SetThreadGroupAffinity()" + " threadId = %6u"
    + " group=%u mask=%x\n",
    + threadId,
    + prev_groupAffinity.Group,
    + (UInt32)prev_groupAffinity.Mask);)
    + }
    + */
    + }
    + }
    + {
    + const DWORD prevSuspendCount = ResumeThread(h);
    /* ResumeThread() returns:
    0 : was_not_suspended
    1 : was_resumed
    @@ -297,6 +504,13 @@
    return Thread_Create_With_CpuSet(p, func, param, NULL);
    }

    +/*
    +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinity)
    +{
    + UNUSED_VAR(group)
    + return Thread_Create_With_Affinity(p, func, param, affinity);
    +}
    +*/

    WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity)
    {
    @@ -577,5 +791,22 @@
    return AutoResetEvent_CreateNotSignaled(p);
    }

    +void ThreadNextGroup_Init(CThreadNextGroup *p, UInt32 numGroups, UInt32 startGroup)
    +{
    + // printf("\n====== ThreadNextGroup_Init numGroups = %x: startGroup=%x\n", numGroups, startGroup);
    + if (numGroups == 0)
    + numGroups = 1;
    + p->NumGroups = numGroups;
    + p->NextGroup = startGroup % numGroups;
    +}
    +
    +
    +UInt32 ThreadNextGroup_GetNext(CThreadNextGroup *p)
    +{
    + const UInt32 next = p->NextGroup;
    + p->NextGroup = (next + 1) % p->NumGroups;
    + return next;
    +}
    +
    #undef PRF
    #undef Print
    diff -Nru 7zip-24.09+dfsg/C/Threads.h 7zip-25.00+dfsg/C/Threads.h
    --- 7zip-24.09+dfsg/C/Threads.h 2024-03-28 18:00:00.000000000 +0100
    +++ 7zip-25.00+dfsg/C/Threads.h 2025-06-30 16:00:00.000000000 +0200
    @@ -1,5 +1,5 @@
    /* Threads.h -- multithreading library
    -2024-03-28 : Igor Pavlov : Public domain */
    +: Igor Pavlov : Public domain */

    #ifndef ZIP7_INC_THREADS_H
    #define ZIP7_INC_THREADS_H
    @@ -140,12 +140,22 @@
    WRes Thread_Wait_Close(CThread *p);

    #ifdef _WIN32
    +WRes Thread_Create_With_Group(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, unsigned group, CAffinityMask affinityMask);
    #define Thread_Create_With_CpuSet(p, func, param, cs) \
    Thread_Create_With_Affinity(p, func, param, *cs)
    #else
    WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet);
    #endif

    +typedef struct
    +{
    + unsigned NumGroups;
    + unsigned NextGroup;
    +} CThreadNextGroup;
    +
    +void ThreadNextGroup_Init(CThreadNextGroup *p, unsigned numGroups, unsigned startGroup);
    +unsigned ThreadNextGroup_GetNext(CThreadNextGroup *p);
    +