digitalmars.D.learn - help with assembler
- Carlos Santander (119/119) Jan 26 2006 The following functions are part of Ben Hinkle's Locks library. I'm usin...
- Kris (29/150) Jan 26 2006 I thought the Mac was on x86 these days :-D
- Sean Kelly (12/23) Jan 26 2006 While this is true for int and smaller variables on x86 systems, I'm not...
- Sean Kelly (69/189) Jan 26 2006 Unfortunately, there is no perfect D equivalent. The purpose of these
- Carlos Santander (7/35) Jan 26 2006 [snip]
- Sean Kelly (19/30) Jan 27 2006 I didn't explain the rest of this very well (yesterday was a long day),
- James Dunne (11/48) Jan 27 2006 In-language support for arbitrary assembly language would be key here,
- Sean Kelly (10/13) Jan 27 2006 Walter seems to want it. In fact he's argued in support of it in the
- pragma (12/24) Jan 27 2006 (late to the party)
- James Dunne (7/39) Jan 27 2006 Yes, in the general case. But not when discussing vectorization and
- Sean Kelly (11/18) Jan 29 2006 It would probably not be too hard to provide intrinsic support for a CAS...
- Kris (7/29) Jan 29 2006 Well, I guess the benefit is that a compiler-writer is already targeting...
- Sean Kelly (8/42) Jan 29 2006 In the general case, yes. But what about the unidirectional memory
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (12/16) Jan 27 2006 I used the Mac OS X kernel functions instead of custom assembly,
- Sean Kelly (7/17) Jan 27 2006 Not all 32-bit hardware offers a 64-bit CAS instruction--x86 is one of
- Kris (4/20) Jan 27 2006 Actually, only the compareAndSet32() is relevant. All those others are n...
The following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please? ///////////////////////////////////////////////////////// /** Compare the value at *expect with the value at *ptr and if * they agree copy *update to *ptr and return true otherwise return * false. * \param ptr the memory location to update * \param expect the expected value at *ptr * \param update the new value for *ptr * \return true if successful */ extern (C) bool compareAndSet64(void* vptr, void* expect, void* update) { asm { naked; enter 0,0; mov EDI,update; mov EBX,[EDI]; mov ECX,4[EDI]; mov EDI,expect; mov EAX,[EDI]; mov EDX,4[EDI]; mov EDI,vptr; lock; cmpxch8b [EDI]; setz AL; leave; ret; } } /** Compare expect to *ptr and if equal copy update to *ptr and return true; * Otherwise return false. * \param ptr the memory location to update * \param expect the expected value at *ptr * \param update the new value for *ptr * \return true if successful */ bool compareAndSet32(void* vptr, void* expect, void* update) { return compareAndSet32(vptr,cast(int)expect,cast(int)update); } // alternative declaration for data instead of pointers extern (C) bool compareAndSet32(void* vptr, int expect, int update) { asm { naked; enter 0,0; mov EBX,update; mov EAX,expect; mov ECX,vptr; lock; cmpxchg [ECX],EBX; setz AL; leave; ret; } } /** Atomically add *val with x and return original content of *value * \param val the value to add to * \param x the amount to add * \return the value before adding x */ extern (C) int atomicAdd32(int* val, int x) { asm { naked; enter 0,0; mov EAX,x; mov EBX,val; lock; xadd [EBX],EAX; leave; ret; } } /** Atomically increment *val * \param val the value to increment */ extern (C) void atomicInc32(int* val) { asm { naked; enter 0,0; mov EBX,val; lock; inc [EBX]; leave; ret; } } /** Atomically decrement *val * \param val the value to decrement */ extern (C) void atomicDec32(int* val) { asm { naked; enter 0,0; mov EBX,val; lock; dec [EBX]; leave; ret; } } /** Atomically set *val and return old value * \param val the value to set * \param newval the new value * \return the old value */ extern (C) int atomicExchange32(int* val, int newval) { asm { naked; enter 0,0; mov EAX,newval; mov EBX,val; xchg [EBX],EAX; leave; ret; } } ///////////////////////////////////////////////////////// -- Carlos Santander Bernal
Jan 26 2006
I thought the Mac was on x86 these days :-D Seriously though, Ben's port of Prof Lea's library uses the compareAndSet32() function only. Unless you have a specific (other) need, you can make life easier by dropping all the others. That aside, you can convert these to D for a single processor/single core CPU only. Anything else requires the equivalent of a bus-lock (with that 'lock' prefix in the assembler), which D does not support at a higher level. From what I recall, Ben actually had non-assembler version of these functions ~ ones that would work only on a single-core machine: Yes ~ here it is: static bool compareAndSet32(void* vptr, int expect, int update) { int* vi = cast(int*)vptr; bool res = false; synchronized { res = expect == *vi; if (res) { *vi = update; } } return res; } Note, again, that the above will not wok on a machine with more than one core, or more than one processor ~ works for multi-threads only. Good luck; - Kris P.S. You might also encourage Sean to get his Atomic lib running on linux and the Mac :) "Carlos Santander" <csantander619 gmail.com> wrote in message news:drboof$2rik$1 digitaldaemon.com...The following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please? ///////////////////////////////////////////////////////// /** Compare the value at *expect with the value at *ptr and if * they agree copy *update to *ptr and return true otherwise return * false. * \param ptr the memory location to update * \param expect the expected value at *ptr * \param update the new value for *ptr * \return true if successful */ extern (C) bool compareAndSet64(void* vptr, void* expect, void* update) { asm { naked; enter 0,0; mov EDI,update; mov EBX,[EDI]; mov ECX,4[EDI]; mov EDI,expect; mov EAX,[EDI]; mov EDX,4[EDI]; mov EDI,vptr; lock; cmpxch8b [EDI]; setz AL; leave; ret; } } /** Compare expect to *ptr and if equal copy update to *ptr and return true; * Otherwise return false. * \param ptr the memory location to update * \param expect the expected value at *ptr * \param update the new value for *ptr * \return true if successful */ bool compareAndSet32(void* vptr, void* expect, void* update) { return compareAndSet32(vptr,cast(int)expect,cast(int)update); } // alternative declaration for data instead of pointers extern (C) bool compareAndSet32(void* vptr, int expect, int update) { asm { naked; enter 0,0; mov EBX,update; mov EAX,expect; mov ECX,vptr; lock; cmpxchg [ECX],EBX; setz AL; leave; ret; } } /** Atomically add *val with x and return original content of *value * \param val the value to add to * \param x the amount to add * \return the value before adding x */ extern (C) int atomicAdd32(int* val, int x) { asm { naked; enter 0,0; mov EAX,x; mov EBX,val; lock; xadd [EBX],EAX; leave; ret; } } /** Atomically increment *val * \param val the value to increment */ extern (C) void atomicInc32(int* val) { asm { naked; enter 0,0; mov EBX,val; lock; inc [EBX]; leave; ret; } } /** Atomically decrement *val * \param val the value to decrement */ extern (C) void atomicDec32(int* val) { asm { naked; enter 0,0; mov EBX,val; lock; dec [EBX]; leave; ret; } } /** Atomically set *val and return old value * \param val the value to set * \param newval the new value * \return the old value */ extern (C) int atomicExchange32(int* val, int newval) { asm { naked; enter 0,0; mov EAX,newval; mov EBX,val; xchg [EBX],EAX; leave; ret; } } ///////////////////////////////////////////////////////// -- Carlos Santander Bernal
Jan 26 2006
Kris wrote:I thought the Mac was on x86 these days :-D Seriously though, Ben's port of Prof Lea's library uses the compareAndSet32() function only. Unless you have a specific (other) need, you can make life easier by dropping all the others. That aside, you can convert these to D for a single processor/single core CPU only. Anything else requires the equivalent of a bus-lock (with that 'lock' prefix in the assembler), which D does not support at a higher level.While this is true for int and smaller variables on x86 systems, I'm not entirely certain it is true for longs on x86, nor may it be true for unaligned variables on non-x86 architectures--ie. anything where multiple ASM instructions may be used for a single logical operation. The x86 makes all this lock-free business unusually easy by making nearly every operation implicitly atomic. I'm not sure that the PPC is quite so forgiving.P.S. You might also encourage Sean to get his Atomic lib running on linux and the Mac :)It isn't Linux that's the problem so much as the PPC. But I think I could track down enough material to give it a shot, with the caveat that I won't even be able to compile it :-) Sean
Jan 26 2006
Carlos Santander wrote:The following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?Unfortunately, there is no perfect D equivalent. The purpose of these functions is twofold: first, there is typically a desire to impose access ordering to maintain algorithm correctness without using Mutexes, and second, to ensure that the data updates occur atomically (again, without Mutexes). Wrapping things in a 'synchronized' block should typically address the ordering issue (though it is not guaranteed as far as relevant specs on Mutexes are concerned--this is merely a common side-effect of how many Mutex implementations work), however, it can not cause the update to occur atomically. If you absolutely must use the Locks library, take my suggested code below and complement it by also only ever reading the variables pointed to by vptr while in a synchronized block. ie. int loadInt( void* vptr ) { synchronized return *cast(int*)vptr; } long loadLong( void* vptr ) { synchronized return *cast(long*)vptr; }///////////////////////////////////////////////////////// /** Compare the value at *expect with the value at *ptr and if * they agree copy *update to *ptr and return true otherwise return * false. * \param ptr the memory location to update * \param expect the expected value at *ptr * \param update the new value for *ptr * \return true if successful */ extern (C) bool compareAndSet64(void* vptr, void* expect, void* update) { asm { naked; enter 0,0; mov EDI,update; mov EBX,[EDI]; mov ECX,4[EDI]; mov EDI,expect; mov EAX,[EDI]; mov EDX,4[EDI]; mov EDI,vptr; lock; cmpxch8b [EDI]; setz AL; leave; ret; } }extern (C) bool compareAndSet64(void* vptr, long expect, long update) { synchronized { if( *(cast(long*)vptr) == expect) { *(cast(long*)vptr) = update; return true; } return false; } }/** Compare expect to *ptr and if equal copy update to *ptr and return true; * Otherwise return false. * \param ptr the memory location to update * \param expect the expected value at *ptr * \param update the new value for *ptr * \return true if successful */ bool compareAndSet32(void* vptr, void* expect, void* update) { return compareAndSet32(vptr,cast(int)expect,cast(int)update); } // alternative declaration for data instead of pointers extern (C) bool compareAndSet32(void* vptr, int expect, int update) { asm { naked; enter 0,0; mov EBX,update; mov EAX,expect; mov ECX,vptr; lock; cmpxchg [ECX],EBX; setz AL; leave; ret; } }extern (C) bool compareAndSet32(void* vptr, int expect, int update) { synchronized { if( *(cast(int*)vptr) == expect) { *(cast(int*)vptr) = update; return true; } return false; } }/** Atomically add *val with x and return original content of *value * \param val the value to add to * \param x the amount to add * \return the value before adding x */ extern (C) int atomicAdd32(int* val, int x) { asm { naked; enter 0,0; mov EAX,x; mov EBX,val; lock; xadd [EBX],EAX; leave; ret; } }extern (C) int atomicAdd32(int* val, int x) { synchronized { *(cast(int*)val) += x; } }/** Atomically increment *val * \param val the value to increment */ extern (C) void atomicInc32(int* val) { asm { naked; enter 0,0; mov EBX,val; lock; inc [EBX]; leave; ret; } }extern (C) void atomicInc32(int* val) { return atomicAdd32(val, 1); }/** Atomically decrement *val * \param val the value to decrement */ extern (C) void atomicDec32(int* val) { asm { naked; enter 0,0; mov EBX,val; lock; dec [EBX]; leave; ret; } }extern (C) int atomicDec32(int* val, int x) { return atomicAdd32(val, -1); }/** Atomically set *val and return old value * \param val the value to set * \param newval the new value * \return the old value */ extern (C) int atomicExchange32(int* val, int newval) { asm { naked; enter 0,0; mov EAX,newval; mov EBX,val; xchg [EBX],EAX; leave; ret; } }extern (C) int atomicExchange32(int* val, int newval) { synchronized { int tmp = *cast(int*)val; *cast(int*)val = newval; return tmp; } }
Jan 26 2006
Sean Kelly escribió:Carlos Santander wrote:[snip] Kris escribió:The following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?Unfortunately, there is no perfect D equivalent. The purpose of these functions is twofold: first, there is typically a desire to impose access ordering to maintain algorithm correctness without using Mutexes, and second, to ensure that the data updates occur atomically (again, without Mutexes). Wrapping things in a 'synchronized' block should typically address the ordering issue (though it is not guaranteed as far as relevant specs on Mutexes are concerned--this is merely a common side-effect of how many Mutex implementations work), however, it can not cause the update to occur atomically. If you absolutely must use the Locks library, take my suggested code below and complement it by also only ever reading the variables pointed to by vptr while in a synchronized block. ie.I thought the Mac was on x86 these days :-D Seriously though, Ben's port of Prof Lea's library uses the compareAndSet32() function only. Unless you have a specific (other) need, you can make life easier by dropping all the others. That aside, you can convert these to D for a single processor/single core CPU only. Anything else requires the equivalent of a bus-lock (with that 'lock' prefix in the assembler), which D does not support at a higher level. From what I recall, Ben actually had non-assembler version of these functions ~ ones that would work only on a single-core machine:[snip] Thank you, guys! -- Carlos Santander Bernal
Jan 26 2006
Sean Kelly wrote:Carlos Santander wrote:I didn't explain the rest of this very well (yesterday was a long day), but the above outlines the basic idea. Essentially, compareAndSet and similar operations exploit low-level hardware functionality to perform certain simple operations that typically require mutual exclusion (ie. a mutex). The motivating factor is usually either to increase performance for very simple operations, to eliminate a mutual exclusion bottleneck, or to write algorithms that have some sort of progress guarantee. Since D doesn't support inline ASM for anything other than x86 at the moment, a PPC implementation would need to be written and compiled on GCC and accessed via extern (C) functions. It's probably easier to just forego the performance benefits of compareAndX and simply perform all read and write operations on the involved variables using a mutex. Or better yet to use a standard locking container unless you have a real need for a lock-free one. That said, I may still try to get PPC support working for std.atomic in Ares, with the caveat that it would basically be a front-end for a small C library. SeanThe following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?Unfortunately, there is no perfect D equivalent. The purpose of these functions is twofold: first, there is typically a desire to impose access ordering to maintain algorithm correctness without using Mutexes, and second, to ensure that the data updates occur atomically (again, without Mutexes).
Jan 27 2006
Sean Kelly wrote:Sean Kelly wrote:In-language support for arbitrary assembly language would be key here, rather than x86(+) specific. This is a tough nut to crack though. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/MU/S d-pu s:+ a-->? C++++$ UL+++ P--- L+++ !E W-- N++ o? K? w--- O M-- V? PS PE Y+ PGP- t+ 5 X+ !R tv-->!tv b- DI++(+) D++ G e++>e h>--->++ r+++ y+++ ------END GEEK CODE BLOCK------ James DunneCarlos Santander wrote:I didn't explain the rest of this very well (yesterday was a long day), but the above outlines the basic idea. Essentially, compareAndSet and similar operations exploit low-level hardware functionality to perform certain simple operations that typically require mutual exclusion (ie. a mutex). The motivating factor is usually either to increase performance for very simple operations, to eliminate a mutual exclusion bottleneck, or to write algorithms that have some sort of progress guarantee. Since D doesn't support inline ASM for anything other than x86 at the moment, a PPC implementation would need to be written and compiled on GCC and accessed via extern (C) functions. It's probably easier to just forego the performance benefits of compareAndX and simply perform all read and write operations on the involved variables using a mutex. Or better yet to use a standard locking container unless you have a real need for a lock-free one. That said, I may still try to get PPC support working for std.atomic in Ares, with the caveat that it would basically be a front-end for a small C library. SeanThe following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?Unfortunately, there is no perfect D equivalent. The purpose of these functions is twofold: first, there is typically a desire to impose access ordering to maintain algorithm correctness without using Mutexes, and second, to ensure that the data updates occur atomically (again, without Mutexes).
Jan 27 2006
James Dunne wrote:In-language support for arbitrary assembly language would be key here, rather than x86(+) specific. This is a tough nut to crack though.Walter seems to want it. In fact he's argued in support of it in the C++ usenet forums. And based on what's been done for x86 ASM, it seems the intent is to support a syntax that's about as close to what's outlined in the appropriate hardware spec as possible. Ultimately, the D spec will probably include a statement to this effect (if there isn't one there already), and will leave the syntax and list of supported instructions to appendices. This is basically what Walter had suggested for C++ as well. Sean
Jan 27 2006
In article <drdr6v$25ka$1 digitaldaemon.com>, Sean Kelly says...James Dunne wrote:(late to the party) Agreed. The asm{} statement should contain code that is platform specific (x86, PPC, ARM, 68K, 6502, z80, whatever), which is in turn version()'ed around as needed. I read the statement "arbitrary assembly language" and my mind zeroed in on the "arbitrary" port of that for a moment. For no explicable reason, I thought that perhaps the problem might be partially solved by a truely arbitrary asm syntax. Then I remembered: D already has some very elementary intrinsic functions in place. Shouldn't these be extended to cover the kind of operations that lockless primitives are based on (like Ares' atomic)? - EricAnderton at yahooIn-language support for arbitrary assembly language would be key here, rather than x86(+) specific. This is a tough nut to crack though.Walter seems to want it. In fact he's argued in support of it in the C++ usenet forums. And based on what's been done for x86 ASM, it seems the intent is to support a syntax that's about as close to what's outlined in the appropriate hardware spec as possible. Ultimately, the D spec will probably include a statement to this effect (if there isn't one there already), and will leave the syntax and list of supported instructions to appendices. This is basically what Walter had suggested for C++ as well.
Jan 27 2006
pragma wrote:In article <drdr6v$25ka$1 digitaldaemon.com>, Sean Kelly says...Yes, in the general case. But not when discussing vectorization and usage of SIMD extensions. ;) Moving into 64-bit land would be key here as well. -- Regards, James DunneJames Dunne wrote:(late to the party) Agreed. The asm{} statement should contain code that is platform specific (x86, PPC, ARM, 68K, 6502, z80, whatever), which is in turn version()'ed around as needed. I read the statement "arbitrary assembly language" and my mind zeroed in on the "arbitrary" port of that for a moment. For no explicable reason, I thought that perhaps the problem might be partially solved by a truely arbitrary asm syntax. Then I remembered: D already has some very elementary intrinsic functions in place. Shouldn't these be extended to cover the kind of operations that lockless primitives are based on (like Ares' atomic)? - EricAnderton at yahooIn-language support for arbitrary assembly language would be key here, rather than x86(+) specific. This is a tough nut to crack though.Walter seems to want it. In fact he's argued in support of it in the C++ usenet forums. And based on what's been done for x86 ASM, it seems the intent is to support a syntax that's about as close to what's outlined in the appropriate hardware spec as possible. Ultimately, the D spec will probably include a statement to this effect (if there isn't one there already), and will leave the syntax and list of supported instructions to appendices. This is basically what Walter had suggested for C++ as well.
Jan 27 2006
pragma wrote:I read the statement "arbitrary assembly language" and my mind zeroed in on the "arbitrary" port of that for a moment. For no explicable reason, I thought that perhaps the problem might be partially solved by a truely arbitrary asm syntax. Then I remembered: D already has some very elementary intrinsic functions in place. Shouldn't these be extended to cover the kind of operations that lockless primitives are based on (like Ares' atomic)?It would probably not be too hard to provide intrinsic support for a CAS operation (with the caveat that it may compile to ~10 instructions on some architectures), but I don't see this offering much compared to a library API--std.atomic has support for unidirectional memory barriers and such, for example. That said, I think D could well benefit from memory access semantics that have more comprehensive support for concurrent operations, but this is a very nontrivial task. I think it would be better just to wait for the C++ folks to sort it out and hope they come up with something reasonable. Sean
Jan 29 2006
Well, I guess the benefit is that a compiler-writer is already targeting a specific instruction-set, and thus could happily implement the appropriate intrinsic? A portable CAS intrinsic would permit one to write an 'atomic' library compatible with all platforms that D supports (and others in the future)? "Sean Kelly" <sean f4.ca> wrote in message news:drj6km$brs$1 digitaldaemon.com...pragma wrote:I read the statement "arbitrary assembly language" and my mind zeroed in on the "arbitrary" port of that for a moment. For no explicable reason, I thought that perhaps the problem might be partially solved by a truely arbitrary asm syntax. Then I remembered: D already has some very elementary intrinsic functions in place. Shouldn't these be extended to cover the kind of operations that lockless primitives are based on (like Ares' atomic)?It would probably not be too hard to provide intrinsic support for a CAS operation (with the caveat that it may compile to ~10 instructions on some architectures), but I don't see this offering much compared to a library API--std.atomic has support for unidirectional memory barriers and such, for example. That said, I think D could well benefit from memory access semantics that have more comprehensive support for concurrent operations, but this is a very nontrivial task. I think it would be better just to wait for the C++ folks to sort it out and hope they come up with something reasonable. Sean
Jan 29 2006
In the general case, yes. But what about the unidirectional memory barrier issue? And what about ordering loads (since this is required on some weaker memory models)? I suppose you could redo my std.atomic as a set of intrinsics, but I don't see much to be gained from that over simply having it as a standard library component. Just duplicating CAS as-is would be another option, but that all by itself is a bit more coarse-grained than people want in some situations. Kris wrote:Well, I guess the benefit is that a compiler-writer is already targeting a specific instruction-set, and thus could happily implement the appropriate intrinsic? A portable CAS intrinsic would permit one to write an 'atomic' library compatible with all platforms that D supports (and others in the future)? "Sean Kelly" <sean f4.ca> wrote in message news:drj6km$brs$1 digitaldaemon.com...pragma wrote:I read the statement "arbitrary assembly language" and my mind zeroed in on the "arbitrary" port of that for a moment. For no explicable reason, I thought that perhaps the problem might be partially solved by a truely arbitrary asm syntax. Then I remembered: D already has some very elementary intrinsic functions in place. Shouldn't these be extended to cover the kind of operations that lockless primitives are based on (like Ares' atomic)?It would probably not be too hard to provide intrinsic support for a CAS operation (with the caveat that it may compile to ~10 instructions on some architectures), but I don't see this offering much compared to a library API--std.atomic has support for unidirectional memory barriers and such, for example. That said, I think D could well benefit from memory access semantics that have more comprehensive support for concurrent operations, but this is a very nontrivial task. I think it would be better just to wait for the C++ folks to sort it out and hope they come up with something reasonable. Sean
Jan 29 2006
Carlos Santander wrote:The following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?I used the Mac OS X kernel functions instead of custom assembly, but weren't able to find all the functions it needed (e.g. 64-bit) Guess you could get away with just assert(false) on those now ? Take a look in Kernel.framework and libkern, under "OSAtomic": http://developer.apple.com/documentation/Darwin/Reference/ KernellibkernFramework/OSAtomic/index.html If you want to roll your own, Linux/NetBSD PPC should have asm... e.g. http://cvsweb.netbsd.org/bsdweb.cgi/src/ For the moment you'll have to do that in a separate C file though, since GDC does not (yet) support inline PowerPC assembler blocks. --anders
Jan 27 2006
Anders F Björklund wrote:Carlos Santander wrote:Not all 32-bit hardware offers a 64-bit CAS instruction--x86 is one of the few. But this operation should not be necessary for most lock-free containers: slists, etc. If the Max offers kernel functions to perform these operations then it would be best to simply use those, and forget about anything that requires compareAndSet64. SeanThe following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?I used the Mac OS X kernel functions instead of custom assembly, but weren't able to find all the functions it needed (e.g. 64-bit) Guess you could get away with just assert(false) on those now ?
Jan 27 2006
Actually, only the compareAndSet32() is relevant. All those others are not used by the Locks package. "Anders F Björklund" <afb algonet.se> wrote in message news:drcm94$k77$1 digitaldaemon.com...Carlos Santander wrote:The following functions are part of Ben Hinkle's Locks library. I'm using GDC on Mac (PPC), so assembler (especially x86 assembler) isn't supported. I don't know assembly. Can somebody help me to translate them to D, please?I used the Mac OS X kernel functions instead of custom assembly, but weren't able to find all the functions it needed (e.g. 64-bit) Guess you could get away with just assert(false) on those now ? Take a look in Kernel.framework and libkern, under "OSAtomic": http://developer.apple.com/documentation/Darwin/Reference/ KernellibkernFramework/OSAtomic/index.html If you want to roll your own, Linux/NetBSD PPC should have asm... e.g. http://cvsweb.netbsd.org/bsdweb.cgi/src/ For the moment you'll have to do that in a separate C file though, since GDC does not (yet) support inline PowerPC assembler blocks. --anders
Jan 27 2006