view lphobos/internal/critical.d @ 920:545f54041d91

Implemented proper support for naked asm using llvm module level asm. Still not 100% complete, but already 1000 times better that what we had before. Don's BignumX86 implementation from Tango (when turned into a standalone unittest) seems to fully work with no changes, and great performance :) Fixed align N; in asm blocks. Fixed inreg parameter passing on x86 for ref/out params. Removed support for lazy initialization of function local static variables, I have no idea why I ever implemented this, it's not in the D spec, and DMD doesn't support it :P Some of the global variable related changes might cause minor regressions, but they should be easily fixable.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 03 Feb 2009 08:54:57 +0100
parents 373489eeaf90
children
line wrap: on
line source

module internal.critical;
extern(C):

import std.c.linux.linux, std.c.stdlib:ccalloc=calloc, cmalloc=malloc, cfree=free;

struct CritSec {
  pthread_mutex_t* p;
}

const PTHREAD_MUTEX_RECURSIVE = 1, PTHREAD_MUTEX_ERRORCHECK=2;

extern(C) int pthread_self();

void _d_criticalenter(CritSec* cs) {
  if (!cs.p) {
    auto newp = cast(pthread_mutex_t*) cmalloc(pthread_mutex_t.sizeof);
    auto cspp = &cs.p;
    pthread_mutexattr_t mt; pthread_mutexattr_init(&mt);
    pthread_mutexattr_settype(&mt, PTHREAD_MUTEX_RECURSIVE);
    printf("Create -> %i\n", pthread_mutex_init(newp, &mt));
    asm { xor EAX, EAX; mov ECX, newp; mov EDX, cspp; lock; cmpxchg int ptr [EDX], ECX; }
    if (cs.p != newp) pthread_mutex_destroy(newp);
  }
  auto count = (cast(uint*) cs.p)[1];
  // printf("%i ::%u\n", pthread_self(), count);
  //printf("%i: Lock %p -> %i\n", pthread_self(), cs.p,
    pthread_mutex_lock(cs.p);//);
}

void _d_criticalexit(CritSec* cs) {
  //printf("%i: Unlock %p -> %i\n", pthread_self(), cs.p,
    pthread_mutex_unlock(cs.p);//);
}

void _d_monitorenter(Object h)
{
    _d_criticalenter(cast(CritSec*) &h.__monitor);
}

void _d_monitorexit(Object h)
{
    _d_criticalexit(cast(CritSec*) &h.__monitor);
}

void _STI_monitor_staticctor() { }
void _STI_critical_init() { }
void _STI_critical_term() { }
void _STD_monitor_staticdtor() { }
void _STD_critical_term() { }