[M3devel] dynamic chose between user/kernel threads?

Jay jay.krell at cornell.edu
Thu Jan 8 10:46:28 CET 2009


Ok, then make it function pointers.
 
That is a little more work.
 
It won't likely be inlined, but I doubt it ever is currently anyway.
A good implementation will have that be zero or one instructions, but it might impede the processor reading ahead in the instruction stream. Zero instructions if the interfaces are actually exposed as function pointers, one instruction if they remain functions that just jump through a pointer. One instruction being much easier to implement probably.
 
 (Actually conditional branches better preserve inlinability, but it takes a sophisticated compiler to benefit).
 
 > at most a couple of instructions 
 
It's pretty hard to do anything in 2 instructions..esp. without inlining.. call, return, budget gone.
 
Here's the uncontended non-recursive EnterCriticalSection for comparison, not as an example of exactly what Modula-3 does, but as what is surely an example of a fairly well implemented lock (albeit the data structure is on the large size, and does support recursion).
 
0:000> u ntdll!RtlEnterCriticalSectionntdll!RtlEnterCriticalSection:00000000`76d87850 fff3            push    rbx00000000`76d87852 4883ec20        sub     rsp,20h00000000`76d87856 f00fba710800    lock btr dword ptr [rcx+8],000000000`76d8785c 488bd1          mov     rdx,rcx00000000`76d8785f 0f832c58ffff    jae     00000000`76d7d091 contention or recursion presumably 00000000`76d87865 65488b042530000000 mov   rax,qword ptr gs:[30h]00000000`76d8786e 488b4848        mov     rcx,qword ptr [rax+48h]00000000`76d87872 c7420c01000000  mov     dword ptr [rdx+0Ch],100000000`76d87879 33c0            xor     eax,eax00000000`76d8787b 48894a10        mov     qword ptr [rdx+10h],rcx00000000`76d8787f 4883c420        add     rsp,20h00000000`76d87883 5b              pop     rbx00000000`76d87884 c3              ret
and then let's follow the contended/recursive path:
 
0:000> u 76d7d09100000000`76d7d091 65488b042530000000 mov   rax,qword ptr gs:[30h]00000000`76d7d09a 488bd9          mov     rbx,rcx00000000`76d7d09d 488b5048        mov     rdx,qword ptr [rax+48h]
Presumably this is a check to see if this thread already has the critical section.00000000`76d7d0a1 48395110        cmp     qword ptr [rcx+10h],rdx00000000`76d7d0a5 0f851413feff    jne     00000000`76d5e3bf if not wait for other guy00000000`76d7d0ab 83410c01        add     dword ptr [rcx+0Ch],1 if so, increment recursion count and done00000000`76d7d0af 33c0            xor     eax,eax00000000`76d7d0b1 4883c420        add     rsp,20h00000000`76d7d0b5 5b              pop     rbx00000000`76d7d0b6 c3              ret
contended path not shown.
 
So that's 13 instructions for initial entry, 15 instructions for recursive entry.
 
 
0:000> u ntdll!RtlLeaveCriticalSectionntdll!RtlLeaveCriticalSection:00000000`76d87800 4883ec28        sub     rsp,28h00000000`76d87804 83410cff        add     dword ptr [rcx+0Ch],0FFFFFFFFh00000000`76d87808 7535            jne     ntdll!RtlLeaveCriticalSection+0x3f (00000000`76d8783f)00000000`76d8780a 48895c2430      mov     qword ptr [rsp+30h],rbx00000000`76d8780f 48897c2420      mov     qword ptr [rsp+20h],rdi00000000`76d87814 48c7411000000000 mov     qword ptr [rcx+10h],000000000`76d8781c bf01000000      mov     edi,100000000`76d87821 488bd9          mov     rbx,rcx00000000`76d87824 f00fc17908      lock xadd dword ptr [rcx+8],edi00000000`76d87829 83c701          add     edi,100000000`76d8782c 83ffff          cmp     edi,0FFFFFFFFh00000000`76d8782f 0f854380fdff    jne     00000000`76d5f87800000000`76d87835 488b5c2430      mov     rbx,qword ptr [rsp+30h]00000000`76d8783a 488b7c2420      mov     rdi,qword ptr [rsp+20h]00000000`76d8783f 33c0            xor     eax,eax00000000`76d87841 4883c428        add     rsp,28h00000000`76d87845 c3              ret
 
6 instructions for recursive exit.
17 instructions for last exit..I assume the conditional branch is to wake waiters.
 
x86:
 
0:000> u ntdll!RtlEnterCriticalSectionntdll!RtlEnterCriticalSection:76f03580 8bff            mov     edi,edi76f03582 55              push    ebp76f03583 8bec            mov     ebp,esp76f03585 83ec0c          sub     esp,0Ch76f03588 56              push    esi76f03589 57              push    edi76f0358a 8b7d08          mov     edi,dword ptr [ebp+8]76f0358d 8d7704          lea     esi,[edi+4]76f03590 8bc6            mov     eax,esi76f03592 f00fba3000      lock btr dword ptr [eax],076f03597 0f83bec60000    jae     (76f0fc5b)76f0359d 64a118000000    mov     eax,dword ptr fs:[00000018h]76f035a3 8b4824          mov     ecx,dword ptr [eax+24h]76f035a6 894f0c          mov     dword ptr [edi+0Ch],ecx76f035a9 c7470801000000  mov     dword ptr [edi+8],176f035b0 5f              pop     edi76f035b1 33c0            xor     eax,eax76f035b3 5e              pop     esi76f035b4 8be5            mov     esp,ebp76f035b6 5d              pop     ebp76f035b7 c20400          ret     4
21 instructions for initial entry
 
0:000> u 76f0fc5b76f0fc5b 648b0d18000000  mov     ecx,dword ptr fs:[18h]76f0fc62 8b570c          mov     edx,dword ptr [edi+0Ch]76f0fc65 3b5124          cmp     edx,dword ptr [ecx+24h]76f0fc68 0f8584de0000    jne     76f1daf276f0fc6e 83470801        add     dword ptr [edi+8],176f0fc72 5f              pop     edi76f0fc73 33c0            xor     eax,eax76f0fc75 5e              pop     esi76f0fc76 8be5            mov     esp,ebp76f0fc78 5d              pop     ebp76f0fc79 c20400          ret     4
 
22 for recursive entry.
 
 
ntdll!RtlLeaveCriticalSection:76f035c0 8bff            mov     edi,edi76f035c2 55              push    ebp76f035c3 8bec            mov     ebp,esp76f035c5 56              push    esi76f035c6 8b7508          mov     esi,dword ptr [ebp+8]76f035c9 834608ff        add     dword ptr [esi+8],0FFFFFFFFh76f035cd 7525            jne     ntdll!RtlLeaveCriticalSection+0x34 (76f035f4)76f035cf 53              push    ebx76f035d0 57              push    edi76f035d1 8d7e04          lea     edi,[esi+4]76f035d4 c7460c00000000  mov     dword ptr [esi+0Ch],076f035db bb01000000      mov     ebx,176f035e0 8bc7            mov     eax,edi76f035e2 f00fc118        lock xadd dword ptr [eax],ebx76f035e6 83c301          add     ebx,176f035e9 83fbff          cmp     ebx,0FFFFFFFFh76f035ec 0f85d8a50100    jne     76f1dbca76f035f2 5f              pop     edi76f035f3 5b              pop     ebx76f035f4 33c0            xor     eax,eax76f035f6 5e              pop     esi76f035f7 5d              pop     ebp76f035f8 c20400          ret     4
 
11 instructions for recursive exit.23 instructions for last exit, I guess, without waiters.
 
 - Jay> To: jay.krell at cornell.edu> Date: Thu, 8 Jan 2009 00:19:26 -0800> From: mika at async.caltech.edu> CC: m3devel at elegosoft.com> Subject: Re: [M3devel] dynamic chose between user/kernel threads?> > Jay writes:> >--_659eacae-e435-4dfa-807c-8eaabce063a9_> >Content-Type: text/plain; charset="iso-8859-1"> >Content-Transfer-Encoding: quoted-printable> >> ...> >PROCEDURE Fork()=3D> >BEGIN IF KernelThreads> > RETURN ThreadPThread.Fork()=3B> > ELSE> > RETURN ThreadPosix.Fork()=3B> > END=3B> > END Fork.> ...> > If it's implemented properly, on many architectures LOCK should be> at most a couple of instructions. I think adding a couple of> branches to it may make a significant difference. On those> architectures it really ought to be inlined, too...> > Here's the "quick path" for LockMutex under user threads:> > INC (inCritical);> IF m.holder = NIL THEN> <* ASSERT self # NIL *>> m.holder := self;> DEC (inCritical);> RETURN;> END;> > Mika
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090108/e7337445/attachment-0002.html>


More information about the M3devel mailing list