2009-05-02 19 views
10

Tôi biết về các hoạt động nguyên tử được xây dựng của GCC: http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Atomic-Builtins.htmlCách tốt hơn để thực hiện tải hoặc tải nguyên tử chung trong GCC?

Nhưng danh sách này không bao gồm các hoạt động rất đơn giản như tải và lưu trữ. Tôi có thể thực hiện những về kiến ​​trúc hạn chế với lắp ráp trực tiếp (trong thực tế đối với nhiều người như x86 họ sẽ có cơ bản chỉ thường xuyên mov), nhưng là không có cách nào tốt hơn trong trường hợp tổng quát hơn một cái gì đó như thế này:

// returns the value at ptr 
void *atomic_load_ptr(void **ptr) 
{ 
    return __sync_fetch_and_add(ptr, 0); 
} 

// returns old value int ptr after setting it to newval 
void *atomic_store_ptr(void **ptr, void *newval) 
{ 
    void *oldval = atomic_load_ptr(ptr) 
    void *oldval2; 
    do { 
     oldval2 = oldval; 
    } while ((oldval = __sync_val_compare_and_swap(ptr, oldval, newval)) != oldval2); 
    return oldval; 
} 
+0

Dừng tôi nếu tôi sai, nhưng chức năng "lưu trữ" của bạn không thực sự là một cửa hàng vì nó trả về giá trị cũ (vì vậy nó rất gần với CAS). – claf

+0

Thực sự là "trao đổi" - lưu trữ một giá trị mới và trả về giá trị trước đó nếu bạn muốn. –

+0

Tôi nhận thấy rằng việc triển khai tải này có vấn đề: nó không thể được sử dụng trên bộ nhớ chỉ đọc. – Mabus

Trả lời

2

Bạn có thể triển khai mutex ở mức độ thấp với test_and_set. Hàm tải là một hàm tốt, nhưng bạn lưu trữ hàm nên sử dụng hàm test_and_set thay vì có

while ((oldval = __sync_val_compare_and_swap(ptr, oldval, newval)) != oldval2); 

để ngăn lỗi.

Các vấn đề liên quan