Subj : Re: What is the real costs of LOCK on x86 multiprocesor machine? To : comp.programming.threads From : David Schwartz Date : Sat Jul 30 2005 02:19 pm "chris noonan" wrote in message news:1122727886.839675.223500@g14g2000cwa.googlegroups.com... > I vaguely remember encountering the LOCK prefix > in one or two places in Microsoft OS code disassembly > (uniprocessor installation). I assumed it was simply > a mistake, something like new routines being hacked > in quickly without them taking the trouble to add > the offsets of the LOCK prefixes to the list to be > NOP'ed out. By the way, the way I do this in applications is by using an illegal instruction. I catch the fault and replace the illegal instruction with either a LOCK or NOP at run time. static void sigill(int, struct siginfo *info, void *extra) { // Dynamically patch a 'ud2' to a 'lock nop' or a 'nop nop' // By: David J. Schwartz // Copyright (C) WebMaster Incorporated, 2003-4 // Begin with a full CPU sync (purge unmodified code) __asm__ __volatile__("cpuid" : : : "ax", "bx", "cx", "dx"); while(AtomicExchange(&sigspin, 1)!=0) { // relax the CPU __asm__ __volatile__("rep; nop"); } ucontext_t *uc=(ucontext_t *) extra; if(uc==NULL) {char *j=NULL; *j++;} else { unsigned char *instr=(unsigned char *) uc->uc_mcontext.gregs[14]; // EIP if(instr==NULL) {char *j=NULL; *j++;} else { if(instr[0]!=0x90) { // instruction wasn't already patched if ( (instr[0]!=0x0f) || // must be a ud2 ((instr[1]!=0x0b)&&(instr[1]!=0xb9)) ) { char *j=NULL; *j++; } else { mprotect( (void *) ( ((int) instr) & ~(PAGESIZE-1) ), PAGESIZE, PROT_WRITE | PROT_EXEC | PROT_READ); instr[0]=0x90; // first byte is always a nop instr[1]=(IsUP) ? 0x90 : 0xf0; mprotect( (void *) ( ((int) instr) & ~(PAGESIZE-1) ), PAGESIZE, PROT_EXEC | PROT_READ); } } } // release the lock AtomicExchange(&sigspin, 0); // Reflush the CPU __asm__ __volatile__("cpuid" : : : "ax", "bx", "cx", "dx"); } } DS .