Coder Social home page Coder Social logo

gyrovorbis / libgimbal Goto Github PK

View Code? Open in Web Editor NEW
73.0 9.0 4.0 3.46 MB

C17-based extended standard library, cross-language type system, and unit testing framework targeting Sega Dreamcast, Sony PSP and PSVita, Windows, Mac, Linux, Android, iOS, and WebAssembly.

Home Page: http://libgimbal.elysianshadows.com

License: MIT License

CMake 1.03% C 92.27% C++ 6.69%
algorithms allocators c containers core dreamcast object-oriented-c type-system unit-testing utility-library

libgimbal's People

Contributors

aaronglazer avatar cykoder avatar gyrovorbis avatar michael-santiago-tfs avatar suicvne avatar theamazingarce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libgimbal's Issues

Add signals for catching failed GblTestScenarios and GblTestSuites

Thanks to @suicvne for raising this issue:

It is often desirable for the user to be able to capture or filter over all of the failing test cases when executing a series of GblTestSuites from a GblTestScenario. You can currently do this by:

  1. Overriding GblTestSuiteClass::pFnCaseRun() to capture the result code.
  2. Iterating over the test suites within a test scenario and logging the failing issue:
for(int i = 0; i < GblObject_childCount(GBL_OBJECT(pScenario)); ++i) {
    GblTestSuite* pSuite = GblObject_findChildByIndex(GBL_OBJECT(pScenario), i);
    if(pSuite->casesFailed) {
        printf("%s has reested with code %s at %s:%s:%zu\n",
               GblObject_name(GBL_OBJECT(pSuite)), gblResultString(pSuite->failingIssue.result),
               pSuite->failingIssue.sourceLocation.pFile, pSuite->failingIssue.sourceLocation.pFunc,
               pSuite->failingIssue.sourceLocation.line);
    }
}

Unfortuantely there are a few shortcomings:

  1. There is no way to retrieve the name of or function pointer to the exact test case that failed.
  2. This would be SO MUCH MORE PRISTINE from an API perspective using the signal/slots mechanism to emit a signal when a test case fails.

UUIDs are not actually 128-bits of randomness

Problem

In gimbal_uuid.c, UUIDs are generated with the following:

// Implemented per RFC4122 section 4.4
GBL_EXPORT GBL_RESULT GblUuid_initV4(GblUuid* pSelf) {
    GBL_CTX_BEGIN(NULL);
    GBL_CTX_VERIFY_POINTER(pSelf);

    // First initialize all bytes to random/psuedo-random numbers
    for(unsigned b = 0; b < GBL_UUID_BYTE_COUNT; ++b) {
        pSelf->bytes[b] = gblRandRange(0, 255);
    }

where gblRandRange(0,255) resolves to

GBL_EXPORT int gblRandRange(int min, int max)  {
    GBL_ASSERT(max <= RAND_MAX);
    static GblBool seeded = GBL_FALSE;
    if(!seeded) GBL_UNLIKELY {
        srand((unsigned)gblSeed(0));
        seeded = GBL_TRUE;
    }
    return (rand() % (max - min + 1)) + min;
}

The C standard library rand() will typically only have a $2^{32} -1$ long period before it begins repeating for any given seed.
The issue arises, because generating multiple random numbers, and concatenating them, does not increase randomness. Since a PRNG's output is determinate, for any given seed, every next value is determinate.

Also, there is no reseeding after it is initially seeded.

In the following program I wrote which basically implements the same behavior

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdint.h>

#define SIZE 16

int main(void)
{
    srand(time(NULL));
    
    uint8_t reference[SIZE] = {0};
    uint8_t current[SIZE] = {0};
    
    printf("Reference: ");
    for(int i = 0; i < SIZE; i++)
    {
        reference[i] = (uint8_t)(rand() % 256);
        printf("%02X ", reference[i]);
    }
    printf("\nFinding duplicates...\n");
    
    clock_t start = clock();

    for(uint64_t i = 1; i < UINT64_MAX; i++)
    {
        for(int j = 0; j < SIZE; j++)
            current[j] = (uint8_t)(rand() % 256);
        
        
        if(!memcmp(reference, current, SIZE))
        {
            printf("Duplicate found after %llu generations\n", i);
            printf("Duplicate: ");
            for(int k = 0; k < SIZE; k++) printf("%02X ", current[k]);
            printf("\n");
            break;
        }
    }
    
    clock_t end = clock();
    float sec = (float)(end-start) / CLOCKS_PER_SEC;
    
    printf("CPU time: %.3f seconds.\n", sec);
    
    return 0;
}

Gives the following output

Reference: 51 82 D7 92 DF 69 AB B6 D1 B4 A1 8E 60 0E C8 B9
Finding duplicates...
Duplicate found after 1048576 generations
Duplicate: 51 82 D7 92 DF 69 AB B6 D1 B4 A1 8E 60 0E C8 B9
CPU time: 0.157 seconds.

Solution

To generate proper UUIDs with all the necessary bits of randomness, implementing a 128-bit PRNG yourself will likely be the best option. An LFSR or an LCG are commonly used in PRNGs.

In addition, you could also find out a scheme for reseeding your RNG in-between number generations, that could help too.

[Bug] Unaligned GblTestFixture/GblPrivateData

Found an issue with unaligned memory access on Dreamcast for the unit tests.

When creating a test fixture with:

GBL_TEST_FIXTURE {
    char dummy;
};

The Dreamcast will shit itself upon creation of the GblTestFixture instance spewing out event code 0x100 which Falco tracked down to represent an "unaligned memory write".

The output from dc-tool-ip:

KallistiOS Git revision 34f7e943-dirty:
  Fri May 31 23:59:48 EDT 2024
  [email protected]:/opt/toolchains/dc/kos
  sh-elf-gcc (GCC) 14.1.0
thd: pre-emption enabled, HZ=100
maple: active drivers:
    Dreameye (Camera): Camera
    Sound Input Peripheral: Microphone
    PuruPuru (Vibration) Pack: JumpPack
    VMU Driver: Clock, LCD, MemoryCard
    Mouse Driver: Mouse
    Keyboard Driver: Keyboard
    Controller Driver: Controller
    Lightgun: LightGun
  DMA Buffer at ac4509e0
vid_set_mode: 640x480 VGA with 1 framebuffers.
dc-load console support enabled
maple: attached devices:
  A0: Dreamcast Controller          (01000000: Controller)

* =========== Cascade Information ===========
*   Version:      0.3.0
*   Git Hash:     
* =========== Cascade Information ===========
* pScenario: 0x8c469144
* Enqueue Central Dispatch Test
* Enqueue Logging Test
Unhandled exception: PC 8c2296b0, code 1, evt 0100
 R0-R7: 00000001 00000000 8cfff8dc 0000003f 00000000 00000000 00000001 00000000
 R8-R15: 8cfff860 8c471398 8c471300 8c47141d 8cfff91c 00000000 8cfff954 8cfff854
 SR 40000000 PR 8c22980c
-------- Stack Trace (innermost first) ---------
   8cfff95c
   (invalid frame pointer)
-------------- End Stack Trace -----------------
kernel panic: unhandled IRQ/Exception
arch: aborting the system

Fix on my code was to do this:

GBL_TEST_FIXTURE {
    char dummy[4];
};

We tracked down where in the code the problem was happening and found code was able to proceed further once this was fixed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.