Beispiel #1
0
SXE_RETURN
sxe_ring_buffer_consumed(void * base, SXE_RING_BUFFER_CONTEXT * context, unsigned len)
{
    SXE_RETURN result = SXE_RETURN_OK;
    SXEE81("sxe_ring_buffer_consumed(len:%u)", len);

    if ((result = sxe_ring_buffer_check_over_run(base, context)) == SXE_RETURN_ERROR_INTERNAL) {
        goto SXE_ERROR_OUT;
    }

    SXEL92("data_block was: %p, moving to %p", context->data_block, context->data_block + len);
    context->data_block     += len;
    context->data_block_len -= len;

    SXEA10(context->data_block <= SXE_RING_BUFFER_WRITEN_END + 1, "the data block did not go off the end of the array");

    if ((context->data_block == SXE_RING_BUFFER_WRITEN_END + 1) && (context->data_block != SXE_RING_BUFFER_CURRENT)) {
        SXEA10(context->data_block_len == 0, "If this consume brought us to the end of the array, the remaining length must be zero");
        SXEL90("Wrapping data_block to the start of the ring");
        context->data_block = SXE_RING_BUFFER_ARRAY_BASE;
        context->itteration++;
    }

SXE_EARLY_OR_ERROR_OUT:
    SXEL93("context data_block: %p, data_block_len: %u itteration: %u", context->data_block, context->data_block_len, context->itteration);
    SXER81("return %s", sxe_return_to_string(result));
    return result;
}
Beispiel #2
0
static SXE_THREAD_RETURN SXE_STDCALL
test_thread_main(void * lock)
{
    SXEE81("test_thread_main(lock=%p)", lock);

    SXEA10(lock                     == &ping,                     "Ping lock not passed to the thread");
    SXEA10(sxe_spinlock_take(&pong) == SXE_SPINLOCK_STATUS_TAKEN, "Pong lock not taken by thread");
    SXEA10(sxe_spinlock_take(&ping) == SXE_SPINLOCK_STATUS_TAKEN, "Ping lock not taken by thread");
    SXEL10("thread: about to pong the main thread");
    sxe_spinlock_give(&pong);

    for (;;) {
        sleep(1);
    }

    SXER80("return NULL");
    return (SXE_THREAD_RETURN)0;
}
Beispiel #3
0
void
sxe_ring_buffer_next_writable_block(void * base, SXE_RING_BUFFER_CONTEXT * context)
{
    SXEE80("sxe_ring_buffer_next_writable_block()");
    context->writable_block = SXE_RING_BUFFER_CURRENT;
    context->writable_block_len = SXE_RING_BUFFER_END - SXE_RING_BUFFER_CURRENT + 1;
    SXEA10(context->writable_block_len != 0, "The writable block length is not zero");
    SXEL92("Writable block: %p, Writable block length: %u", context->writable_block, context->writable_block_len);
    SXER80("return");
}
Beispiel #4
0
void
sxe_ring_buffer_next_writable_block_size(void * base, SXE_RING_BUFFER_CONTEXT * context, unsigned size)
{
    SXEE81("sxe_ring_buffer_next_writable_block_size(size=%u)", size);
    SXEA10(size <= SXE_RING_BUFFER_SIZE, "The requested size is equall or smaller then the ring");
    sxe_ring_buffer_next_writable_block(base, context);
    if (context->writable_block_len < size) {
        sxe_ring_buffer_force_ring_wrap(base);
        sxe_ring_buffer_next_writable_block(base, context);
    }
    SXER80("return");
}
Beispiel #5
0
void *
sxe_sync_ev_new(void * user_data)
{
    unsigned id;

    SXEE81("sxe_sync_ev_new(user_data=%p)", user_data);
    SXEA10((id = sxe_pool_set_oldest_element_state(sxe_sync_ev_pool, 0, 1)) != SXE_POOL_NO_INDEX,
           "Could not allocate a sync object");
    sxe_sync_ev_pool[id].sock      = sxe_sync_ev_socket();
    sxe_sync_ev_pool[id].user_data = user_data;

    SXER81("return sync=%p", &sxe_sync_ev_pool[id]);
    return &sxe_sync_ev_pool[id];
}
Beispiel #6
0
void
sxe_ring_buffer_wrote_block(void * base, SXE_RING_BUFFER_CONTEXT * context, unsigned len)
{
    SXEE81("sxe_ring_buffer_wrote_block(len=%u)", len);
    SXEA10(context->writable_block == SXE_RING_BUFFER_CURRENT, "The current pointer is still where it was when you asked for it");
    SXEA10(len <= (unsigned)(SXE_RING_BUFFER_END - SXE_RING_BUFFER_CURRENT + 1), "Did not overwrite end of buffer ring");

    SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_CURRENT + len;

    if (SXE_RING_BUFFER_CURRENT == (SXE_RING_BUFFER_END + 1)) {
        SXEL90("Wrote to the last byte in the array, wrapping pointer");
        SXE_RING_BUFFER_ITERATION++;
        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
        SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_END;
    }
    else {
        if (SXE_RING_BUFFER_WRITEN_END < SXE_RING_BUFFER_CURRENT) {
            SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT - 1;
        }
    }

    SXEL93("Current: %p, Writen End %p, Itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_WRITEN_END, SXE_RING_BUFFER_ITERATION);
    SXER80("return");
}
Beispiel #7
0
void *
sxe_ring_buffer_new(unsigned size)
{
    void * base;

    SXEE81("sxe_ring_buffer_new(size=%u)", size);
    SXEA10((base = malloc(size + SXE_RING_BUFFER_SIZE_OF_INTERNALS)) != NULL, "Error allocating sxe-ring-buffer");

    SXE_RING_BUFFER_SIZE       = size;
    SXE_RING_BUFFER_ITERATION  = 0;
    SXE_RING_BUFFER_CURRENT    = SXE_RING_BUFFER_ARRAY_BASE;
    SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT;

    SXEL92("Array base=%p, End of Array=%p", SXE_RING_BUFFER_ARRAY_BASE, SXE_RING_BUFFER_END);
    SXER81("return base=%p", base);
    return base;
}
Beispiel #8
0
void
sxe_ring_buffer_add(void * base, const char * buf, unsigned len)
{
    unsigned available_space;

    SXEE82("sxe_ring_buffer_add(buf=%p,len=%u)", buf, len);
    SXEL92("Current: %p, Itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_ITERATION);

    SXEA10(len <= SXE_RING_BUFFER_SIZE, "The item we're will fit in the whole array");

    available_space = (SXE_RING_BUFFER_END - SXE_RING_BUFFER_CURRENT + 1);
    SXEL91("There is %u space between the current pointer and the end of the array", available_space);

    if (available_space >= len) { // Can we fit it on the end of the array?
        SXEL92("Adding %u bytes at %p", len, SXE_RING_BUFFER_CURRENT);
        memcpy(SXE_RING_BUFFER_CURRENT, buf, len);

        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_CURRENT + len;
        if (SXE_RING_BUFFER_CURRENT == (SXE_RING_BUFFER_END + 1)) {
            SXEL90("Wrote to the last byte in the array, wrapping pointer");
            SXE_RING_BUFFER_ITERATION++;
            SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
            SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_END;
        }
        else {
            if (SXE_RING_BUFFER_WRITEN_END < SXE_RING_BUFFER_CURRENT) {
                SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT - 1;
            }
        }
    }
    else { // else we have to wrap around the ring
        memcpy(SXE_RING_BUFFER_CURRENT, buf, available_space);
        SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_END;
        SXE_RING_BUFFER_ITERATION++;
        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE;
        memcpy(SXE_RING_BUFFER_CURRENT, buf + available_space, (len - available_space));
        SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_CURRENT + (len - available_space);
    }

    SXEL93("Current: %p, Writen End %p, Itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_WRITEN_END, SXE_RING_BUFFER_ITERATION);
    SXER80("return");
}
Beispiel #9
0
/* Note that the decoded_name will be NUL terminated, and therefore the
 * maximum_name_length_maximum should probably be 254 and not 253 (though, with
 * pointers, the decoded name could well be *longer* than 253 characters!
 */
static SXE_RETURN
sxe_dns_decode_name(
    const unsigned char * dns_packet                 ,
    unsigned                dns_packet_length          ,
    unsigned              name_offset                ,
    char                * decoded_name               ,
    unsigned                decoded_name_length_maximum,
    unsigned              * decoded_name_length        )
{
    SXE_RETURN result = SXE_RETURN_ERROR_INTERNAL;
    unsigned   decoded_name_offset = 0;

    SXEE86("sxe_dns_decode_name(dns_packet=%p, dns_packet_length=%u, name_offset=%u, decoded_name=%p, decoded_name_length_maximum=%u, decoded_name_length=%p)", dns_packet, dns_packet_length, name_offset, decoded_name, decoded_name_length_maximum, decoded_name_length);
    SXEA10(decoded_name_length != 0,                                 "A value for decoded_name_length must be provided");
    SXEA10(decoded_name == NULL || decoded_name_length_maximum != 0, "NAME can not be decoded into an empty buffer");

    while (name_offset < dns_packet_length) {
        unsigned char len = dns_packet[name_offset];

        if (len == '\0') {
            SXEL60("NAME is terminated normally");
            if (decoded_name_offset > 0) {
                --decoded_name_offset;
            }

            if (decoded_name != NULL) {
                decoded_name[decoded_name_offset] = '\0';
            }
            *decoded_name_length = decoded_name_offset;
            result = SXE_RETURN_OK;
            goto SXE_EARLY_OUT;
        }
        else if ((len & SXE_DNS_LABEL_LENGTH_POINTER) == 0) {
            SXEL73("Normal label of length %u '%.*s'", len, len, &dns_packet[name_offset + 1]);

            /* Don't allow the NAME to exceed the known packet length */
            if ((decoded_name != NULL) && (decoded_name_offset + len + 1 >= decoded_name_length_maximum)) {
                SXEL51("sxe_dns_decode_name(): NAME is invalid; Decoded NAME is longer than the provided buffer length %u", decoded_name_length_maximum);
                goto SXE_ERROR_OUT;
            }

            /* Copy the label */
            if (decoded_name != NULL) {
                memcpy((unsigned char*)(decoded_name + decoded_name_offset), dns_packet + name_offset + 1, len);
                decoded_name[decoded_name_offset + len] = '.';
            }

            decoded_name_offset += len + 1;
        }
        else if ((len & SXE_DNS_LABEL_LENGTH_POINTER) == SXE_DNS_LABEL_LENGTH_POINTER) {
            SXEL60("NAME includes a pointer");
            name_offset = (len & ~SXE_DNS_LABEL_LENGTH_POINTER) + dns_packet[name_offset + 1];
            SXEL61("New NAME offset is %u", name_offset);

            /* Prevent looping forever - a pointer should never point to a pointer
             */
            if ((dns_packet[name_offset] & SXE_DNS_LABEL_LENGTH_POINTER) != 0) {
                SXEL51("sxe_dns_decode_name(): NAME contains a pointer which points to another pointer at packet offset %u",
                       name_offset);
                goto SXE_ERROR_OUT;
            }

            continue;
        }
        else {
            SXEL51("sxe_dns_decode_name(): NAME is invalid; NAME contains an invalid length/pointer value at packet offset %u", name_offset);
            goto SXE_ERROR_OUT;
        }

        name_offset += len + 1;
    }

    SXEL60("NAME is invalid because it extends outside the packet");

SXE_ERROR_OUT:
SXE_EARLY_OUT:
    SXER81("return // result=%s", sxe_return_to_string(result));
    return result;
}
Beispiel #10
0
int
main(int argc, char ** argv)
{
    const char * line;
    unsigned     i;

    if (argc > 1) {
        test_program_arg = argv[1];
        sxe_log_hook_line_out(test_log_line_out_to_stdout);
        SXEA10(sxe_log_hook_line_out(test_log_line_out_to_stdout) == test_log_line_out_to_stdout,
               "sxe_log_hook_line_out failed to hook test_log_line_out_to_stdout");

        if (strcmp(argv[1], "1") == 0) {
            if (getenv("SXE_LOG_LEVEL") != NULL) {
                SXED80("should not see this (level too high)", strlen("should not see this (level too high)"));    /* Cover early out in dump */
            }

            SXEL40("BOO");
        }
        else if (strcmp(argv[1], "2") == 0) {
#ifndef LOCAL_SXE_DEBUG
            sxe_log_set_indent_maximum(~0U);
#endif
            sxe_log_set_level(SXE_LOG_LEVEL_WARNING);
            SXEE50("level_five()");
            test_level_six(SXE_LOG_LEVEL_LIBRARY_DUMP);
            SXER50("return // five");
            SXEE50("level_five()");
            test_level_six(SXE_LOG_LEVEL_WARNING);
            SXER50("return // five");
            SXEL20("that's all, folks");
        }

        exit(0);
    }

    test_program_name = argv[0];
    plan_tests(3 * TEST_LINES_EXPECTED + 3);

    /* Tests for different log level settings */

    tap_test_case_name("Level settings");
    ok((line = test_log_first("1")) != NULL,                        "Test log at default level wrote a line");
    diag("line = %s", line);

    SXEA12(putenv((char *)(intptr_t)"SXE_LOG_LEVEL=2") >= 0,        "%s: Failed to putenv: %s", test_program_name, strerror(errno));
    ok(test_log_first("1") == NULL,                                 "Test log with SXE_LOG_LEVEL=2 failed to write a line");

    /* TODO: Replace putenvs with calls to the TBD function that allows setting fine grained levels programmatically. */

    SXEA12(putenv((char *)(intptr_t)"SXE_LOG_LEVEL_LIBSXE=5") >= 0, "%s: Failed to putenv: %s", test_program_name, strerror(errno));
    ok((line = test_log_first("1")) != NULL,                        "Test log with SXE_LOG_LEVEL_LIBSXE=5 wrote a line");
    diag("line = %s", line);
    SXEA12(putenv((char *)(intptr_t)"SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LOG=2") >= 0, "%s: Failed to setenv: %s", test_program_name, strerror(errno));
    ok(test_log_first("1") == NULL,                                 "Test log with SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LOG=2 failed to write a line");
    SXEA12(putenv((char *)(intptr_t)"SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LOG_TEST_TEST_SXE_LOG_LEVELS=7") >= 0, "%s: Failed to putenv: %s", test_program_name, strerror(errno));
    ok((line = test_log_first("1")) != NULL,                        "Test log with SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LOG_TEST_TEST_SXE_LOG_LEVELS=7 wrote a line");
    diag("line = %s", line);

    /* Remove the more specific environment variables
     */
    SXEA12(unsetenv("SXE_LOG_LEVEL_LIBSXE") == 0,                                      "%s: unsetenv failed: %s", test_program_name, strerror(errno));
    SXEA12(unsetenv("SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LOG") == 0,                          "%s: unsetenv failed: %s", test_program_name, strerror(errno));
    SXEA12(unsetenv("SXE_LOG_LEVEL_LIBSXE_LIB_SXE_LOG_TEST_TEST_SXE_LOG_LEVELS") == 0, "%s: unsetenv failed: %s", test_program_name, strerror(errno));

    /* Tests for indentation interacting with log level */

    tap_test_case_name("Indentation");
    line = test_log_first("2");

    for (i = 0; i < TEST_LINES_EXPECTED; i++) {
        ok(line != NULL,                                            "Got line %u", 2 * i + 1);
        ok(strstr(line, test_expected[i]) != NULL,                  "Found '%s' in '%.*s'", test_expected[i], (int)strlen(line) - 1, line);

        if (i > 2) {
            ok(test_log_next() != NULL,                             "Got line %u", 2 * i + 2);
        }

        line = test_log_next();
    }

    ok(line == NULL,                                                "Got EOF");
    return exit_status();
}
Beispiel #11
0
int
main(int argc, char ** argv)
{
#ifdef WINDOWS_NT
    SXEL10("WARNING: Need to implement sxe_spawn() on Windows to run this test file!");
#else
    int           fd;
    double        start_time;
    unsigned      count;
    unsigned      id;
    unsigned    * pool;
    unsigned    * shared;
    size_t        size;
    SXE_MMAP      memmap;
    SXE_RETURN    result;
    SXE_SPAWN     spawn[TEST_CLIENT_INSTANCES];

    if (argc > 1) {
        count = atoi(argv[1]);
        sxe_mmap_open(&memmap, "memmap");
        shared  = (unsigned *)(unsigned long)SXE_MMAP_ADDR(&memmap);
        pool    = sxe_pool_from_base(shared);
        SXEL63("Instance %u mapped to shared pool // base=%p, pool=%p", count, shared, pool);
        do {
            usleep(10000 * count);
            id = sxe_pool_set_oldest_element_state_locked(pool, TEST_STATE_FREE, TEST_STATE_CLIENT_TAKE);
            SXEA10(id != SXE_POOL_LOCK_NEVER_TAKEN, "Got SXE_POOL_LOCK_NEVER_TAKEN");;
        } while (id == SXE_POOL_NO_INDEX);

        SXEL62("Instance %u got pool element %u", count, id);
        pool[id] = count;
        sxe_pool_set_indexed_element_state_locked(pool, id, TEST_STATE_CLIENT_TAKE, TEST_STATE_CLIENT_DONE);
        sxe_mmap_close(&memmap);
        SXEL61("Instance %u exiting", count);
        return 0;
    }

    plan_tests(5);
    ok((size = sxe_pool_size(TEST_CLIENT_INSTANCES/2, sizeof(*pool), TEST_STATE_NUMBER_OF_STATES)) >= TEST_CLIENT_INSTANCES * sizeof(*pool),
       "Expect pool size %u to be at least the size of the array %u", size, TEST_CLIENT_INSTANCES * sizeof(*pool));

    SXEA11((fd = open("memmap", O_CREAT | O_TRUNC | O_WRONLY, 0666)) >= 0, "Failed to create file 'memmap': %s",         strerror(errno));
    SXEA12(ftruncate(fd, size)                                       >= 0, "Failed to extend the file to %lu bytes: %s", size, strerror(errno));
    close(fd);
    sxe_mmap_open(&memmap, "memmap");
    shared = (unsigned *)(unsigned long)SXE_MMAP_ADDR(&memmap);

    pool = sxe_pool_construct(shared, "shared-pool", TEST_CLIENT_INSTANCES/2, sizeof(*pool), TEST_STATE_NUMBER_OF_STATES, SXE_POOL_LOCKS_ENABLED);

    sxe_register(TEST_CLIENT_INSTANCES + 1, 0);
    SXEA11((result = sxe_init()) == SXE_RETURN_OK,  "Failed to initialize the SXE package: %s",  sxe_return_to_string(result));

    for (count = 1; count <= TEST_CLIENT_INSTANCES; count++) {
        char buffer[12];

        snprintf(buffer, sizeof(buffer), "%u", count);
        result = sxe_spawn(NULL, &spawn[count - 1], argv[0], buffer, NULL, NULL, NULL, NULL);
        SXEA13(result == SXE_RETURN_OK, "Failed to spawn '%s %s': %s", argv[0], buffer, sxe_return_to_string(result));
    }

    start_time = sxe_get_time_in_seconds();
    for (count = 0; (count < TEST_CLIENT_INSTANCES); ) {
        SXEA10((TEST_WAIT + start_time ) > sxe_get_time_in_seconds(), "Unexpected timeout... is the hardware too slow?");
        usleep(10000);
        id = sxe_pool_set_oldest_element_state_locked(pool, TEST_STATE_CLIENT_DONE, TEST_STATE_FREE);

        /* Assert here in  the test. The actual service would take specific action here */
        SXEA12(id != SXE_POOL_LOCK_NEVER_TAKEN, "Parent: Failed to acqure lock .. yield limit reached. id %u vs %u", id, SXE_POOL_LOCK_NEVER_TAKEN);

        if (id != SXE_POOL_NO_INDEX) {
            SXEL62("Looks like instance %u got element %u", pool[id], id);
            count++;
        }
    }
    ok(count == TEST_CLIENT_INSTANCES, "All clients got an element in the pool");

    start_time = sxe_get_time_in_seconds();
    for (count = 0; (count < TEST_CLIENT_INSTANCES); count++) {
        SXEA10((TEST_WAIT + start_time ) > sxe_get_time_in_seconds(), "Unexpected timeout... is the hardware too slow?");
        waitpid(spawn[count].pid, NULL, 0);
    }

    ok(SXE_POOL_LOCK_NEVER_TAKEN != sxe_pool_lock(pool), "Forced lock to be always locked!");
    id = sxe_pool_set_oldest_element_state_locked(pool, TEST_STATE_FREE, TEST_STATE_FREE);
    ok(id == SXE_POOL_LOCK_NEVER_TAKEN,   "sxe_pool_set_oldest_element_state_locked() Failed to acquire lock");
    id = sxe_pool_set_indexed_element_state_locked(pool, 0, TEST_STATE_FREE, TEST_STATE_FREE);
    ok(id == SXE_POOL_LOCK_NEVER_TAKEN,   "sxe_pool_set_indexed_element_state_locked() Failed to acquire lock");
    sxe_pool_unlock(pool);
    sxe_pool_override_locked(pool); /* for coverage */

    sxe_mmap_close(&memmap);
    return exit_status();
#endif
}