Я пытаюсь использовать CAS для обеспечения безопасности потоков во встроенной системе.К сожалению, он не работает должным образом.
Допустим, существует глобальный массив, и к нему будут обращаться несколько потоков.
typedef struct{
int in_use;
data_type data;
} item_type;
item_type global_array[N]
Идея такова: потоки могут использовать доступный элемент в global_array, который указываетфлагом "in_use".реализация, как показано ниже:
item_type* get_available_item_pointer(void){
int available_index = N;
for (int i=0; i<N; i++){
if (atomic_compare_and_set(&(global_array[index].in_use), FALSE, TRUE))
{
available_index = i;
break;
}
}
return &(global_array[index]);
}
void free_item_pointer(item_type* item_ptr){
if (item_ptr->in_use){
memset(&item_ptr->data, 0x0, sizeof(data_type));
item_ptr->in_use = FALSE; //should I use atomic function for this line?
}
}
В плохом случае я обнаружил, что 2 потока имеют доступ к одному и тому же элементу и имеют повреждение данных, я понятия не имею, почему это возможно?
thread A is calling get_available_item_pointer() //return index 0
thread B is calling free_item_pointer() //freeing index 0
Кстати, реализация atomic_compare_and_set выглядит так:
static inline int atomic_compare_and_set(
unsigned int* target,
unsigned int old_val,
unsigned int new_val)
{
unsigned int current_val;
__asm__ __volatile__(
......
return current_val == old_val;
}