[Issue 1091] New: Wrong size reserved for critical sections

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Apr 2 16:49:44 PDT 2007


http://d.puremagic.com/issues/show_bug.cgi?id=1091

           Summary: Wrong size reserved for critical sections
           Product: D
           Version: 1.010
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla at digitalmars.com
        ReportedBy: fvbommel at wxs.nl


It looks like DMD on Linux only reserves 4 bytes for a critical section used to
implement a synchronized {} block, while it should be at least 28 bytes.
(A pointer to this is passed to _d_criticalenter, which takes a pointer to the
following (C) struct:
---
// from phobos/internal/critical.c
typedef struct D_CRITICAL_SECTION

{

    struct D_CRITICAL_SECTION *next;

    pthread_mutex_t cs;

} D_CRITICAL_SECTION;
---
According to my (32-bit) GCC the entire structure totals 28 bytes)

This manifests itself in the following (synthetic) code:
---
import std.stdio;

void main()
{
        synchronized {
                synchronized {
                        writefln("Hello world!");
                }
        }
}
---
The critical sections in the .data section are 4 bytes apart, yet should be 28
bytes large. Overlapping is _bad_.
This code hangs when ran on my computer, but it's probably subject to the whim
of the pthreads implementation...
(Note: this is obviously useless code, I constructed it after figuring out what
the problem was)

AFAICT above D code should have been roughly equivalent to the following C code
(linked to Phobos):
---
#include <stdio.h>
#include <pthread.h>
#include <string.h>

// from phobos/internal/critical.c
typedef struct D_CRITICAL_SECTION
{
    struct D_CRITICAL_SECTION *next;
    pthread_mutex_t cs;
} D_CRITICAL_SECTION;

D_CRITICAL_SECTION c1, c2;

int main() {
        // not sure if this is necessary, but the space DMD
        // reserves is also zeroed, so...
        memset(&c1, 0, sizeof(D_CRITICAL_SECTION));
        memset(&c2, 0, sizeof(D_CRITICAL_SECTION));

        _d_criticalenter(&c1);
        _d_criticalenter(&c2);
        printf("Hello world!\n");
        _d_criticalexit(&c2);
        _d_criticalexit(&c1);

        return 0;
}
---
Which runs just fine.


(I used keyword "wrong-code" because "wrong-data" wasn't on the list ;) )


-- 



More information about the Digitalmars-d-bugs mailing list