LINUX.ORG.RU

Сообщения qweururu

 

Отличия C и C++

Форум — Development

Есть два эквивалентных примера:

#include <stdatomic.h>

int main() {
  int v[2], * p0 = v, * _Atomic p1 = v;
  if (p0 != p1) return 1;
  if (++p0 != ++p1) return 2;
  if (++p0 != (atomic_fetch_add_explicit(&p1, 1, memory_order_relaxed), p1)) return 3;
}

#include <atomic>
using namespace std;

int main() {
  int v[2], * p0 = v; atomic<int*> p1 = v;
  if (p0 != p1) return 1;
  if (++p0 != ++p1) return 2;
  if (++p0 != (p1.fetch_add(1, memory_order_relaxed), p1)) return 3;
}

C-версия делает return 3. Из-за того, что atomic_fetch_add_explicit(&p1, 1, memory_order_relaxed) компилируется в lock addq $0x1,-0x10(%rsp). В C++ lock addq $0x4,-0x10(%rsp) - как и должно быть, учитывает тип. Это баг какой-то или так специально сделано? Зачем?

 ,

qweururu
()

Синхронизация потоков

Форум — Development

Есть код такого вида:

#include <stdatomic.h>

struct { long l; char s[8]; } queue[1024 * 1024];
_Atomic int qsize;

void process_queue() {
  extern void process(typeof(*queue));
#ifdef X86
  for (int i; (i = atomic_fetch_sub_explicit(&qsize, 1, memory_order_acq_rel)) > 0; process(queue[i - 1]));
#else
  int i = atomic_fetch_sub_explicit(&qsize, 1, memory_order_acquire);
  while (i > 0) { process(queue[i - 1]); i = atomic_fetch_sub_explicit(&qsize, 1, memory_order_relaxed); }
  atomic_fetch_sub_explicit(&qsize, 1, memory_order_release);
#endif
}
void extra_thread() {
  while (1) { while (atomic_load_explicit(&qsize, memory_order_relaxed) <= 0); process_queue(); }
}
void main_thread() {
  while (1) {
    extern int thread_count;
    extern int get_data(typeof(queue), int);
    atomic_store_explicit(&qsize, get_data(queue, sizeof(queue) / sizeof(*queue)), memory_order_release);
    process_queue();
    while (atomic_load_explicit(&qsize, memory_order_relaxed) !=
#ifdef X86
      -thread_count + 1
#else
      -thread_count + 1 << 1
#endif
    );
  }
}

С х86 вопросов нет. Хоть как пиши - оно будет работать/тормозить одинаково. С чем-то другим не совсем понятно. Можно ли сделать лучше, чем мой вариант под #else?

В get_data сисколы и в реальности можно просто писать relaxed везде и всё будет работать. Но интересно как сделать «по правилам»(из стандарта).

 ,

qweururu
()

Атомарные операции

Форум — Development

Здесь написано следующее:

All writes in other threads that release the same atomic variable are visible in the current thread

All writes in the current thread are visible in other threads that acquire the same atomic variable

Это про acquire и release. Это обобщённая модель или существует/существовало железо, где действительно можно было не увидеть изменения из другого потока? Если да, то с какой целью такое поведение у железа было сделано?

 ,

qweururu
()

Размещение глобальных данных

Форум — Development

Пример:

int x;
double y;
struct { char zs[256]; } z;

int main() {}

Регламентирует ли стандарт C(или C++) размещение x/y/z? Порядок, выравнивание и подобное. Если есть инфа по реализациям(гцц/шланг) - тоже интересно. Вариант просто собрать посмотреть не подойдёт - нужна какая-то стабильность/гарантии, а не просто текущее положение дел.

 ,

qweururu
()

Изоляция ФС

Форум — Development

Есть потребность сделать некий каталог корневым для процесса. Есть chroot, но написано, что он дырявый. Ищу альтернативы без дыр. Напишите, кто знает.

 

qweururu
()

RSS подписка на новые темы