Changeset df29f24 in mainline for uspace


Ignore:
Timestamp:
2011-06-01T09:04:08Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0a7627b, c9f0975
Parents:
e51a514 (diff), 5d1b3aa (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

Conflicts - trivial to solve
In kernel/generic/src/mm/page.c - sys_page_find_mapping does
not use locking when accessing page tables (hope that is correct).

Location:
uspace
Files:
8 added
24 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    re51a514 rdf29f24  
    9494        drv/rootvirt \
    9595        drv/test1 \
    96         drv/test2
     96        drv/test2 \
     97        drv/test3
    9798
    9899## Networking
  • uspace/app/tester/Makefile

    re51a514 rdf29f24  
    4848        ipc/ping_pong.c \
    4949        loop/loop1.c \
     50        mm/common.c \
    5051        mm/malloc1.c \
    5152        mm/malloc2.c \
    5253        mm/mapping1.c \
     54        mm/malloc3.c \
    5355        devs/devman1.c \
     56        devs/devman2.c \
    5457        hw/misc/virtchar1.c \
    5558        hw/serial/serial1.c
  • uspace/app/tester/devs/devman2.c

    re51a514 rdf29f24  
    11/*
    2  * Copyright (c) 2009 Martin Decky
     2 * Copyright (c) 2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 #include <test.h>
     29/** @addtogroup tester
     30 * @brief Test devman service.
     31 * @{
     32 */
     33/**
     34 * @file
     35 */
    3036
    31 const char *test_sse1(void)
     37#include <inttypes.h>
     38#include <errno.h>
     39#include <str_error.h>
     40#include <sys/types.h>
     41#include <async.h>
     42#include <devman.h>
     43#include <str.h>
     44#include <vfs/vfs.h>
     45#include <sys/stat.h>
     46#include <fcntl.h>
     47#include "../tester.h"
     48
     49#define DEVICE_CLASS "test3"
     50
     51const char *test_devman2(void)
    3252{
    33         return NULL;
     53        size_t idx = 1;
     54        int rc = EOK;
     55        const char *err_msg = NULL;
     56        char *path = NULL;
     57        while (rc == EOK) {
     58                rc = asprintf(&path, "/dev/class/%s\\%zu", DEVICE_CLASS, idx);
     59                if (rc < 0) {
     60                        continue;
     61                }
     62                int fd = open(path, O_RDONLY);
     63                if (fd < 0) {
     64                        TPRINTF("Failed opening `%s': %s.\n",
     65                            path, str_error(fd));
     66                        rc = fd;
     67                        err_msg = "Failed opening file";
     68                        continue;
     69                }
     70                int phone = fd_phone(fd);
     71                close(fd);
     72                if (phone < 0) {
     73                        TPRINTF("Failed opening phone: %s.\n", str_error(phone));
     74                        rc = phone;
     75                        err_msg = "Failed opening file descriptor phone";
     76                        continue;
     77                }
     78                async_hangup(phone);
     79                TPRINTF("Path `%s' okay.\n", path);
     80                free(path);
     81                idx++;
     82                rc = EOK;
     83        }
     84       
     85        if (path != NULL) {
     86                free(path);
     87        }
     88
     89        return err_msg;
    3490}
     91
     92/** @}
     93 */
  • uspace/app/tester/mm/malloc1.c

    re51a514 rdf29f24  
    3030
    3131#include <stdio.h>
    32 #include <unistd.h>
    3332#include <stdlib.h>
    34 #include <malloc.h>
     33#include "common.h"
    3534#include "../tester.h"
    3635
     
    4544 */
    4645
    47 /**
    48  * sizeof_array
    49  * @array array to determine the size of
    50  *
    51  * Returns the size of @array in array elements.
    52  */
    53 #define sizeof_array(array) \
    54         (sizeof(array) / sizeof((array)[0]))
    55 
    56 #define MAX_ALLOC (16 * 1024 * 1024)
    57 
    58 /*
    59  * Subphase control structures: subphase termination conditions,
    60  * probabilities of individual actions, subphase control structure.
    61  */
    62 
    63 typedef struct {
    64         unsigned int max_cycles;
    65         unsigned int no_memory;
    66         unsigned int no_allocated;
    67 } sp_term_cond_s;
    68 
    69 typedef struct {
    70         unsigned int alloc;
    71         unsigned int free;
    72 } sp_action_prob_s;
    73 
    74 typedef struct {
    75         const char *name;
    76         sp_term_cond_s cond;
    77         sp_action_prob_s prob;
    78 } subphase_s;
    79 
    80 
    81 /*
    82  * Phase control structures: The minimum and maximum block size that
    83  * can be allocated during the phase execution, phase control structure.
    84  */
    85 
    86 typedef struct {
    87         size_t min_block_size;
    88         size_t max_block_size;
    89 } ph_alloc_size_s;
    90 
    91 typedef struct {
    92         const char *name;
    93         ph_alloc_size_s alloc;
    94         subphase_s *subphases;
    95 } phase_s;
    96 
    97 
    9846/*
    9947 * Subphases are defined separately here. This is for two reasons:
     
    10149 * how many subphases a phase contains.
    10250 */
    103 static subphase_s subphases_32B[] = {
     51static subphase_t subphases_32B[] = {
    10452        {
    10553                .name = "Allocation",
     
    14088};
    14189
    142 static subphase_s subphases_128K[] = {
     90static subphase_t subphases_128K[] = {
    14391        {
    14492                .name = "Allocation",
     
    179127};
    180128
    181 static subphase_s subphases_default[] = {
     129static subphase_t subphases_default[] = {
    182130        {
    183131                .name = "Allocation",
     
    217165        }
    218166};
    219 
    220167
    221168/*
    222169 * Phase definitions.
    223170 */
    224 static phase_s phases[] = {
     171static phase_t phases[] = {
    225172        {
    226173                .name = "32 B memory blocks",
     
    257204};
    258205
    259 
    260 /*
    261  * Global error flag. The flag is set if an error
    262  * is encountered (overlapping blocks, inconsistent
    263  * block data, etc.)
    264  */
    265 static bool error_flag = false;
    266 
    267 /*
    268  * Memory accounting: the amount of allocated memory and the
    269  * number and list of allocated blocks.
    270  */
    271 static size_t mem_allocated;
    272 static size_t mem_blocks_count;
    273 
    274 static LIST_INITIALIZE(mem_blocks);
    275 
    276 typedef struct {
    277         /* Address of the start of the block */
    278         void *addr;
    279        
    280         /* Size of the memory block */
    281         size_t size;
    282        
    283         /* link to other blocks */
    284         link_t link;
    285 } mem_block_s;
    286 
    287 typedef mem_block_s *mem_block_t;
    288 
    289 
    290 /** init_mem
    291  *
    292  * Initializes the memory accounting structures.
    293  *
    294  */
    295 static void init_mem(void)
     206static void do_subphase(phase_t *phase, subphase_t *subphase)
    296207{
    297         mem_allocated = 0;
    298         mem_blocks_count = 0;
    299 }
    300 
    301 
    302 static bool overlap_match(link_t *entry, void *addr, size_t size)
    303 {
    304         mem_block_t mblk = list_get_instance(entry, mem_block_s, link);
    305        
    306         /* Entry block control structure <mbeg, mend) */
    307         uint8_t *mbeg = (uint8_t *) mblk;
    308         uint8_t *mend = (uint8_t *) mblk + sizeof(mem_block_s);
    309        
    310         /* Entry block memory <bbeg, bend) */
    311         uint8_t *bbeg = (uint8_t *) mblk->addr;
    312         uint8_t *bend = (uint8_t *) mblk->addr + mblk->size;
    313        
    314         /* Data block <dbeg, dend) */
    315         uint8_t *dbeg = (uint8_t *) addr;
    316         uint8_t *dend = (uint8_t *) addr + size;
    317        
    318         /* Check for overlaps */
    319         if (((mbeg >= dbeg) && (mbeg < dend)) ||
    320                 ((mend > dbeg) && (mend <= dend)) ||
    321                 ((bbeg >= dbeg) && (bbeg < dend)) ||
    322                 ((bend > dbeg) && (bend <= dend)))
    323                 return true;
    324        
    325         return false;
    326 }
    327 
    328 
    329 /** test_overlap
    330  *
    331  * Test whether a block starting at @addr overlaps with another, previously
    332  * allocated memory block or its control structure.
    333  *
    334  * @param addr Initial address of the block
    335  * @param size Size of the block
    336  *
    337  * @return false if the block does not overlap.
    338  *
    339  */
    340 static int test_overlap(void *addr, size_t size)
    341 {
    342         link_t *entry;
    343         bool fnd = false;
    344        
    345         for (entry = mem_blocks.next; entry != &mem_blocks; entry = entry->next) {
    346                 if (overlap_match(entry, addr, size)) {
    347                         fnd = true;
    348                         break;
    349                 }
    350         }
    351        
    352         return fnd;
    353 }
    354 
    355 
    356 /** checked_malloc
    357  *
    358  * Allocate @size bytes of memory and check whether the chunk comes
    359  * from the non-mapped memory region and whether the chunk overlaps
    360  * with other, previously allocated, chunks.
    361  *
    362  * @param size Amount of memory to allocate
    363  *
    364  * @return NULL if the allocation failed. Sets the global error_flag to
    365  *         true if the allocation succeeded but is illegal.
    366  *
    367  */
    368 static void *checked_malloc(size_t size)
    369 {
    370         void *data;
    371        
    372         /* Allocate the chunk of memory */
    373         data = malloc(size);
    374         if (data == NULL)
    375                 return NULL;
    376        
    377         /* Check for overlaps with other chunks */
    378         if (test_overlap(data, size)) {
    379                 TPRINTF("\nError: Allocated block overlaps with another "
    380                         "previously allocated block.\n");
    381                 error_flag = true;
    382         }
    383        
    384         return data;
    385 }
    386 
    387 
    388 /** alloc_block
    389  *
    390  * Allocate a block of memory of @size bytes and add record about it into
    391  * the mem_blocks list. Return a pointer to the block holder structure or
    392  * NULL if the allocation failed.
    393  *
    394  * If the allocation is illegal (e.g. the memory does not come from the
    395  * right region or some of the allocated blocks overlap with others),
    396  * set the global error_flag.
    397  *
    398  * @param size Size of the memory block
    399  *
    400  */
    401 static mem_block_t alloc_block(size_t size)
    402 {
    403         /* Check for allocation limit */
    404         if (mem_allocated >= MAX_ALLOC)
    405                 return NULL;
    406        
    407         /* Allocate the block holder */
    408         mem_block_t block = (mem_block_t) checked_malloc(sizeof(mem_block_s));
    409         if (block == NULL)
    410                 return NULL;
    411        
    412         link_initialize(&block->link);
    413        
    414         /* Allocate the block memory */
    415         block->addr = checked_malloc(size);
    416         if (block->addr == NULL) {
    417                 free(block);
    418                 return NULL;
    419         }
    420        
    421         block->size = size;
    422        
    423         /* Register the allocated block */
    424         list_append(&block->link, &mem_blocks);
    425         mem_allocated += size + sizeof(mem_block_s);
    426         mem_blocks_count++;
    427        
    428         return block;
    429 }
    430 
    431 
    432 /** free_block
    433  *
    434  * Free the block of memory and the block control structure allocated by
    435  * alloc_block. Set the global error_flag if an error occurs.
    436  *
    437  * @param block Block control structure
    438  *
    439  */
    440 static void free_block(mem_block_t block)
    441 {
    442         /* Unregister the block */
    443         list_remove(&block->link);
    444         mem_allocated -= block->size + sizeof(mem_block_s);
    445         mem_blocks_count--;
    446        
    447         /* Free the memory */
    448         free(block->addr);
    449         free(block);
    450 }
    451 
    452 
    453 /** expected_value
    454  *
    455  * Compute the expected value of a byte located at @pos in memory
    456  * block described by @blk.
    457  *
    458  * @param blk Memory block control structure
    459  * @param pos Position in the memory block data area
    460  *
    461  */
    462 static inline uint8_t expected_value(mem_block_t blk, uint8_t *pos)
    463 {
    464         return ((unsigned long) blk ^ (unsigned long) pos) & 0xff;
    465 }
    466 
    467 
    468 /** fill_block
    469  *
    470  * Fill the memory block controlled by @blk with data.
    471  *
    472  * @param blk Memory block control structure
    473  *
    474  */
    475 static void fill_block(mem_block_t blk)
    476 {
    477         uint8_t *pos;
    478         uint8_t *end;
    479        
    480         for (pos = blk->addr, end = pos + blk->size; pos < end; pos++)
    481                 *pos = expected_value(blk, pos);
    482 }
    483 
    484 
    485 /** check_block
    486  *
    487  * Check whether the block @blk contains the data it was filled with.
    488  * Set global error_flag if an error occurs.
    489  *
    490  * @param blk Memory block control structure
    491  *
    492  */
    493 static void check_block(mem_block_t blk)
    494 {
    495         uint8_t *pos;
    496         uint8_t *end;
    497        
    498         for (pos = blk->addr, end = pos + blk->size; pos < end; pos++) {
    499                 if (*pos != expected_value (blk, pos)) {
    500                         TPRINTF("\nError: Corrupted content of a data block.\n");
    501                         error_flag = true;
    502                         return;
    503                 }
    504         }
    505 }
    506 
    507 
    508 static link_t *list_get_nth(link_t *list, unsigned int i)
    509 {
    510         unsigned int cnt = 0;
    511         link_t *entry;
    512        
    513         for (entry = list->next; entry != list; entry = entry->next) {
    514                 if (cnt == i)
    515                         return entry;
    516                
    517                 cnt++;
    518         }
    519        
    520         return NULL;
    521 }
    522 
    523 
    524 /** get_random_block
    525  *
    526  * Select a random memory block from the list of allocated blocks.
    527  *
    528  * @return Block control structure or NULL if the list is empty.
    529  *
    530  */
    531 static mem_block_t get_random_block(void)
    532 {
    533         if (mem_blocks_count == 0)
    534                 return NULL;
    535        
    536         unsigned int blkidx = rand() % mem_blocks_count;
    537         link_t *entry = list_get_nth(&mem_blocks, blkidx);
    538        
    539         if (entry == NULL) {
    540                 TPRINTF("\nError: Corrupted list of allocated memory blocks.\n");
    541                 error_flag = true;
    542         }
    543        
    544         return list_get_instance(entry, mem_block_s, link);
    545 }
    546 
    547 
    548 #define RETURN_IF_ERROR \
    549 { \
    550         if (error_flag) \
    551                 return; \
    552 }
    553 
    554 
    555 static void do_subphase(phase_s *phase, subphase_s *subphase)
    556 {
    557         unsigned int cycles;
    558         for (cycles = 0; /* always */; cycles++) {
    559                
    560                 if (subphase->cond.max_cycles &&
    561                         cycles >= subphase->cond.max_cycles) {
     208        for (unsigned int cycles = 0; /* always */; cycles++) {
     209               
     210                if ((subphase->cond.max_cycles) &&
     211                    (cycles >= subphase->cond.max_cycles)) {
    562212                        /*
    563213                         * We have performed the required number of
     
    572222                unsigned int rnd = rand() % 100;
    573223                if (rnd < subphase->prob.alloc) {
    574                         /* Compute a random number lying in interval <min_block_size, max_block_size> */
     224                        /*
     225                         * Compute a random number lying in interval
     226                         * <min_block_size, max_block_size>
     227                         */
    575228                        int alloc = phase->alloc.min_block_size +
    576229                            (rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
    577230                       
    578                         mem_block_t blk = alloc_block(alloc);
     231                        mem_block_t *blk = alloc_block(alloc);
    579232                        RETURN_IF_ERROR;
    580233                       
     
    585238                                        break;
    586239                                }
    587                                
    588240                        } else {
    589241                                TPRINTF("A");
    590242                                fill_block(blk);
     243                                RETURN_IF_ERROR;
    591244                        }
    592245                       
    593246                } else if (rnd < subphase->prob.free) {
    594                         mem_block_t blk = get_random_block();
     247                        mem_block_t *blk = get_random_block();
    595248                        if (blk == NULL) {
    596249                                TPRINTF("F(R)");
     
    599252                                        break;
    600253                                }
    601                                
    602254                        } else {
    603255                                TPRINTF("R");
     
    614266}
    615267
    616 
    617 static void do_phase(phase_s *phase)
     268static void do_phase(phase_t *phase)
    618269{
    619         unsigned int subno;
    620        
    621         for (subno = 0; subno < 3; subno++) {
    622                 subphase_s *subphase = & phase->subphases [subno];
     270        for (unsigned int subno = 0; subno < 3; subno++) {
     271                subphase_t *subphase = &phase->subphases[subno];
    623272               
    624273                TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name);
     
    632281        init_mem();
    633282       
    634         unsigned int phaseno;
    635         for (phaseno = 0; phaseno < sizeof_array(phases); phaseno++) {
    636                 phase_s *phase = &phases[phaseno];
     283        for (unsigned int phaseno = 0; phaseno < sizeof_array(phases);
     284            phaseno++) {
     285                phase_t *phase = &phases[phaseno];
    637286               
    638287                TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
     
    645294        }
    646295       
     296        TPRINTF("Cleaning up.\n");
     297        done_mem();
    647298        if (error_flag)
    648299                return "Test failed";
  • uspace/app/tester/tester.c

    re51a514 rdf29f24  
    6363#include "mm/malloc1.def"
    6464#include "mm/malloc2.def"
     65#include "mm/malloc3.def"
    6566#include "mm/mapping1.def"
    6667#include "hw/serial/serial1.def"
    6768#include "hw/misc/virtchar1.def"
    6869#include "devs/devman1.def"
     70#include "devs/devman2.def"
    6971        {NULL, NULL, NULL, false}
    7072};
  • uspace/app/tester/tester.h

    re51a514 rdf29f24  
    3838#include <sys/types.h>
    3939#include <bool.h>
     40#include <stacktrace.h>
    4041
    4142#define IPC_TEST_SERVICE  10240
     
    4647extern char **test_argv;
    4748
     49/**
     50 * sizeof_array
     51 * @array array to determine the size of
     52 *
     53 * Returns the size of @array in array elements.
     54 */
     55#define sizeof_array(array) \
     56        (sizeof(array) / sizeof((array)[0]))
     57
    4858#define TPRINTF(format, ...) \
    49         { \
     59        do { \
    5060                if (!test_quiet) { \
    51                         fprintf(stderr, format, ##__VA_ARGS__); \
     61                        fprintf(stderr, (format), ##__VA_ARGS__); \
    5262                } \
    53         }
     63        } while (0)
     64
     65#define TSTACKTRACE() \
     66        do { \
     67                if (!test_quiet) { \
     68                        stacktrace_print(); \
     69                } \
     70        } while (0)
    5471
    5572typedef const char *(*test_entry_t)(void);
     
    7996extern const char *test_malloc1(void);
    8097extern const char *test_malloc2(void);
     98extern const char *test_malloc3(void);
    8199extern const char *test_mapping1(void);
    82100extern const char *test_serial1(void);
    83101extern const char *test_virtchar1(void);
    84102extern const char *test_devman1(void);
     103extern const char *test_devman2(void);
    85104
    86105extern test_t tests[];
  • uspace/drv/rootvirt/devices.def

    re51a514 rdf29f24  
    2121        .match_id = "virtual&test1"
    2222},
     23{
     24        .name = "test3",
     25        .match_id = "virtual&test3"
     26},
    2327#endif
    2428#ifdef CONFIG_RUN_VIRTUAL_USB_HC
  • uspace/lib/c/arch/ppc32/_link.ld.in

    re51a514 rdf29f24  
    1010#endif
    1111        data PT_LOAD FLAGS(6);
     12        debug PT_NOTE;
    1213}
    1314
     
    5556        } :data
    5657       
     58#ifdef CONFIG_LINE_DEBUG
     59        .comment 0 : { *(.comment); } :debug
     60        .debug_abbrev 0 : { *(.debug_abbrev); } :debug
     61        .debug_aranges 0 : { *(.debug_aranges); } :debug
     62        .debug_info 0 : { *(.debug_info); } :debug
     63        .debug_line 0 : { *(.debug_line); } :debug
     64        .debug_loc 0 : { *(.debug_loc); } :debug
     65        .debug_pubnames 0 : { *(.debug_pubnames); } :debug
     66        .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
     67        .debug_ranges 0 : { *(.debug_ranges); } :debug
     68        .debug_str 0 : { *(.debug_str); } :debug
     69#endif
     70       
    5771        /DISCARD/ : {
    5872                *(*);
  • uspace/lib/c/generic/assert.c

    re51a514 rdf29f24  
    3333#include <assert.h>
    3434#include <stdio.h>
     35#include <io/klog.h>
    3536#include <stdlib.h>
     37#include <atomic.h>
    3638#include <stacktrace.h>
     39#include <stdint.h>
     40
     41static atomic_t failed_asserts = {0};
    3742
    3843void assert_abort(const char *cond, const char *file, unsigned int line)
    3944{
     45        /*
     46         * Send the message safely to klog. Nested asserts should not occur.
     47         */
     48        klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
     49            cond, file, line);
     50       
     51        /*
     52         * Check if this is a nested or parallel assert.
     53         */
     54        if (atomic_postinc(&failed_asserts))
     55                abort();
     56       
     57        /*
     58         * Attempt to print the message to standard output and display
     59         * the stack trace. These operations can theoretically trigger nested
     60         * assertions.
     61         */
    4062        printf("Assertion failed (%s) in file \"%s\", line %u.\n",
    4163            cond, file, line);
    4264        stacktrace_print();
     65       
    4366        abort();
    4467}
  • uspace/lib/c/generic/io/klog.c

    re51a514 rdf29f24  
    3838#include <sys/types.h>
    3939#include <unistd.h>
     40#include <errno.h>
    4041#include <io/klog.h>
     42#include <io/printf_core.h>
    4143
    4244size_t klog_write(const void *buf, size_t size)
     
    5557}
    5658
     59/** Print formatted text to klog.
     60 *
     61 * @param fmt Format string
     62 *
     63 * \see For more details about format string see printf_core.
     64 *
     65 */
     66int klog_printf(const char *fmt, ...)
     67{
     68        va_list args;
     69        va_start(args, fmt);
     70       
     71        int ret = klog_vprintf(fmt, args);
     72       
     73        va_end(args);
     74       
     75        return ret;
     76}
     77
     78static int klog_vprintf_str_write(const char *str, size_t size, void *data)
     79{
     80        size_t wr = klog_write(str, size);
     81        return str_nlength(str, wr);
     82}
     83
     84static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
     85{
     86        size_t offset = 0;
     87        size_t chars = 0;
     88       
     89        while (offset < size) {
     90                char buf[STR_BOUNDS(1)];
     91                size_t sz = 0;
     92               
     93                if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
     94                        klog_write(buf, sz);
     95               
     96                chars++;
     97                offset += sizeof(wchar_t);
     98        }
     99       
     100        return chars;
     101}
     102
     103/** Print formatted text to klog.
     104 *
     105 * @param fmt Format string
     106 * @param ap  Format parameters
     107 *
     108 * \see For more details about format string see printf_core.
     109 *
     110 */
     111int klog_vprintf(const char *fmt, va_list ap)
     112{
     113        printf_spec_t ps = {
     114                klog_vprintf_str_write,
     115                klog_vprintf_wstr_write,
     116                NULL
     117        };
     118       
     119        return printf_core(fmt, &ps, ap);
     120}
     121
    57122/** @}
    58123 */
  • uspace/lib/c/generic/io/vprintf.c

    re51a514 rdf29f24  
    9696/** Print formatted text to stdout.
    9797 *
    98  * @param file Output stream
    99  * @param fmt  Format string
    100  * @param ap   Format parameters
     98 * @param fmt Format string
     99 * @param ap  Format parameters
    101100 *
    102101 * \see For more details about format string see printf_core.
  • uspace/lib/c/generic/malloc.c

    re51a514 rdf29f24  
    6565#define BASE_ALIGN  16
    6666
     67/** Heap shrink granularity
     68 *
     69 * Try not to pump and stress the heap to much
     70 * by shrinking and enlarging it too often.
     71 * A heap area won't shrunk if it the released
     72 * free block is smaller than this constant.
     73 *
     74 */
     75#define SHRINK_GRANULARITY  (64 * PAGE_SIZE)
     76
    6777/** Overhead of each heap block. */
    6878#define STRUCT_OVERHEAD \
    6979        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    7080
     81/** Overhead of each area. */
     82#define AREA_OVERHEAD(size) \
     83        (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
     84
    7185/** Calculate real size of a heap block.
    7286 *
     
    86100 *
    87101 */
    88 #define AREA_FIRST_BLOCK(area) \
     102#define AREA_FIRST_BLOCK_HEAD(area) \
    89103        (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
     104
     105/** Get last block in heap area.
     106 *
     107 */
     108#define AREA_LAST_BLOCK_FOOT(area) \
     109        (((uintptr_t) (area)->end) - sizeof(heap_block_foot_t))
     110
     111/** Get header in heap block.
     112 *
     113 */
     114#define BLOCK_HEAD(foot) \
     115        ((heap_block_head_t *) \
     116            (((uintptr_t) (foot)) + sizeof(heap_block_foot_t) - (foot)->size))
    90117
    91118/** Get footer in heap block.
     
    94121#define BLOCK_FOOT(head) \
    95122        ((heap_block_foot_t *) \
    96             (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
     123            (((uintptr_t) (head)) + (head)->size - sizeof(heap_block_foot_t)))
    97124
    98125/** Heap area.
     
    115142        void *end;
    116143       
     144        /** Previous heap area */
     145        struct heap_area *prev;
     146       
    117147        /** Next heap area */
    118148        struct heap_area *next;
     
    157187
    158188/** Next heap block to examine (next fit algorithm) */
    159 static heap_block_head_t *next = NULL;
     189static heap_block_head_t *next_fit = NULL;
    160190
    161191/** Futex for thread-safe heap manipulation */
    162192static futex_t malloc_futex = FUTEX_INITIALIZER;
     193
     194#ifndef NDEBUG
     195
     196#define malloc_assert(expr) \
     197        do { \
     198                if (!(expr)) {\
     199                        futex_up(&malloc_futex); \
     200                        assert_abort(#expr, __FILE__, __LINE__); \
     201                } \
     202        } while (0)
     203
     204#else /* NDEBUG */
     205
     206#define malloc_assert(expr)
     207
     208#endif /* NDEBUG */
    163209
    164210/** Initialize a heap block
     
    202248        heap_block_head_t *head = (heap_block_head_t *) addr;
    203249       
    204         assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
     250        malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    205251       
    206252        heap_block_foot_t *foot = BLOCK_FOOT(head);
    207253       
    208         assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
    209         assert(head->size == foot->size);
     254        malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     255        malloc_assert(head->size == foot->size);
    210256}
    211257
    212258/** Check a heap area structure
    213259 *
     260 * Should be called only inside the critical section.
     261 *
    214262 * @param addr Address of the heap area.
    215263 *
     
    219267        heap_area_t *area = (heap_area_t *) addr;
    220268       
    221         assert(area->magic == HEAP_AREA_MAGIC);
    222         assert(area->start < area->end);
    223         assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
    224         assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     269        malloc_assert(area->magic == HEAP_AREA_MAGIC);
     270        malloc_assert(addr == area->start);
     271        malloc_assert(area->start < area->end);
     272        malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     273        malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
    225274}
    226275
    227276/** Create new heap area
    228277 *
    229  * @param start Preffered starting address of the new area.
    230  * @param size  Size of the area.
     278 * Should be called only inside the critical section.
     279 *
     280 * @param size Size of the area.
    231281 *
    232282 */
     
    248298       
    249299        area->start = astart;
    250         area->end = (void *)
    251             ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
     300        area->end = (void *) ((uintptr_t) astart + asize);
     301        area->prev = NULL;
    252302        area->next = NULL;
    253303        area->magic = HEAP_AREA_MAGIC;
    254304       
    255         void *block = (void *) AREA_FIRST_BLOCK(area);
     305        void *block = (void *) AREA_FIRST_BLOCK_HEAD(area);
    256306        size_t bsize = (size_t) (area->end - block);
    257307       
     
    262312                last_heap_area = area;
    263313        } else {
     314                area->prev = last_heap_area;
    264315                last_heap_area->next = area;
    265316                last_heap_area = area;
     
    271322/** Try to enlarge a heap area
    272323 *
     324 * Should be called only inside the critical section.
     325 *
    273326 * @param area Heap area to grow.
    274  * @param size Gross size of item to allocate (bytes).
     327 * @param size Gross size to grow (bytes).
     328 *
     329 * @return True if successful.
    275330 *
    276331 */
     
    282337        area_check(area);
    283338       
    284         size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
    285             PAGE_SIZE);
    286        
    287339        /* New heap area size */
    288         void *end = (void *)
    289             ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
     340        size_t gross_size = (size_t) (area->end - area->start) + size;
     341        size_t asize = ALIGN_UP(gross_size, PAGE_SIZE);
     342        void *end = (void *) ((uintptr_t) area->start + asize);
    290343       
    291344        /* Check for overflow */
     
    299352       
    300353        /* Add new free block */
    301         block_init(area->end, (size_t) (end - area->end), true, area);
     354        size_t net_size = (size_t) (end - area->end);
     355        if (net_size > 0)
     356                block_init(area->end, net_size, true, area);
    302357       
    303358        /* Update heap area parameters */
     
    309364/** Try to enlarge any of the heap areas
    310365 *
     366 * Should be called only inside the critical section.
     367 *
    311368 * @param size Gross size of item to allocate (bytes).
    312369 *
     
    318375       
    319376        /* First try to enlarge some existing area */
    320         heap_area_t *area;
    321         for (area = first_heap_area; area != NULL; area = area->next) {
     377        for (heap_area_t *area = first_heap_area; area != NULL;
     378            area = area->next) {
    322379                if (area_grow(area, size))
    323380                        return true;
     
    325382       
    326383        /* Eventually try to create a new area */
    327         return area_create(AREA_FIRST_BLOCK(size));
    328 }
    329 
    330 /** Try to shrink heap space
    331  *
     384        return area_create(AREA_OVERHEAD(size));
     385}
     386
     387/** Try to shrink heap
     388 *
     389 * Should be called only inside the critical section.
    332390 * In all cases the next pointer is reset.
    333391 *
    334  */
    335 static void heap_shrink(void)
    336 {
    337         next = NULL;
     392 * @param area Last modified heap area.
     393 *
     394 */
     395static void heap_shrink(heap_area_t *area)
     396{
     397        area_check(area);
     398       
     399        heap_block_foot_t *last_foot =
     400            (heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area);
     401        heap_block_head_t *last_head = BLOCK_HEAD(last_foot);
     402       
     403        block_check((void *) last_head);
     404        malloc_assert(last_head->area == area);
     405       
     406        if (last_head->free) {
     407                /*
     408                 * The last block of the heap area is
     409                 * unused. The area might be potentially
     410                 * shrunk.
     411                 */
     412               
     413                heap_block_head_t *first_head =
     414                    (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(area);
     415               
     416                block_check((void *) first_head);
     417                malloc_assert(first_head->area == area);
     418               
     419                size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE);
     420               
     421                if (first_head == last_head) {
     422                        /*
     423                         * The entire heap area consists of a single
     424                         * free heap block. This means we can get rid
     425                         * of it entirely.
     426                         */
     427                       
     428                        heap_area_t *prev = area->prev;
     429                        heap_area_t *next = area->next;
     430                       
     431                        if (prev != NULL) {
     432                                area_check(prev);
     433                                prev->next = next;
     434                        } else
     435                                first_heap_area = next;
     436                       
     437                        if (next != NULL) {
     438                                area_check(next);
     439                                next->prev = prev;
     440                        } else
     441                                last_heap_area = prev;
     442                       
     443                        as_area_destroy(area->start);
     444                } else if (shrink_size >= SHRINK_GRANULARITY) {
     445                        /*
     446                         * Make sure that we always shrink the area
     447                         * by a multiple of page size and update
     448                         * the block layout accordingly.
     449                         */
     450                       
     451                        size_t asize = (size_t) (area->end - area->start) - shrink_size;
     452                        void *end = (void *) ((uintptr_t) area->start + asize);
     453                       
     454                        /* Resize the address space area */
     455                        int ret = as_area_resize(area->start, asize, 0);
     456                        if (ret != EOK)
     457                                abort();
     458                       
     459                        /* Update heap area parameters */
     460                        area->end = end;
     461                        size_t excess = ((size_t) area->end) - ((size_t) last_head);
     462                       
     463                        if (excess > 0) {
     464                                if (excess >= STRUCT_OVERHEAD) {
     465                                        /*
     466                                         * The previous block cannot be free and there
     467                                         * is enough free space left in the area to
     468                                         * create a new free block.
     469                                         */
     470                                        block_init((void *) last_head, excess, true, area);
     471                                } else {
     472                                        /*
     473                                         * The excess is small. Therefore just enlarge
     474                                         * the previous block.
     475                                         */
     476                                        heap_block_foot_t *prev_foot = (heap_block_foot_t *)
     477                                            (((uintptr_t) last_head) - sizeof(heap_block_foot_t));
     478                                        heap_block_head_t *prev_head = BLOCK_HEAD(prev_foot);
     479                                       
     480                                        block_check((void *) prev_head);
     481                                       
     482                                        block_init(prev_head, prev_head->size + excess,
     483                                            prev_head->free, area);
     484                                }
     485                        }
     486                }
     487        }
     488       
     489        next_fit = NULL;
    338490}
    339491
     
    362514static void split_mark(heap_block_head_t *cur, const size_t size)
    363515{
    364         assert(cur->size >= size);
     516        malloc_assert(cur->size >= size);
    365517       
    366518        /* See if we should split the block. */
     
    398550{
    399551        area_check((void *) area);
    400         assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
    401         assert((void *) first_block < area->end);
    402        
    403         heap_block_head_t *cur;
    404         for (cur = first_block; (void *) cur < area->end;
     552        malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     553        malloc_assert((void *) first_block < area->end);
     554       
     555        for (heap_block_head_t *cur = first_block; (void *) cur < area->end;
    405556            cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
    406557                block_check(cur);
     
    425576                                split_mark(cur, real_size);
    426577                               
    427                                 next = cur;
     578                                next_fit = cur;
    428579                                return addr;
    429580                        } else {
     
    436587                                         * data in (including alignment).
    437588                                         */
    438                                         if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
     589                                        if ((void *) cur > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
    439590                                                /*
    440591                                                 * There is a block before the current block.
     
    477628                                                split_mark(next_head, real_size);
    478629                                               
    479                                                 next = next_head;
     630                                                next_fit = next_head;
    480631                                                return aligned;
    481632                                        } else {
     
    496647                                                        size_t reduced_size = cur->size - excess;
    497648                                                        cur = (heap_block_head_t *)
    498                                                             (AREA_FIRST_BLOCK(area) + excess);
     649                                                            (AREA_FIRST_BLOCK_HEAD(area) + excess);
    499650                                                       
    500                                                         block_init((void *) AREA_FIRST_BLOCK(area), excess,
    501                                                             true, area);
     651                                                        block_init((void *) AREA_FIRST_BLOCK_HEAD(area),
     652                                                            excess, true, area);
    502653                                                        block_init(cur, reduced_size, true, area);
    503654                                                        split_mark(cur, real_size);
    504655                                                       
    505                                                         next = cur;
     656                                                        next_fit = cur;
    506657                                                        return aligned;
    507658                                                }
     
    527678static void *malloc_internal(const size_t size, const size_t align)
    528679{
    529         assert(first_heap_area != NULL);
     680        malloc_assert(first_heap_area != NULL);
    530681       
    531682        if (align == 0)
     
    541692       
    542693        /* Try the next fit approach */
    543         split = next;
     694        split = next_fit;
    544695       
    545696        if (split != NULL) {
     
    552703       
    553704        /* Search the entire heap */
    554         heap_area_t *area;
    555         for (area = first_heap_area; area != NULL; area = area->next) {
     705        for (heap_area_t *area = first_heap_area; area != NULL;
     706            area = area->next) {
    556707                heap_block_head_t *first = (heap_block_head_t *)
    557                     AREA_FIRST_BLOCK(area);
     708                    AREA_FIRST_BLOCK_HEAD(area);
    558709               
    559710                void *addr = malloc_area(area, first, split, real_size,
     
    652803       
    653804        block_check(head);
    654         assert(!head->free);
     805        malloc_assert(!head->free);
    655806       
    656807        heap_area_t *area = head->area;
    657808       
    658809        area_check(area);
    659         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    660         assert((void *) head < area->end);
     810        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     811        malloc_assert((void *) head < area->end);
    661812       
    662813        void *ptr = NULL;
     
    675826                        block_init((void *) head + real_size,
    676827                            orig_size - real_size, true, area);
    677                         heap_shrink();
     828                        heap_shrink(area);
    678829                }
    679830               
     
    697848                       
    698849                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    699                         next = NULL;
     850                        next_fit = NULL;
    700851                } else
    701852                        reloc = true;
     
    729880       
    730881        block_check(head);
    731         assert(!head->free);
     882        malloc_assert(!head->free);
    732883       
    733884        heap_area_t *area = head->area;
    734885       
    735886        area_check(area);
    736         assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
    737         assert((void *) head < area->end);
     887        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     888        malloc_assert((void *) head < area->end);
    738889       
    739890        /* Mark the block itself as free. */
     
    751902       
    752903        /* Look at the previous block. If it is free, merge the two. */
    753         if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
     904        if ((void *) head > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
    754905                heap_block_foot_t *prev_foot =
    755906                    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
     
    765916        }
    766917       
    767         heap_shrink();
     918        heap_shrink(area);
    768919       
    769920        futex_up(&malloc_futex);
    770921}
    771922
     923void *heap_check(void)
     924{
     925        futex_down(&malloc_futex);
     926       
     927        if (first_heap_area == NULL) {
     928                futex_up(&malloc_futex);
     929                return (void *) -1;
     930        }
     931       
     932        /* Walk all heap areas */
     933        for (heap_area_t *area = first_heap_area; area != NULL;
     934            area = area->next) {
     935               
     936                /* Check heap area consistency */
     937                if ((area->magic != HEAP_AREA_MAGIC) ||
     938                    ((void *) area != area->start) ||
     939                    (area->start >= area->end) ||
     940                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
     941                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
     942                        futex_up(&malloc_futex);
     943                        return (void *) area;
     944                }
     945               
     946                /* Walk all heap blocks */
     947                for (heap_block_head_t *head = (heap_block_head_t *)
     948                    AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end;
     949                    head = (heap_block_head_t *) (((void *) head) + head->size)) {
     950                       
     951                        /* Check heap block consistency */
     952                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
     953                                futex_up(&malloc_futex);
     954                                return (void *) head;
     955                        }
     956                       
     957                        heap_block_foot_t *foot = BLOCK_FOOT(head);
     958                       
     959                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
     960                            (head->size != foot->size)) {
     961                                futex_up(&malloc_futex);
     962                                return (void *) foot;
     963                        }
     964                }
     965        }
     966       
     967        futex_up(&malloc_futex);
     968       
     969        return NULL;
     970}
     971
    772972/** @}
    773973 */
  • uspace/lib/c/generic/thread.c

    re51a514 rdf29f24  
    4444
    4545#ifndef THREAD_INITIAL_STACK_PAGES_NO
    46 #define THREAD_INITIAL_STACK_PAGES_NO 1
     46#define THREAD_INITIAL_STACK_PAGES_NO   2
    4747#endif
    4848
  • uspace/lib/c/include/adt/list.h

    re51a514 rdf29f24  
    4949 *
    5050 */
    51 #define LIST_INITIALIZE(name)  link_t name = { \
    52         .prev = &name, \
    53         .next = &name \
    54 }
     51#define LIST_INITIALIZE(name) \
     52        link_t name = { \
     53                .prev = &name, \
     54                .next = &name \
     55        }
     56
     57#define list_get_instance(link, type, member) \
     58        ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
     59
     60#define list_foreach(list, iterator) \
     61        for (link_t *iterator = (list).next; \
     62            iterator != &(list); iterator = iterator->next)
    5563
    5664/** Initialize doubly-linked circular list link
     
    7179 * Initialize doubly-linked circular list.
    7280 *
    73  * @param head Pointer to link_t structure representing head of the list.
    74  *
    75  */
    76 static inline void list_initialize(link_t *head)
    77 {
    78         head->prev = head;
    79         head->next = head;
     81 * @param list Pointer to link_t structure representing the list.
     82 *
     83 */
     84static inline void list_initialize(link_t *list)
     85{
     86        list->prev = list;
     87        list->next = list;
    8088}
    8189
     
    8593 *
    8694 * @param link Pointer to link_t structure to be added.
    87  * @param head Pointer to link_t structure representing head of the list.
    88  *
    89  */
    90 static inline void list_prepend(link_t *link, link_t *head)
    91 {
    92         link->next = head->next;
    93         link->prev = head;
    94         head->next->prev = link;
    95         head->next = link;
     95 * @param list Pointer to link_t structure representing the list.
     96 *
     97 */
     98static inline void list_prepend(link_t *link, link_t *list)
     99{
     100        link->next = list->next;
     101        link->prev = list;
     102        list->next->prev = link;
     103        list->next = link;
    96104}
    97105
     
    101109 *
    102110 * @param link Pointer to link_t structure to be added.
    103  * @param head Pointer to link_t structure representing head of the list.
    104  *
    105  */
    106 static inline void list_append(link_t *link, link_t *head)
    107 {
    108         link->prev = head->prev;
    109         link->next = head;
    110         head->prev->next = link;
    111         head->prev = link;
    112 }
    113 
    114 /** Insert item before another item in doubly-linked circular list. */
    115 static inline void list_insert_before(link_t *l, link_t *r)
    116 {
    117         list_append(l, r);
    118 }
    119 
    120 /** Insert item after another item in doubly-linked circular list. */
    121 static inline void list_insert_after(link_t *r, link_t *l)
    122 {
    123         list_prepend(l, r);
     111 * @param list Pointer to link_t structure representing the list.
     112 *
     113 */
     114static inline void list_append(link_t *link, link_t *list)
     115{
     116        link->prev = list->prev;
     117        link->next = list;
     118        list->prev->next = link;
     119        list->prev = link;
     120}
     121
     122/** Insert item before another item in doubly-linked circular list.
     123 *
     124 */
     125static inline void list_insert_before(link_t *link, link_t *list)
     126{
     127        list_append(link, list);
     128}
     129
     130/** Insert item after another item in doubly-linked circular list.
     131 *
     132 */
     133static inline void list_insert_after(link_t *link, link_t *list)
     134{
     135        list_prepend(list, link);
    124136}
    125137
     
    143155 * Query emptiness of doubly-linked circular list.
    144156 *
    145  * @param head Pointer to link_t structure representing head of the list.
    146  *
    147  */
    148 static inline int list_empty(link_t *head)
    149 {
    150         return ((head->next == head) ? 1 : 0);
     157 * @param list Pointer to link_t structure representing the list.
     158 *
     159 */
     160static inline int list_empty(link_t *list)
     161{
     162        return (list->next == list);
     163}
     164
     165/** Get head item of a list.
     166 *
     167 * @param list Pointer to link_t structure representing the list.
     168 *
     169 * @return Head item of the list.
     170 * @return NULL if the list is empty.
     171 *
     172 */
     173static inline link_t *list_head(link_t *list)
     174{
     175        return ((list->next == list) ? NULL : list->next);
    151176}
    152177
     
    205230}
    206231
    207 #define list_get_instance(link, type, member) \
    208         ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
    209 
    210 #define list_foreach(list, iterator) \
    211         for (link_t *iterator = (list).next; \
    212             iterator != &(list); iterator = iterator->next)
     232/** Get n-th item of a list.
     233 *
     234 * @param list Pointer to link_t structure representing the list.
     235 * @param n    Item number (indexed from zero).
     236 *
     237 * @return n-th item of the list.
     238 * @return NULL if no n-th item found.
     239 *
     240 */
     241static inline link_t *list_nth(link_t *list, unsigned int n)
     242{
     243        unsigned int cnt = 0;
     244       
     245        list_foreach(*list, link) {
     246                if (cnt == n)
     247                        return link;
     248               
     249                cnt++;
     250        }
     251       
     252        return NULL;
     253}
    213254
    214255extern int list_member(const link_t *, const link_t *);
  • uspace/lib/c/include/as.h

    re51a514 rdf29f24  
    5959extern int as_area_destroy(void *);
    6060extern void *set_maxheapsize(size_t);
    61 extern void * as_get_mappable_page(size_t);
     61extern void *as_get_mappable_page(size_t);
    6262extern int as_get_physical_mapping(void *, uintptr_t *);
    6363
  • uspace/lib/c/include/io/klog.h

    re51a514 rdf29f24  
    3737
    3838#include <sys/types.h>
     39#include <stdarg.h>
    3940
    4041extern size_t klog_write(const void *, size_t);
    4142extern void klog_update(void);
     43extern int klog_printf(const char *, ...);
     44extern int klog_vprintf(const char *, va_list);
    4245
    4346#endif
  • uspace/lib/c/include/malloc.h

    re51a514 rdf29f24  
    4646extern void *realloc(const void *addr, const size_t size);
    4747extern void free(const void *addr);
     48extern void *heap_check(void);
    4849
    4950#endif
  • uspace/lib/net/il/ip_client.c

    re51a514 rdf29f24  
    181181        /* Set the header */
    182182        header = (ip_header_t *) data;
    183         header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) +
    184             ipopt_length);
     183        SET_IP_HEADER_LENGTH(header,
     184            (IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length)));
    185185        header->ttl = (ttl ? ttl : IPDEFTTL);
    186186        header->tos = tos;
     
    188188
    189189        if (dont_fragment)
    190                 header->flags = IPFLAG_DONT_FRAGMENT;
     190                SET_IP_HEADER_FLAGS(header, IPFLAG_DONT_FRAGMENT);
    191191
    192192        return EOK;
     
    227227                *tos = header->tos;
    228228        if (dont_fragment)
    229                 *dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT;
     229                *dont_fragment = GET_IP_HEADER_FLAGS(header) & IPFLAG_DONT_FRAGMENT;
    230230        if (ipopt_length) {
    231231                *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t);
  • uspace/lib/net/include/ip_header.h

    re51a514 rdf29f24  
    6464 */
    6565#define IP_FRAGMENT_OFFSET(header) \
    66         ((((header)->fragment_offset_high << 8) + \
     66        (((GET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header) << 8) + \
    6767            (header)->fragment_offset_low) * 8U)
    6868
     
    8383 */
    8484#define IP_HEADER_LENGTH(header) \
    85         ((header)->header_length * 4U)
     85        (GET_IP_HEADER_LENGTH(header) * 4U)
    8686
    8787/** Returns the actual IP packet total length.
     
    143143 */
    144144struct ip_header {
    145 #ifdef ARCH_IS_BIG_ENDIAN
    146         uint8_t version : 4;
    147         uint8_t header_length : 4;
    148 #else
    149         uint8_t header_length : 4;
    150         uint8_t version : 4;
    151 #endif
     145        uint8_t vhl; /* version, header_length */
     146
     147#define GET_IP_HEADER_VERSION(header) \
     148        (((header)->vhl & 0xf0) >> 4)
     149#define SET_IP_HEADER_VERSION(header, version) \
     150        ((header)->vhl = \
     151         ((version & 0x0f) << 4) | ((header)->vhl & 0x0f))
     152
     153#define GET_IP_HEADER_LENGTH(header) \
     154        ((header)->vhl & 0x0f)
     155#define SET_IP_HEADER_LENGTH(header, length) \
     156        ((header)->vhl = \
     157         (length & 0x0f) | ((header)->vhl & 0xf0))
    152158
    153159        uint8_t tos;
     
    155161        uint16_t identification;
    156162
    157 #ifdef ARCH_IS_BIG_ENDIAN
    158         uint8_t flags : 3;
    159         uint8_t fragment_offset_high : 5;
    160 #else
    161         uint8_t fragment_offset_high : 5;
    162         uint8_t flags : 3;
    163 #endif
     163        uint8_t ffoh; /* flags, fragment_offset_high */
     164
     165#define GET_IP_HEADER_FLAGS(header) \
     166        (((header)->ffoh & 0xe0) >> 5)
     167#define SET_IP_HEADER_FLAGS(header, flags) \
     168        ((header)->ffoh = \
     169         ((flags & 0x07) << 5) | ((header)->ffoh & 0x1f))
     170
     171#define GET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header) \
     172        ((header)->ffoh & 0x1f)
     173#define SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header, fragment_offset_high) \
     174        ((header)->ffoh = \
     175         (fragment_offset_high & 0x1f) | ((header)->ffoh & 0xe0))
    164176
    165177        uint8_t fragment_offset_low;
     
    181193        uint8_t pointer;
    182194
    183 #ifdef ARCH_IS_BIG_ENDIAN
    184         uint8_t overflow : 4;
    185         uint8_t flags : 4;
    186 #else
    187         uint8_t flags : 4;
    188         uint8_t overflow : 4;
    189 #endif
     195        uint8_t of; /* overflow, flags */
     196
     197#define GET_IP_OPTION_OVERFLOW(option) \
     198        (((option)->of & 0xf0) >> 4)
     199#define SET_IP_OPTION_OVERFLOW(option, overflow) \
     200        ((option)->of = \
     201         ((overflow & 0x0f) << 4) | ((option)->of & 0x0f))
     202
     203#define GET_IP_OPTION_FLAGS(option) \
     204        ((option)->of & 0x0f)
     205#define SET_IP_OPTION_FLAGS(option, flags) \
     206        ((option)->of = \
     207         (flags & 0x0f) | ((option)->of & 0xf0))
     208
    190209} __attribute__ ((packed));
    191210
  • uspace/srv/net/il/ip/ip.c

    re51a514 rdf29f24  
    201201
    202202        /* Set the destination address */
    203         switch (header->version) {
     203        switch (GET_IP_HEADER_VERSION(header)) {
    204204        case IPVERSION:
    205205                addrlen = sizeof(dest_in);
     
    635635
    636636        /* Process all IP options */
    637         while (next < first->header_length) {
     637        while (next < GET_IP_HEADER_LENGTH(first)) {
    638638                option = (ip_option_t *) (((uint8_t *) first) + next);
    639639                /* Skip end or noop */
     
    656656        if (length % 4) {
    657657                bzero(((uint8_t *) last) + length, 4 - (length % 4));
    658                 last->header_length = length / 4 + 1;
     658                SET_IP_HEADER_LENGTH(last, (length / 4 + 1));
    659659        } else {
    660                 last->header_length = length / 4;
     660                SET_IP_HEADER_LENGTH(last, (length / 4));
    661661        }
    662662
     
    706706                return rc;
    707707       
    708         header->version = IPV4;
    709         header->fragment_offset_high = 0;
     708        SET_IP_HEADER_VERSION(header, IPV4);
     709        SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header, 0);
    710710        header->fragment_offset_low = 0;
    711711        header->header_checksum = 0;
     
    735735                        memcpy(middle_header, last_header,
    736736                            IP_HEADER_LENGTH(last_header));
    737                         header->flags |= IPFLAG_MORE_FRAGMENTS;
     737                        SET_IP_HEADER_FLAGS(header,
     738                            (GET_IP_HEADER_FLAGS(header) | IPFLAG_MORE_FRAGMENTS));
    738739                        middle_header->total_length =
    739740                            htons(packet_get_data_length(next));
    740                         middle_header->fragment_offset_high =
    741                             IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length);
     741                        SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(middle_header,
     742                            IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length));
    742743                        middle_header->fragment_offset_low =
    743744                            IP_COMPUTE_FRAGMENT_OFFSET_LOW(length);
     
    768769                middle_header->total_length =
    769770                    htons(packet_get_data_length(next));
    770                 middle_header->fragment_offset_high =
    771                     IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length);
     771                SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(middle_header,
     772                    IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length));
    772773                middle_header->fragment_offset_low =
    773774                    IP_COMPUTE_FRAGMENT_OFFSET_LOW(length);
     
    785786                length += packet_get_data_length(next);
    786787                free(last_header);
    787                 header->flags |= IPFLAG_MORE_FRAGMENTS;
     788                SET_IP_HEADER_FLAGS(header,
     789                    (GET_IP_HEADER_FLAGS(header) | IPFLAG_MORE_FRAGMENTS));
    788790        }
    789791
     
    834836        new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length);
    835837        offset = IP_FRAGMENT_OFFSET(header) + IP_HEADER_DATA_LENGTH(header);
    836         new_header->fragment_offset_high =
    837             IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset);
     838        SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(new_header,
     839            IP_COMPUTE_FRAGMENT_OFFSET_HIGH(offset));
    838840        new_header->fragment_offset_low =
    839841            IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset);
     
    865867                return NULL;
    866868        memcpy(middle, last, IP_HEADER_LENGTH(last));
    867         middle->flags |= IPFLAG_MORE_FRAGMENTS;
     869        SET_IP_HEADER_FLAGS(middle,
     870            (GET_IP_HEADER_FLAGS(middle) | IPFLAG_MORE_FRAGMENTS));
    868871        return middle;
    869872}
     
    922925
    923926        /* Fragmentation forbidden? */
    924         if(header->flags & IPFLAG_DONT_FRAGMENT)
     927        if(GET_IP_HEADER_FLAGS(header) & IPFLAG_DONT_FRAGMENT)
    925928                return EPERM;
    926929
     
    958961
    959962        /* Mark the first as fragmented */
    960         header->flags |= IPFLAG_MORE_FRAGMENTS;
     963        SET_IP_HEADER_FLAGS(header,
     964            (GET_IP_HEADER_FLAGS(header) | IPFLAG_MORE_FRAGMENTS));
    961965
    962966        /* Create middle fragments */
     
    13191323        int rc;
    13201324
    1321         if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
     1325        if ((GET_IP_HEADER_FLAGS(header) & IPFLAG_MORE_FRAGMENTS) ||
    13221326            IP_FRAGMENT_OFFSET(header)) {
    13231327                // TODO fragmented
     
    13251329        }
    13261330       
    1327         switch (header->version) {
     1331        switch (GET_IP_HEADER_VERSION(header)) {
    13281332        case IPVERSION:
    13291333                addrlen = sizeof(src_in);
     
    14471451
    14481452        /* Set the destination address */
    1449         switch (header->version) {
     1453        switch (GET_IP_HEADER_VERSION(header)) {
    14501454        case IPVERSION:
    14511455                addrlen = sizeof(addr_in);
  • uspace/srv/net/tl/tcp/tcp.c

    re51a514 rdf29f24  
    476476        old_incoming = socket_data->next_incoming;
    477477
    478         if (header->finalize) {
     478        if (GET_TCP_HEADER_FINALIZE(header)) {
    479479                socket_data->fin_incoming = new_sequence_number +
    480480                    total_length - TCP_HEADER_LENGTH(header);
     
    838838        assert(packet);
    839839
    840         if (!header->synchronize)
     840        if (!GET_TCP_HEADER_SYNCHRONIZE(header))
    841841                return tcp_release_and_return(packet, EINVAL);
    842842       
     
    903903        assert(packet);
    904904
    905         if (!header->synchronize)
     905        if (!GET_TCP_HEADER_SYNCHRONIZE(header))
    906906                return tcp_release_and_return(packet, EINVAL);
    907907
     
    10571057        assert(packet);
    10581058
    1059         if (!header->acknowledge)
     1059        if (!GET_TCP_HEADER_ACKNOWLEDGE(header))
    10601060                return tcp_release_and_return(packet, EINVAL);
    10611061
     
    11261126        assert(header);
    11271127
    1128         if (!header->acknowledge)
     1128        if (!GET_TCP_HEADER_ACKNOWLEDGE(header))
    11291129                return;
    11301130
     
    18331833
    18341834        /* Remember the outgoing FIN */
    1835         if (header->finalize)
     1835        if (GET_TCP_HEADER_FINALIZE(header))
    18361836                socket_data->fin_outgoing = socket_data->next_outgoing;
    18371837       
     
    19521952                header->acknowledgement_number =
    19531953                    htonl(socket_data->next_incoming);
    1954                 header->acknowledge = 1;
     1954                SET_TCP_HEADER_ACKNOWLEDGE(header, 1);
    19551955        }
    19561956        header->window = htons(socket_data->window);
     
    20242024        header->source_port = htons(socket->port);
    20252025        header->source_port = htons(socket_data->dest_port);
    2026         header->header_length = TCP_COMPUTE_HEADER_LENGTH(sizeof(*header));
    2027         header->synchronize = synchronize;
    2028         header->finalize = finalize;
     2026        SET_TCP_HEADER_LENGTH(header,
     2027            TCP_COMPUTE_HEADER_LENGTH(sizeof(*header)));
     2028        SET_TCP_HEADER_SYNCHRONIZE(header, synchronize);
     2029        SET_TCP_HEADER_FINALIZE(header, finalize);
    20292030}
    20302031
  • uspace/srv/net/tl/tcp/tcp_header.h

    re51a514 rdf29f24  
    4747 * @param[in] header The TCP packet header.
    4848 */
    49 #define TCP_HEADER_LENGTH(header)               ((header)->header_length * 4U)
     49#define TCP_HEADER_LENGTH(header)               (GET_TCP_HEADER_LENGTH(header) * 4U)
    5050
    5151/** Returns the TCP header length.
     
    7373        uint32_t sequence_number;
    7474        uint32_t acknowledgement_number;
    75        
    76 #ifdef ARCH_IS_BIG_ENDIAN
    77         uint8_t header_length:4;
    78         uint8_t reserved1:4;
    79 #else
    80         uint8_t reserved1:4;
    81         uint8_t header_length:4;
    82 #endif
    8375
    84 #ifdef ARCH_IS_BIG_ENDIAN
    85         uint8_t reserved2:2;
    86         uint8_t urgent:1;
    87         uint8_t acknowledge:1;
    88         uint8_t push:1;
    89         uint8_t reset:1;
    90         uint8_t synchronize:1;
    91         uint8_t finalize:1;
    92 #else
    93         uint8_t finalize:1;
    94         uint8_t synchronize:1;
    95         uint8_t reset:1;
    96         uint8_t push:1;
    97         uint8_t acknowledge:1;
    98         uint8_t urgent:1;
    99         uint8_t reserved2:2;
    100 #endif
     76        uint8_t hlr; /* header length, reserved1 */
     77
     78#define GET_TCP_HEADER_LENGTH(header) \
     79        (((header)->hlr & 0xf0) >> 4)
     80#define SET_TCP_HEADER_LENGTH(header, length) \
     81        ((header)->hlr = \
     82         ((length & 0x0f) << 4) | ((header)->hlr & 0x0f))
     83
     84#define GET_TCP_HEADER_RESERVED1(header) \
     85        ((header)->hlr & 0x0f)
     86#define SET_TCP_HEADER_RESERVED1(header, reserved1) \
     87        ((header)->hlr = \
     88         (reserved1 & 0x0f) | ((header)->hlr & 0xf0))
     89
     90        /* reserved2, urgent, acknowledge, push, reset, synchronize, finalize */
     91        uint8_t ruaprsf; 
     92
     93#define GET_TCP_HEADER_RESERVED2(header) \
     94        (((header)->ruaprsf & 0xc0) >> 6)
     95#define SET_TCP_HEADER_RESERVED2(header, reserved2) \
     96        ((header)->ruaprsf = \
     97         ((reserved2 & 0x03) << 6) | ((header)->ruaprsf & 0x3f))
     98
     99#define GET_TCP_HEADER_URGENT(header) \
     100        (((header)->ruaprsf & 0x20) >> 5)
     101#define SET_TCP_HEADER_URGENT(header, urgent) \
     102        ((header)->ruaprsf = \
     103         ((urgent & 0x01) << 5) | ((header)->ruaprsf & 0xdf))
     104
     105#define GET_TCP_HEADER_ACKNOWLEDGE(header) \
     106        (((header)->ruaprsf & 0x10) >> 4)
     107#define SET_TCP_HEADER_ACKNOWLEDGE(header, acknowledge) \
     108        ((header)->ruaprsf = \
     109         ((acknowledge & 0x01) << 4) | ((header)->ruaprsf & 0xef))
     110
     111#define GET_TCP_HEADER_PUSH(header) \
     112        (((header)->ruaprsf & 0x08) >> 3)
     113#define SET_TCP_HEADER_PUSH(header, push) \
     114        ((header)->ruaprsf = \
     115         ((push & 0x01) << 3) | ((header)->ruaprsf & 0xf7))
     116
     117#define GET_TCP_HEADER_RESET(header) \
     118        (((header)->ruaprsf & 0x04) >> 2)
     119#define SET_TCP_HEADER_RESET(header, reset) \
     120        ((header)->ruaprsf = \
     121         ((reset & 0x01) << 2) | ((header)->ruaprsf & 0xfb))
     122
     123#define GET_TCP_HEADER_SYNCHRONIZE(header) \
     124        (((header)->ruaprsf & 0x02) >> 1)
     125#define SET_TCP_HEADER_SYNCHRONIZE(header, synchronize) \
     126        ((header)->ruaprsf = \
     127         ((synchronize & 0x01) << 1) | ((header)->ruaprsf & 0xfd))
     128
     129#define GET_TCP_HEADER_FINALIZE(header) \
     130        ((header)->ruaprsf & 0x01)
     131#define SET_TCP_HEADER_FINALIZE(header, finalize) \
     132        ((header)->ruaprsf = \
     133         (finalize & 0x01) | ((header)->ruaprsf & 0xfe))
    101134
    102135        uint16_t window;
  • uspace/srv/vfs/vfs.h

    re51a514 rdf29f24  
    176176    vfs_pair_t *, ...);
    177177extern int vfs_open_node_internal(vfs_lookup_res_t *);
    178 extern int vfs_close_internal(vfs_file_t *);
    179178
    180179extern bool vfs_nodes_init(void);
  • uspace/srv/vfs/vfs_file.c

    re51a514 rdf29f24  
    7979        for (i = 0; i < MAX_OPEN_FILES; i++) {
    8080                if (FILES[i]) {
    81                         (void) vfs_close_internal(FILES[i]);
    8281                        (void) vfs_fd_free(i);
    8382                }
     
    108107}
    109108
     109/** Close the file in the endpoint FS server. */
     110static int vfs_file_close_remote(vfs_file_t *file)
     111{
     112        ipc_call_t answer;
     113        aid_t msg;
     114        sysarg_t rc;
     115        int phone;
     116
     117        assert(!file->refcnt);
     118
     119        phone = vfs_grab_phone(file->node->fs_handle);
     120        msg = async_send_2(phone, VFS_OUT_CLOSE, file->node->devmap_handle,
     121            file->node->index, &answer);
     122        async_wait_for(msg, &rc);
     123        vfs_release_phone(file->node->fs_handle, phone);
     124
     125        return IPC_GET_ARG1(answer);
     126}
     127
     128
    110129/** Increment reference count of VFS file structure.
    111130 *
     
    125144 *                      decremented.
    126145 */
    127 static void vfs_file_delref(vfs_file_t *file)
    128 {
     146static int vfs_file_delref(vfs_file_t *file)
     147{
     148        int rc = EOK;
     149
    129150        assert(fibril_mutex_is_locked(&VFS_DATA->lock));
    130151
    131152        if (file->refcnt-- == 1) {
    132153                /*
    133                  * Lost the last reference to a file, need to drop our reference
    134                  * to the underlying VFS node.
     154                 * Lost the last reference to a file, need to close it in the
     155                 * endpoint FS and drop our reference to the underlying VFS node.
    135156                 */
     157                rc = vfs_file_close_remote(file);
    136158                vfs_node_delref(file->node);
    137159                free(file);
    138160        }
     161
     162        return rc;
    139163}
    140164
     
    201225int vfs_fd_free(int fd)
    202226{
     227        int rc;
     228
    203229        if (!vfs_files_init())
    204230                return ENOMEM;
     
    210236        }
    211237       
    212         vfs_file_delref(FILES[fd]);
     238        rc = vfs_file_delref(FILES[fd]);
    213239        FILES[fd] = NULL;
    214240        fibril_mutex_unlock(&VFS_DATA->lock);
    215241       
    216         return EOK;
     242        return rc;
    217243}
    218244
  • uspace/srv/vfs/vfs_ops.c

    re51a514 rdf29f24  
    717717}
    718718
    719 int vfs_close_internal(vfs_file_t *file)
    720 {
    721         /*
    722          * Lock the open file structure so that no other thread can manipulate
    723          * the same open file at a time.
    724          */
    725         fibril_mutex_lock(&file->lock);
    726        
    727         if (file->refcnt <= 1) {
    728                 /* Only close the file on the destination FS server
    729                    if there are no more file descriptors (except the
    730                    present one) pointing to this file. */
    731                
    732                 int fs_phone = vfs_grab_phone(file->node->fs_handle);
    733                
    734                 /* Make a VFS_OUT_CLOSE request at the destination FS server. */
    735                 aid_t msg;
    736                 ipc_call_t answer;
    737                 msg = async_send_2(fs_phone, VFS_OUT_CLOSE,
    738                     file->node->devmap_handle, file->node->index, &answer);
    739                
    740                 /* Wait for reply from the FS server. */
    741                 sysarg_t rc;
    742                 async_wait_for(msg, &rc);
    743                
    744                 vfs_release_phone(file->node->fs_handle, fs_phone);
    745                 fibril_mutex_unlock(&file->lock);
    746                
    747                 return IPC_GET_ARG1(answer);
    748         }
    749        
    750         fibril_mutex_unlock(&file->lock);
    751         return EOK;
    752 }
    753 
    754719void vfs_close(ipc_callid_t rid, ipc_call_t *request)
    755720{
    756721        int fd = IPC_GET_ARG1(*request);
    757        
    758         /* Lookup the file structure corresponding to the file descriptor. */
    759         vfs_file_t *file = vfs_file_get(fd);
    760         if (!file) {
    761                 async_answer_0(rid, ENOENT);
    762                 return;
    763         }
    764        
    765         int ret = vfs_close_internal(file);
    766         if (ret != EOK)
    767                 async_answer_0(rid, ret);
    768        
    769         vfs_file_put(file);
     722        int ret;
     723       
    770724        ret = vfs_fd_free(fd);
    771725        async_answer_0(rid, ret);
     
    13691323        fibril_mutex_lock(&oldfile->lock);
    13701324       
    1371         /* Lookup an open file structure possibly corresponding to newfd. */
    1372         vfs_file_t *newfile = vfs_file_get(newfd);
    1373         if (newfile) {
    1374                 /* Close the originally opened file. */
    1375                 int ret = vfs_close_internal(newfile);
    1376                 if (ret != EOK) {
    1377                         fibril_mutex_unlock(&oldfile->lock);
    1378                         vfs_file_put(oldfile);
    1379                         vfs_file_put(newfile);
    1380                         async_answer_0(rid, ret);
    1381                         return;
    1382                 }
    1383                
    1384                 ret = vfs_fd_free(newfd);
    1385                 if (ret != EOK) {
    1386                         fibril_mutex_unlock(&oldfile->lock);
    1387                         vfs_file_put(oldfile);
    1388                         vfs_file_put(newfile);
    1389                         async_answer_0(rid, ret);
    1390                         return;
    1391                 }
    1392                 vfs_file_put(newfile);
    1393         }
     1325        /* Make sure newfd is closed. */
     1326        (void) vfs_fd_free(newfd);
    13941327       
    13951328        /* Assign the old file to newfd. */
Note: See TracChangeset for help on using the changeset viewer.