Пример #1
0
int ebsp_open_up_stream(void** address, unsigned stream_id) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return 0;
    }

    ebsp_stream_descriptor* stream = &coredata.local_streams[stream_id];

    if (stream->is_down_stream) {
        ebsp_message(err_mixed_up_down);
        return 0;
    }

    if (stream->current_buffer != NULL) {
        ebsp_message(err_create_opened);
        return 0;
    }

    stream->current_buffer = ebsp_malloc(stream->max_chunksize + sizeof(int));
    if (stream->current_buffer == NULL) {
        ebsp_message(err_out_of_memory);
        return 0;
    }

    (*address) = (void*)((unsigned)stream->current_buffer + sizeof(int));

    // Set the size to max_chunksize
    int* header = (int*)stream->current_buffer;
    header[0] = stream->max_chunksize;

    stream->cursor = stream->extmem_addr;

    return stream->max_chunksize;
}
Пример #2
0
void ebsp_close_up_stream(unsigned stream_id) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return;
    }

    ebsp_stream_descriptor* out_stream = &coredata.local_streams[stream_id];

    if (out_stream->is_down_stream) {
        ebsp_message(err_mixed_up_down);
        return;
    }

    if (out_stream->current_buffer == NULL) {
        ebsp_message(err_close_closed);
        return;
    }

    // wait for data transfer to finish before closing
    ebsp_dma_handle* desc = (ebsp_dma_handle*)&out_stream->e_dma_desc;
    ebsp_dma_wait(desc);

    ebsp_free(out_stream->current_buffer);
    out_stream->current_buffer = NULL;

    if (out_stream->next_buffer != NULL) {
        ebsp_free(out_stream->next_buffer);
        out_stream->next_buffer = NULL;
    }
}
Пример #3
0
void ebsp_close_down_stream(unsigned stream_id) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return;
    }

    ebsp_stream_descriptor* in_stream = &coredata.local_streams[stream_id];

    if (!(in_stream->is_down_stream)) {
        ebsp_message(err_mixed_up_down);
        return;
    }

    if (in_stream->current_buffer == NULL) {
        ebsp_message(err_close_closed);
        return;
    }

    ebsp_dma_handle* desc = (ebsp_dma_handle*)&in_stream->e_dma_desc;
    ebsp_dma_wait(desc);

    ebsp_free(in_stream->current_buffer);
    in_stream->current_buffer = NULL;

    if (in_stream->next_buffer != NULL) {
        ebsp_free(in_stream->next_buffer);
        in_stream->next_buffer = NULL;
    }
}
Пример #4
0
void ebsp_move_down_cursor(int stream_id, int jump_n_chunks) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return;
    }

    ebsp_stream_descriptor* in_stream = &coredata.local_streams[stream_id];

    if (jump_n_chunks > 0) // jump forward
    {
        while (jump_n_chunks--) {
            // read 2nd int in (next size) header from ext
            size_t chunk_size = *(int*)(in_stream->cursor + sizeof(int));
            if (chunk_size == 0) {
                ebsp_message(err_jump_out_of_bounds);
                return;
            }
            in_stream->cursor = (void*)(((unsigned)(in_stream->cursor)) +
                                        2 * sizeof(int) + chunk_size);
        }
    } else // jump backward
    {
        while (jump_n_chunks++) {
            // read 1st int in (prev size) header from ext
            int chunk_size = *(int*)(in_stream->cursor);
            if (chunk_size == 0) {
                ebsp_message(err_jump_out_of_bounds);
                return;
            }
            in_stream->cursor = (void*)(((unsigned)(in_stream->cursor)) -
                                        2 * sizeof(int) - chunk_size);
        }
    }
}
Пример #5
0
int ebsp_open_down_stream(void** address, unsigned stream_id) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return 0;
    }

    ebsp_stream_descriptor* stream = &coredata.local_streams[stream_id];

    if (!stream->is_down_stream) {
        ebsp_message(err_mixed_up_down);
        return 0;
    }
    if (stream->current_buffer != NULL || stream->next_buffer != NULL) {
        ebsp_message(err_open_opened);
        return 0;
    }

    stream->cursor = stream->extmem_addr;

    // this will be the current buffer when move_chunk_down gets called for
    // the first time
    stream->next_buffer = ebsp_malloc(stream->max_chunksize + 2 * sizeof(int));
    if (stream->next_buffer == NULL) {
        ebsp_message(err_out_of_memory);
        return 0;
    }

    _ebsp_write_chunk(stream, stream->next_buffer);

    *address = (void*)((unsigned)stream->next_buffer + 2 * sizeof(int));

    return stream->max_chunksize;
}
Пример #6
0
void _ebsp_write_chunk(ebsp_stream_descriptor* stream, void* target) {
    // read header from ext
    int prev_size = *(int*)(stream->cursor);
    int chunk_size = *(int*)(stream->cursor + sizeof(int));

    if (chunk_size != 0) // stream has not ended
    {
        void* dst = target + 2 * sizeof(int);
        void* src = stream->cursor + 2 * sizeof(int);

        // jump over header+chunk
        stream->cursor = (void*)(((unsigned)(stream->cursor)) +
                                 2 * sizeof(int) + chunk_size);

        // If token is too large, truncate it.
        // However DO jump the correct distance with cursor
        if (chunk_size > stream->max_chunksize) {
            ebsp_message(err_token_size2, chunk_size, stream->max_chunksize);
            chunk_size = stream->max_chunksize;
        }

        ebsp_dma_push(&stream->e_dma_desc, dst, src, chunk_size);
    }

    // copy it to local
    // we do NOT do this with the DMA because of the
    // possible trunction done above
    *(int*)(target) = prev_size;
    *(int*)(target + sizeof(int)) = chunk_size;
}
Пример #7
0
int main() {
    bsp_begin();
    int var = bsp_pid();
    int* unregistered_var = (int*)0x7000;
    char teststr[] = "Default test string!";
    char goodstr[] = "Replacement string.";
    bsp_push_reg(&var, sizeof(int));

    if (bsp_pid() != 2)
        bsp_sync();

    bsp_push_reg(teststr, sizeof(int));

    // Only core 2 will do both registrations in the same sync
    if (bsp_pid() == 2)
        bsp_sync();
    // expect: ($02: BSP ERROR: multiple bsp_push_reg calls within one sync)

    if (bsp_pid() == 1) {
        bsp_hpput(0, &var, &var, 0, sizeof(int));
        bsp_hpput(0, &var, unregistered_var, 0, sizeof(int)); // Error
        // expect: ($01: BSP ERROR: could not find bsp var 0x7000)
    }
    if (bsp_pid() == 0) {
        bsp_hpput(1, goodstr, teststr, 0, 19 * sizeof(char));
    }

    bsp_sync();

    if (bsp_pid() == 0)
        ebsp_message("%d", var);
    // expect: ($00: 1)
    bsp_sync();
    if (bsp_pid() == 1)
        ebsp_message(teststr);
    // expect: ($01: Replacement string.!)

    bsp_end();
    return 0;
}
Пример #8
0
int main()
{
    bsp_begin();

    int n = bsp_nprocs();
    int p = bsp_pid();

    ebsp_message("Hello world from core %d/%d", p, n);

    bsp_end();

    return 0;
}
Пример #9
0
void ebsp_reset_down_cursor(int stream_id) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return;
    }

    ebsp_stream_descriptor* in_stream = &coredata.local_streams[stream_id];

    size_t chunk_size = -1;

    // break when previous block has size 0 (begin of stream)
    while (chunk_size != 0) {
        // read 1st int in (prev size) header from ext
        chunk_size = *(int*)(in_stream->cursor);
        in_stream->cursor = (void*)(((unsigned)(in_stream->cursor)) -
                                    2 * sizeof(int) - chunk_size);
    }
}
Пример #10
0
void EXT_MEM_TEXT
bsp_send(int pid, const void* tag, const void* payload, int nbytes) {
    unsigned int index;
    unsigned int payload_offset;
    unsigned int total_nbytes = coredata.tagsize + nbytes;

    ebsp_message_queue* q =
        &combuf->message_queue[coredata.read_queue_index ^ 1];

    e_mutex_lock(0, 0, &coredata.payload_mutex);

    index = q->count;
    payload_offset = combuf->data_payloads.buffer_size;

    if ((payload_offset + total_nbytes > MAX_PAYLOAD_SIZE) ||
        (index >= MAX_MESSAGES)) {
        index = -1;
        payload_offset = -1;
    } else {
        q->count++;
        combuf->data_payloads.buffer_size += total_nbytes;
    }

    e_mutex_unlock(0, 0, &coredata.payload_mutex);

    if (index == -1)
        return ebsp_message(err_send_overflow);

    // We are now ready to save the request and payload
    void* tag_ptr = &combuf->data_payloads.buf[payload_offset];
    payload_offset += coredata.tagsize;
    void* payload_ptr = &combuf->data_payloads.buf[payload_offset];

    q->message[index].pid = pid;
    q->message[index].tag = tag_ptr;
    q->message[index].payload = payload_ptr;
    q->message[index].nbytes = nbytes;

    ebsp_memcpy(tag_ptr, tag, coredata.tagsize);
    ebsp_memcpy(payload_ptr, payload, nbytes);
}
Пример #11
0
int main()
{
    bsp_begin();
    int s = bsp_pid();

    std::vector<int> vec = {5, 7, 12};

    MySubClass<int> b;
    b.foo(17);

    for (auto i : vec) {
        if (s < 4)
            b.bar(nullptr);
        else if (s < 8)
            b.bar(func);
        else
            b.bar([&i](int x) {
                    ebsp_message("lambda i = %d, x = %d", i, x);
                });
    }

    bsp_end();
    return 0;
}
Пример #12
0
void func(int a) {
    ebsp_message("func a = %d", a);
}
Пример #13
0
 void bar(std::function<void(T)> f) const {
     if (f)
         f(value);
     else
         ebsp_message("nullptr passed to MySubClass::bar");
 }
Пример #14
0
int ebsp_move_chunk_down(void** address, unsigned stream_id, int prealloc) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return 0;
    }

    ebsp_stream_descriptor* stream = &coredata.local_streams[stream_id];

    ebsp_dma_handle* desc = (ebsp_dma_handle*)(&(stream->e_dma_desc));

    // if(stream->current_buffer == NULL)
    //    stream->current_buffer =
    //                     ebsp_malloc(stream->max_chunksize + 2*sizeof(int));

    // Here: current_buffer contains data from previous chunk
    // this can be null the first time ebsp_move_chunk_down is called

    if (!(stream->is_down_stream)) {
        ebsp_message(err_mixed_up_down);
        return 0;
    }

    if (stream->next_buffer == NULL) // did not prealloc last time
    {
        // overwrite current buffer
        _ebsp_write_chunk(stream, stream->current_buffer);
    } else // did prealloc last time
    {
        void* tmp = stream->current_buffer;
        stream->current_buffer = stream->next_buffer;
        stream->next_buffer = tmp;
    }

    // either wait for dma_push from last prealloc (else)
    // or the one we just started (if)
    ebsp_dma_wait(desc);

    // Here: current_buffer contains data from THIS chunk

    // *address must point after the counter header
    (*address) = (void*)((unsigned)stream->current_buffer + 2 * sizeof(int));

    // the counter header
    int current_chunk_size =
        *((int*)((unsigned)stream->current_buffer + sizeof(int)));

    if (current_chunk_size == 0) // stream has ended
    {
        (*address) = NULL;
        return 0;
    }

    if (prealloc) {
        if (stream->next_buffer == NULL) {
            // no next buffer available, malloc it
            stream->next_buffer =
                ebsp_malloc(stream->max_chunksize + 2 * sizeof(int));
            if (stream->next_buffer == NULL) {
                ebsp_message(err_out_of_memory);
                return 0;
            }
        }
        _ebsp_write_chunk(stream, stream->next_buffer);
    } else {
        // free malloced next buffer
        if (stream->next_buffer != NULL) {
            ebsp_free(stream->next_buffer);
            stream->next_buffer = NULL;
        }
    }

    // Here: next_buffer should (possibly) point to data of NEXT
    // chunk (begin written to) or be zero

    return current_chunk_size;
}
Пример #15
0
int ebsp_move_chunk_up(void** address, unsigned stream_id, int prealloc) {
    if (stream_id >= coredata.local_nstreams) {
        ebsp_message(err_no_such_stream);
        return 0;
    }

    ebsp_stream_descriptor* stream = &coredata.local_streams[stream_id];

    if (stream->is_down_stream) {
        ebsp_message(err_mixed_up_down);
        return 0;
    }

    ebsp_dma_handle* desc = (ebsp_dma_handle*)&stream->e_dma_desc;

    // if we prealloced last time, we have to wait until dma is finished
    if (stream->next_buffer != NULL) {
        ebsp_dma_wait(desc);
    }

    if (prealloc) {
        if (stream->next_buffer == NULL) {
            stream->next_buffer =
                ebsp_malloc(stream->max_chunksize + sizeof(int));
            if (stream->next_buffer == NULL) {
                ebsp_message(err_out_of_memory);
                return 0;
            }
        }

        // read int header from current_buffer (next size)
        int chunk_size = ((int*)stream->current_buffer)[0];

        void* src = (void*)((unsigned)stream->current_buffer + sizeof(int));
        void* dst = stream->cursor;

        ebsp_dma_push(desc, dst, src, chunk_size); // start dma
        // ebsp_dma_start();

        void* tmp = stream->current_buffer; // swap buffers
        stream->current_buffer = stream->next_buffer;
        stream->next_buffer = tmp;

        stream->cursor += chunk_size; // move pointer in extmem
    } else                            // no prealloc
    {
        if (stream->next_buffer != NULL) {
            ebsp_free(stream->next_buffer);
            stream->next_buffer = NULL;
        }

        // read int header from current_buffer (next size)
        int chunk_size = ((int*)stream->current_buffer)[0];

        void* src = (void*)((unsigned)stream->current_buffer + sizeof(int));
        void* dst = stream->cursor;

        ebsp_dma_push(desc, dst, src, chunk_size); // start dma
        // ebsp_dma_start();
        ebsp_dma_wait(desc);

        stream->cursor += chunk_size; // move pointer in extmem
    }

    (*address) = (void*)((unsigned)stream->current_buffer + sizeof(int));

    // Set the out_size to max_chunksize
    *((int*)(stream->current_buffer)) = stream->max_chunksize;

    return stream->max_chunksize;
}