pkernel kai clock()/malloc()/free() tailoring

Giorgos Keramidas keramida at ceid.upatras.gr
Sat Mar 9 20:16:03 EET 2013


On Sat, 9 Mar 2013 19:07:07 +0200, Christos Houtouridis <hoo2.ch.pub at gmail.com> wrote:
> Θενκς Γιώργο,
>
> Προς το παρόν στήνω την memory allocation de-allocation μηχανή
> μου. Αυτήν χρησιμοποιεί τόσο ο πυρήνας μου για να κάνει allocation
> stack για τα process, αλλά και οι 'custom' malloc, calloc, realloc και
> free για heap που κάνω export. Απλά για stack η μηχανή μου δίνει μνήμη
> από το τέλος, ενώ για heap από την "αρχή"(&pulStack). Οι μέχρι τώρα
> υλοποίηση πάντως παίζει σχετικά καλά και ο linker χρησιμοποιεί τις
> δικές μου συναρτήσεις, χωρίς να πειράξω τίποτα. Απλά δεν ξέρω αν θα
> παίξει το ίδιο όταν μετατρέψω τον πυρήνα μου από απλά αρχεία που είναι
> τώρα, σε bin μορφή, δλδ "libpkernel.a" και πρέπει να κάνω link
> ταυτόχρονα με libc και libpkernel για το κάθε firmware. Εκεί θα
> δούμε....
>
> Πάντως θα δοκιμάσω το ίδιο και για την clock() και time().
>
> Ένα κακό βλέπω μόνο. Ότι ο pkernel μεγαλώνει. Αυτό που δεν ξέρω είναι
> αν ο linker θα πετάει μέσα στο τελικό .elf όλες τις συναρτήσεις ή μόνο
> αυτές που καλούνται κάθε φορά.

Αυτό που λες με το να μην υπάρχουν καν τα unused symbols συνήθως το λένε
'dead symbol elimination'.  Για statically linked binaries είναι σχετικά
εύκολο για τον compiler και linker να βρουν αν ένα symbol χρησιμοποιείται
κάπου, και με τα ανάλογα link-time options να μην το συμπεριλάβουν καν στο
τελικό binary.  Για shared libraries όμως δεν είναι τόσο προφανές αν ένα
symbol χρησιμοποιείται.

Π.χ. σκέψου πώς θα μπορούσε ο linker να ξέρει αν καλείται ποτέ ή όχι ένα
function το οποίο έχει μόνο ένα reference, σε ένα static array από function
pointers:

    int
    add(int x, int y)
    {
        return x + y;
    }

    int
    subtract(int x, int y)
    {
        return x - y;
    }

    int
    mul(int x, int y)
    {
        return x * y;
    }

    int
    div(int x, int y)
    {
        return x * y;
    }

    int intops[] = {
        add, sub, mul, div
    };
    size_t intops_size = sizeof(intops) / sizeof(intops[0]);

Κι έστω ότι ο κώδικας που χρησιμοποιεί το intops έχει ένα off-by-one error,
και τελικά δε χρησιμοποιεί ποτέ την div() function:

    int a = 1, b = 2;
    int results = malloc(sizeof(int) * intops_size);
    int k;

    for (k = 0; k < intops_size - 1; k++) {
        results = intops[k](a, b);
    }

Για να καταλάβει ο compiler ότι όντως ΔΕΝ θα κληθεί ποτέ η div() πρέπει να
κάνει κάτι μαγικό.  Να βρει το off-by-one bug εντελώς αυτόματα!

Τώρα... Υπό συνθήκες ίσως _μπορεί_ να γίνει κάτι...

Π.χ. για statically linked binaries *μπορείς* πάντως να χρησιμοποιήσεις τα
εξής options:

    compile-time =>    -fdata-sections -ffunction-sections
    link-time    =>    -Wl,--gc-sections

Νομίζω ότι ταυτόνχρονα πρέπει να χρησιμοποιήσεις και το -Os option, για να
κάνει optimization-for-size ο compiler, αλλά δεν είμαι σίγουρος.  Πρέπει να
το δοκιμάσω πρώτα για να σου πω στάνταρ.



More information about the Linux-greek-users mailing list