2010-01-23 19 views
5

Ich habe für atomare Inkrement und Dekrement-Operatoren auf Mac OS X gegoogelt und "OSAtomic.h" gefunden, aber es scheint, dass Sie dies nur im Kernelraum verwenden können.Atom-Inkrement auf Mac OS X

Jeremy Friesner wies mich auf eine Cross-Plattform atomic counter in denen sie Assembly oder Mutex auf OS X verwenden (soweit ich das Interleaving von Ifdefs verstanden).

Gibt es unter OS X nicht so etwas wie InterlockedDecrement oder atomic_dec()?

Antwort

7

Was lässt Sie vermuten, dass OSAtomic nur Kernel-Space ist? Das folgende kompiliert und funktioniert gut.

#include <libkern/OSAtomic.h> 
#include <stdio.h> 

int main(int argc, char** argv) { 
    int32_t foo = 1; 
    OSAtomicDecrement32(&foo); 
    printf("%d\n", foo); 

    return 0; 
} 
+0

Geee, das ist seltsam! http://developer.apple.com/Mac/library/documentation/Darwin/Reference/KernelIOKitFramework/OSAtomic_h/index.html gibt OSDecrementAtomic an, aber ich sehe keinen Verweis auf OSAtomicDecrement32, obwohl es gut kompiliert wird. Das Kernel-Ding wurde nur in einem Mailing-Listen-Archiv gelesen ... Danke PS: Wenn Sie wissen, warum der Doc anders als Ihr Code sagt, würde ich mich freuen zu wissen. – gaspard

+0

Der 'libkern'-Teil impliziert nicht _kernel mode_. Sie werden als Teil des Kernel- und Treiberentwicklungsframeworks angeboten - siehe (http://developer.apple.com/mac/library/documentation/DriversKernelHardware/Reference/libkern_ref/index.html) für Details. Vielleicht möchten Sie stattdessen die 'OSAtomicDecrement32Barrier()' Variante verwenden. –

+0

@ D.Shawley: Ich brauche die Speicherbarriere nicht, da ich Speicher nicht zuweisst (ich benutze den Zähler für eine gleichzeitige Referenzzählung Klasse). – gaspard

1

Sie können auch IncrementAtomic() und DecrementAtomic() über Coreservices nutzen:

#include <CoreServices/CoreServices.h> 

int main(int argc, char** argv) 
{ 
    int val = 0; 
    IncrementAtomic(&val); 
    DecrementAtomic(&val);  

    return 0; 
} 

Hinweis: Der Rückgabewert dieser Funktionen ist der Wert der ganzen Zahl vor es erhöht wird, wenn Sie so wollen Ähnlich wie bei den Funktionen Win32 InterlockedIncrement() und InterlockedDecrement() müssen Sie Wrapper erstellen, die den Rückgabewert +1 enthalten.