[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