Universal References in C++11

К сожалению, мне еще не довелось использовать C++11 в каком-либо боевом проекте, так что приходится ограничиваться тестами, да всякими лекциями. В очередной раз наткнулся на показавшуюся мне интересной лекцию, на сей раз от Скотта Мейерса, посвященную универсальным ссылкам (насколько я понял, термин свежеизобретенный, автор сам Майерс). Лекция длинная, и если в кратце, то ее суть вот в чем:

Widget&& var1 = someWidget; // here, "&&" means rvalue reference

auto&& var2 = var1; // here, "&&" does not mean rvalue reference

template<typename T>
void f(std::vector<T>&& param); // here, "&&" means rvalue reference

template<typename T>
void f(T&& param); // here, "&&" does not mean rvalue reference

В то же время, я о потраченных 83 минутах не пожалел.

ARM архитектура

На РСДН-е возник заинтересовавший меня вопрос: что бы такого почитать про архитектуру ARM процессоров. Лично меня этот вопрос интересовал давно, но все время находилось что-то более срочное, но сейчас я решил хотя бы поверхностно ознакомится с темой.
Первое что приходит в голову – это полистать ARM* Architecture Reference Manual (документ бесплатен, но требуется предварительная регистрация на сайте). Документ полезный, но вот по увлекательности для чтения несколько не дотягивает до стандарта C++, т.е. просмотреть его можно, но вот при детальном чтении велик риск довольно быстро заснуть.

К куда более увлекательным и полезным можно отнести:

1. ARM assembler от Richard Murray. Краткое введение в ARM ассемблер и архитектуру процессоров. Сайт довольно “олдскульный”, но наполнение скучать не заставит.
2. Introduction to ARM, от David Thomas. Мне понравилось – понятно, кратко, интересно, да и вид сайта современный. Читается легко и риск заснуть минимален.
3. ARM System Developer’s Guide. Книга продается на Amazon за довольно таки большие деньги – $74.10, но судя по отзывам она великолепна. Полистал – действительно книга на высоте, и если есть желание или необходимость разобраться с ARM более-менее прилично, то читать ее нужно.

Монитор от Герба Саттера

В недавно вышедшем выступлении Герба Саттера посвященном многопоточности он привел интересный пример примитива для синхронного выполнения последовательностей операций. Сам Майерс окрестил детище “монитором”, по аналогии с мониторами из мира Java и C#, хотя на мой взгляд, сходства между ними не так уж и много. Суть задумки в том, что бы синхронизировать работу с каким-либо объектом, который изначально не поддерживает синхронизации. При этом, обеспечив синхронность не только на уровне одной операции, но и на уровне “трансзакции”.

string s = "Start\n";
vector<future <void>> v;

for(int i=0; i&lt;5; ++i)
{
    v.push_back(async([&,i]{
        {
            // необходимо сделать атомарно.
            s += to_string(i) + " " + to_string(i);
            s += "\n";
        }
        {
            // так же необходимо сделать атомарно.
            cout < < s;
        }
    }));
}

В принципе, в приведенном выше примере вполне можно воспользоваться комбинацией mutex + lock_guard, но так не интересно, не красиво, да и о чем было бы рассказывать в течении полутора часов?
Решение предложенно действительно элегантное: Continue reading

RB-tree в sglib

Наткнулся на довольно мерзкий баг, в когда-то уважаемой мной библиотеке sglib. Дело в том, что на определенных наборах данных у rb-tree из этой библиотеки сносит башню! В результате добавленные ранее элементы перестают находиться, хотя, количество элементов не изменяется и при обходе дерева все элементы в нем присутствуют.

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include "sglib.h"

struct rb_tree
{
    int64_t data;
    char color_field;
    struct rb_tree *left;
    struct rb_tree *right;
};
typedef struct rb_tree rb_tree;

#define CMPARATOR(x,y) ((x->data)-(y->data))

SGLIB_DEFINE_RBTREE_PROTOTYPES(rb_tree, left, right, color_field, CMPARATOR);
SGLIB_DEFINE_RBTREE_FUNCTIONS(rb_tree, left, right, color_field, CMPARATOR);

rb_tree *the_tree = 0;

int main(int argc, char *argv[])
{
    if( argc < 2 )
        return -1;

    const char *data_file_path = argv[1];
    FILE *data_file;
    data_file = fopen( data_file_path, "r" );
    if( 0 == data_file )
        return -1;

    uint64_t value;
    rb_tree *node, e;
    e.data = 6610223104;
    int added = 0;
    while( EOF != fscanf( data_file, "%llun", &value ) )
    {
        if( value == e.data )
            added = 1;
        node = malloc( sizeof(rb_tree) );
        node->data = value;
        sglib_rb_tree_add( &the_tree, node );
        if( 0 != added )
        {
            node = sglib_rb_tree_find_member( the_tree, &e );
            if( 0 == node )
                printf("ERRORn");
        }
    }

    return 0;
}

Файл с тестовыми данными.

Channel 9 продолжает радовать

Вообще, мне не очень нравится Channel 9. Обычно он представляет собой какое-то нелепое, скучное нагромождение мелкософт-ориентированной попсятины, что, вобщем-то ожидаемо, с учетом того кому этот канал принадлежит. Но, то ли в честь нового года, то ли в честь так и не пришедшего конца света, на сайте появилось еще одно замечательное выступление от Саттера: C++ and Beyond 2012: Herb Sutter – C++ Concurrency. Кстати, а до этого было не менее интересное C++ and Beyond 2012: Herb Sutter – You don’t know [blank] and [blank]

Модель памяти Rust

Модель памяти Rust довольно сильно отличается как от управляемых языков типа Java или C#, так и от не управляемых языков типа C и C++. Так как Rust является совершенно новым языком программирования и не ограничен какими-либо требованиями совместимости с предшественниками, он реализует наиболее удобную модель памяти для решения следующих целей:
Безопасность. Предотвращение возникновения утечек памяти или ошибок сегментации.
Производительность. Сборщик мусора управляет указателями а не объектами. Нет необходимости замораживать все задачи для очистки памяти, так как каждая из них имеет собственный хип.
Многопоточность. Предотвращение возникновения гонок в памяти, так как каждая из задач имеет собственный хип и передаваемые между задачами данные должны копироваться. Наличие хипа обмена для избежания лишних операций копирования с семантикой владения. Continue reading