জায়গা: আমি এমন একটি এআরএম এমবেডেড (প্রায় খালি ধাতব) পরিবেশের সাথে কাজ করছি যেখানে আমার সি ++ 11 (সহ std::atomic<int>
) উপলব্ধ নেই, সুতরাং দয়া করে " কেবলমাত্র স্ট্যান্ডার্ড সি ++ ব্যবহার করুনstd::atomic<int>
" এর মতো উত্তরগুলি এড়িয়ে চলুন : আমি পারছি না ।
এটি কি এটমিক্যান্টের এআরএম বাস্তবায়ন সঠিক? ( ধরুন এআরএম আর্কিটেকচারটি এআরএমভি 7-এ )
আপনি কিছু সিঙ্ক্রোনাইজেশন সমস্যা দেখতে পাচ্ছেন? এটি volatile
প্রয়োজনীয় / দরকারী?
// File: atomic_int.h
#ifndef ATOMIC_INT_H_
#define ATOMIC_INT_H_
#include <stdint.h>
class AtomicInt
{
public:
AtomicInt(int32_t init = 0) : atom(init) { }
~AtomicInt() {}
int32_t add(int32_t value); // Implement 'add' method in platform-specific file
int32_t sub(int32_t value) { return add(-value); }
int32_t inc(void) { return add(1); }
int32_t dec(void) { return add(-1); }
private:
volatile int32_t atom;
};
#endif
// File: arm/atomic_int.cpp
#include "atomic_int.h"
int32_t AtomicInt::add(int32_t value)
{
int32_t res, prev, tmp;
asm volatile(
"try: ldrex %1, [%3]\n" // prev = atom;
" add %0, %1, %4\n" // res = prev + value;
" strex %2, %0, [%3]\n" // tmp = outcome(atom = res); // may fail
" teq %2, #0\n" // if (tmp)
" bne try" // goto try; /* add failed: someone else modified atom -> retry */
: "=&r" (res), "=&r" (prev), "=&r" (tmp), "+mo" (atom) // output (atom is both in-out)
: "r" (value) // input
: "cc"); // clobbers (condition code register [CPSR] changed)
return prev; // safe return (local variable cannot be changed by other execution contexts)
}
এছাড়াও, আমি কিছু কোড পুনরায় ব্যবহারের চেষ্টা করছি, সে কারণেই আমি প্ল্যাটফর্ম-নির্দিষ্ট কোড (অভ্যন্তরীণ add()
পদ্ধতি arm/atomic_int.cpp
) প্রয়োগ করতে কেবল একটি প্রাথমিক ফাংশনকে পৃথক করেছিলাম ।
কি atomic_int.h
সত্যিই পোর্টেবল যেমন বিভিন্ন প্ল্যাটফর্মের / আর্কিটেকচারের / কম্পাইলার জুড়ে যায়? এই পদ্ধতির কি সম্ভব ? ( সম্ভবপরতার সাথে আমি প্রতিটি প্ল্যাটফর্মের পক্ষে কেবলমাত্র add()
পদ্ধতিটি প্রয়োগ করে পারমাণবিকতার গ্যারান্টি দেওয়া সম্ভব ))
এখানে একই এআরএম জিসিসি 8.3.1 একই ফাংশনটির বাস্তবায়ন রয়েছে। স্পষ্টতই, একমাত্র আসল পার্থক্য হ'ল dmb
আগে এবং পরে উপস্থিতি । তারা কি সত্যিই আমার ক্ষেত্রে প্রয়োজন? কেন? আমার AtomicInt
(ব্যতীত dmb
) ব্যর্থ হয়েছে এমন কোনও উদাহরণ কি আপনার আছে ?
আপডেট: স্থির বাস্তবায়ন, get()
পারমাণবিকতা এবং প্রান্তিককরণ সমস্যা সমাধানের জন্য সরানো পদ্ধতি। এখন add()
স্ট্যান্ডার্ডের মতো আচরণ করে fetchAndAdd()
।
__ATOMIC_INT_H_
) নাম এবং মূল নাম সহ একটি আন্ডারস্কোর দিয়ে শুরু হওয়া নামগুলি প্রয়োগের মাধ্যমে ব্যবহারের জন্য সংরক্ষিত। এগুলি আপনার কোডে ব্যবহার করবেন না।
atomic
সম্ভবত বিভ্রান্তি এড়াতে সবচেয়ে বেশি ব্যবহৃত হয় না std::atomic
, যদিও আপনি যে কোনও ক্ষেত্রে কেবল এটি ব্যবহার করবেন না কেন তা প্রশ্ন করে।
__ATOMIC_INT_H_
শনাক্তকারী।
volatile
সি ++ এর কীওয়ার্ডের অর্থ ভেরিয়েবলের মাধ্যমে অনুকূলিতকরণ করবেন না। সুতরাংget()
পদ্ধতি এটি থেকে উপকৃত হয়। যদিও, সাধারণভাবে, অস্থির সি ++ এ অবসন্ন হতে চলেছে। যদি আপনার সিস্টেমটি অন্তর্নির্মিত 32-বিট ডেটা সিঙ্ক্রোনাইজ করতে না পারে, তবে আপনার কাছে খুব পরিমাণে স্পিনলক - মিউটেক্সগুলি ব্যবহার করা ছাড়া বিকল্প নেই।