Skip to content
Snippets Groups Projects
Forked from Glasgow Haskell Compiler / GHC
5133 commits behind the upstream repository.
  • Cheng Shao's avatar
    a9979f55
    testsuite: fix testwsdeque with recent clang · a9979f55
    Cheng Shao authored and Marge Bot's avatar Marge Bot committed
    This patch fixes compilation of testwsdeque.c with recent versions of
    clang, which will fail with the error below:
    
    ```
    testwsdeque.c:95:33: error:
         warning: format specifies type 'long' but the argument has type 'void *' [-Wformat]
           95 |         barf("FAIL: %ld %d %d", p, n, val);
              |                     ~~~         ^
    
    testwsdeque.c:95:39: error:
         warning: format specifies type 'int' but the argument has type 'StgWord' (aka 'unsigned long') [-Wformat]
           95 |         barf("FAIL: %ld %d %d", p, n, val);
              |                            ~~         ^~~
              |                            %lu
    
    testwsdeque.c:133:42: error:
         error: incompatible function pointer types passing 'void (void *)' to parameter of type 'OSThreadProc *' (aka 'void *(*)(void *)') [-Wincompatible-function-pointer-types]
          133 |         createOSThread(&ids[n], "thief", thief, (void*)(StgWord)n);
              |                                          ^~~~~
    
    /workspace/ghc/_build/stage1/lib/../lib/x86_64-linux-ghc-9.11.20240502/rts-1.0.2/include/rts/OSThreads.h:193:51: error:
         note: passing argument to parameter 'startProc' here
          193 |                                     OSThreadProc *startProc, void *param);
              |                                                   ^
    
    2 warnings and 1 error generated.
    ```
    a9979f55
    History
    testsuite: fix testwsdeque with recent clang
    Cheng Shao authored and Marge Bot's avatar Marge Bot committed
    This patch fixes compilation of testwsdeque.c with recent versions of
    clang, which will fail with the error below:
    
    ```
    testwsdeque.c:95:33: error:
         warning: format specifies type 'long' but the argument has type 'void *' [-Wformat]
           95 |         barf("FAIL: %ld %d %d", p, n, val);
              |                     ~~~         ^
    
    testwsdeque.c:95:39: error:
         warning: format specifies type 'int' but the argument has type 'StgWord' (aka 'unsigned long') [-Wformat]
           95 |         barf("FAIL: %ld %d %d", p, n, val);
              |                            ~~         ^~~
              |                            %lu
    
    testwsdeque.c:133:42: error:
         error: incompatible function pointer types passing 'void (void *)' to parameter of type 'OSThreadProc *' (aka 'void *(*)(void *)') [-Wincompatible-function-pointer-types]
          133 |         createOSThread(&ids[n], "thief", thief, (void*)(StgWord)n);
              |                                          ^~~~~
    
    /workspace/ghc/_build/stage1/lib/../lib/x86_64-linux-ghc-9.11.20240502/rts-1.0.2/include/rts/OSThreads.h:193:51: error:
         note: passing argument to parameter 'startProc' here
          193 |                                     OSThreadProc *startProc, void *param);
              |                                                   ^
    
    2 warnings and 1 error generated.
    ```
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
testwsdeque.c 2.97 KiB
#define THREADED_RTS

#include "Rts.h"
#include "WSDeque.h"
#include <stdio.h>

#define SCRATCH_SIZE (1024*1024)
#define THREADS 3
#define POP 2

WSDeque *q;

StgWord scratch[SCRATCH_SIZE];
StgWord done;

OSThreadId ids[THREADS];

// -----------------------------------------------------------------------------
// version of stealWSDeque() that logs its actions, for debugging

#if defined(DEBUG)

#define BUF 128

int bufs[THREADS];

StgWord last_b[THREADS][BUF];
StgWord last_t[THREADS][BUF];
StgWord last_v[THREADS][BUF];

#define CASTOP(addr,old,new) ((old) == cas(((StgPtr)addr),(old),(new)))

void *
myStealWSDeque_ (WSDeque *q, uint32_t n)
{
    void * stolen;

// Can't do this on someone else's spark pool:
// ASSERT_WSDEQUE_INVARIANTS(q);

    // NB. these loads must be ordered, otherwise there is a race
    // between steal and pop.
    StgWord t = ACQUIRE_LOAD(&q->top);
    SEQ_CST_FENCE();
    StgWord b = ACQUIRE_LOAD(&q->bottom);

    void *result = NULL;
    if (t < b) {
        /* Non-empty queue */
        result = RELAXED_LOAD(&q->elements[t % q->size]);
        if (!cas_top(q, t, t+1)) {
            return NULL;
        }
    }
    return result;
}

void *
myStealWSDeque (WSDeque *q, uint32_t n)
{
    void *stolen;

    do {
        stolen = myStealWSDeque_(q,n);
    } while (stolen == NULL && !looksEmptyWSDeque(q));

    return stolen;
}

void dump(void)
{
    uint32_t n;
    uint32_t i;
    for (n = 0; n < THREADS; n++) {
        debugBelch("\nthread %d:\n", n);
        for (i = bufs[n]; i >= stg_max(bufs[n]-20,0); i--) {
            debugBelch("%d: t=%ld b=%ld = %ld\n", i, last_t[n][i], last_b[n][i], last_v[n][i]);
        }
    }
}

#endif // DEBUG

// -----------------------------------------------------------------------------

void work(void *p, uint32_t n)
{
    StgWord val;

    // debugBelch("work %ld %d\n", p, n);
    val = *(StgWord *)p;
    if (val != 0) {
        fflush(stdout);
        fflush(stderr);
        barf("FAIL: %p %" FMT_Word32 " %" FMT_Word, p, n, val);
    }
    *(StgWord*)p = n+10;
}

void* OSThreadProcAttr thief(void *info)
{
    void *p;
    StgWord n;
    uint32_t count = 0;

    n = (StgWord)info;

    while (!done) {
#if defined(DEBUG)
        p = myStealWSDeque(q,n);
#else
        p = stealWSDeque(q);
#endif
        if (p != NULL) { work(p,n+1); count++; }
    }
    debugBelch("thread %ld finished, stole %d", n, count);
    return NULL;
}

int main(int argc, char*argv[])
{
    int n;
    uint32_t count = 0;
    void *p;

    q = newWSDeque(1024);
    done = 0;

    for (n=0; n < SCRATCH_SIZE; n++) {
        scratch[n] = 0;
    }

    for (n=0; n < THREADS; n++) {
        createOSThread(&ids[n], "thief", (OSThreadProc*)thief, (void*)(StgWord)n);
    }

    for (n=0; n < SCRATCH_SIZE; n++) {
        if (n % POP) {
            p = popWSDeque(q);
            if (p != NULL) { work(p,0); count++; }
        }
        pushWSDeque(q,&scratch[n]);
    }

#if defined(DEBUG)
    debugBelch("main thread finished, popped %d", count);
#endif
    exit(0);
}