פונקציות עדכון אטומיות של RenderScript

סקירה כללית

כדי לעדכן ערכים ששותפו בין כמה שרשורים, משתמשים בפונקציות הבאות. הם מוודאים שהערכים מתעדכנים באופן אטומי, כלומר שהקריאות מהזיכרון, העדכונים והכתובות בזיכרון מתבצעים בסדר הנכון.

הפונקציות האלה איטיות יותר מהפונקציות המקבילות שאין להן מאפיין אטומי, לכן כדאי להשתמש בהן רק כשצריך סנכרון.

חשוב לזכור שב-RenderScript, סביר להניח שהקוד יפעל בשרשור נפרד גם אם לא יצרתם אותו באופן מפורש. לרוב, סביבת זמן הריצה של RenderScript תחלק את הביצוע של ליבה אחת לכמה חוטים. צריך לעדכן משתנים גלובליים באמצעות פונקציות אטומיות. אם אפשר, כדאי לשנות את האלגוריתם כדי להימנע מהן לגמרי.

סיכום

פונקציות
rsAtomicAdd הוספה ללא סיכון לבעיות בשרשור (thread-safe)
rsAtomicAnd ביטוי AND בינארי בטוח למחרוזות
rsAtomicCas השוואה והגדרה ללא סיכון לבעיות בשרשור (thread-safe)
rsAtomicDec הפחתה בטוחה למחרוזת
rsAtomicInc הוספה בטוחה למחרוזת (thread-safe)
rsAtomicMax ערך מקסימלי ללא סיכון לבעיות בשרשור
rsAtomicMin מינימום בטוח למספר השרשור
rsAtomicOr או ביטוי ברמת הסיביות ללא סיכון לבעיות בשרשור (thread-safe)
rsAtomicSub חיסור בטוח למספרי תהליכים
rsAtomicXor או בלעדי בוליאני ברמת הסיביות ללא סיכון לבעיות בשרשור (thread-safe)

פונקציות

rsAtomicAdd : הוספה ללא סיכון לתאונות בשרשור

int32_t rsAtomicAdd(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
int32_t rsAtomicAdd(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 20
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךהסכום להוספה.
החזרות
הערך של *addr לפני הפעולה.

הוספה אטומית של ערך לערך בכתובת addr, כלומר *addr += value.

rsAtomicAnd : ביט AND ללא סיכון לתאונות בשרשור

int32_t rsAtomicAnd(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
int32_t rsAtomicAnd(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 20
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךהערך של 'אל' ושל 'עם'.
החזרות
הערך של *addr לפני הפעולה.

ביצוע אטומי של ביט-בייט של שני ערכים, ושמירת התוצאה ב-addr, כלומר *addr &= value.

rsAtomicCas : השוואה והגדרה ללא סיכון לתאונות בשרשור

int32_t rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue); נוספה ב-רמת API 14
uint32_t rsAtomicCas(volatile uint32_t* addr, uint32_t compareValue, uint32_t newValue); נוספה ב-רמת API 14
פרמטרים
addrכתובת הערך שיש להשוות אליו ולהחליף אותו אם הבדיקה עוברת.
compareValueהערך שיש להשוות אליו את *addr.
newValueהערך שרוצים לכתוב אם הבדיקה עוברת.
החזרות
הערך של *addr לפני הפעולה.

אם הערך ב-addr תואם ל-compareValue, הערך החדש ייכתב ב-addr, כלומר if (*addr == compareValue) { *addr = newValue; }.

כדי לבדוק שהערך נכתב, בודקים שהערך המוחזר על ידי rsAtomicCas() הוא compareValue.

rsAtomicDec : הפחתה בטוחה למשיכות

int32_t rsAtomicDec(volatile int32_t* addr); נוספה ב-רמת API 14
int32_t rsAtomicDec(volatile uint32_t* addr); נוספה ב-רמת API 20
פרמטרים
addrהכתובת של הערך שרוצים להקטין.
החזרות
הערך של *addr לפני הפעולה.

הפונקציה מחסרת אטומית אחד מהערך ב-addr. זה שווה ערך ל-rsAtomicSub(addr, 1).

rsAtomicInc : הוספה בטוחה למחרוזת

int32_t rsAtomicInc(volatile int32_t* addr); נוספה ב-רמת API 14
int32_t rsAtomicInc(volatile uint32_t* addr); נוספה ב-רמת API 20
פרמטרים
addrהכתובת של הערך שרוצים להגדיל.
החזרות
הערך של *addr לפני הפעולה.

הוספה אטומית של אחד לערך ב-addr. זה שווה ערך ל-rsAtomicAdd(addr, 1).

rsAtomicMax : ערך מקסימלי ללא סיכון לתאונות בשרשור

int32_t rsAtomicMax(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
uint32_t rsAtomicMax(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 14
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךערך להשוואה.
החזרות
הערך של *addr לפני הפעולה.

הגדרה אטומית של הערך ב-addr לערך המקסימלי של *addr ו-value, כלומר *addr = max(*addr, value).

rsAtomicMin : ערך מינימלי בטוח לשרשור

int32_t rsAtomicMin(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
uint32_t rsAtomicMin(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 14
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךערך להשוואה.
החזרות
הערך של *addr לפני הפעולה.

הגדרה אטומית של הערך ב-addr לערך המינימלי של *addr ו-value, כלומר *addr = min(*addr, value).

rsAtomicOr : או בינארי בטוח למחרוזות

int32_t rsAtomicOr(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
int32_t rsAtomicOr(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 20
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךהערך של 'אל' או 'עם'.
החזרות
הערך של *addr לפני הפעולה.

ביצוע אופרטורים בייטיים של או או על שני ערכים באופן אטומי, ושמירת התוצאה ב-addr, כלומר *addr |= value.

rsAtomicSub : חיסור בטוח למספרי תהליכים

int32_t rsAtomicSub(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
int32_t rsAtomicSub(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 20
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךהסכום שיש לחסר.
החזרות
הערך של *addr לפני הפעולה.

הפונקציה מחסירת באופן אטומי ערך מהערך ב-addr, כלומר *addr -= value.

rsAtomicXor : XOR בלעדי ברמת הסיביות ללא סיכון לבעיות בשרשור

int32_t rsAtomicXor(volatile int32_t* addr, int32_t value); נוספה ב-רמת API 14
int32_t rsAtomicXor(volatile uint32_t* addr, uint32_t value); נוספה ב-רמת API 20
פרמטרים
addrכתובת הערך שרוצים לשנות.
ערךהערך שרוצים לבצע איתו XOR.
החזרות
הערך של *addr לפני הפעולה.

ביצוע אטומי של XOR בינארי של שני ערכים, ושמירת התוצאה ב-addr, כלומר *addr ^= value.