Changeset c47e1a8 in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2010-05-21T07:50:04Z (16 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d51ee2b
Parents:
cf8cc36 (diff), 15b592b (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 (rev. 451)

Location:
uspace/lib/c/generic
Files:
4 added
46 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/adt/hash_table.c

    rcf8cc36 rc47e1a8  
    4242#include <malloc.h>
    4343#include <assert.h>
    44 #include <stdio.h>
    45 #include <string.h>
     44#include <str.h>
    4645
    4746/** Create chained hash table.
    4847 *
    49  * @param h             Hash table structure. Will be initialized by this call.
    50  * @param m             Number of hash table buckets.
    51  * @param max_keys      Maximal number of keys needed to identify an item.
    52  * @param op            Hash table operations structure.
    53  * @return              True on success
     48 * @param h        Hash table structure. Will be initialized by this call.
     49 * @param m        Number of hash table buckets.
     50 * @param max_keys Maximal number of keys needed to identify an item.
     51 * @param op       Hash table operations structure.
     52 *
     53 * @return True on success
     54 *
    5455 */
    5556int hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,
    5657    hash_table_operations_t *op)
    5758{
    58         hash_count_t i;
    59 
    6059        assert(h);
    6160        assert(op && op->hash && op->compare);
     
    6362       
    6463        h->entry = malloc(m * sizeof(link_t));
    65         if (!h->entry) {
    66                 printf("cannot allocate memory for hash table\n");
     64        if (!h->entry)
    6765                return false;
    68         }
     66       
    6967        memset((void *) h->entry, 0,  m * sizeof(link_t));
    7068       
     69        hash_count_t i;
    7170        for (i = 0; i < m; i++)
    7271                list_initialize(&h->entry[i]);
     
    7574        h->max_keys = max_keys;
    7675        h->op = op;
     76       
    7777        return true;
    7878}
     
    8080/** Destroy a hash table instance.
    8181 *
    82  * @param h             Hash table to be destroyed.
     82 * @param h Hash table to be destroyed.
     83 *
    8384 */
    8485void hash_table_destroy(hash_table_t *h)
     
    8687        assert(h);
    8788        assert(h->entry);
     89       
    8890        free(h->entry);
    8991}
     
    9193/** Insert item into a hash table.
    9294 *
    93  * @param h             Hash table.
    94  * @param key           Array of all keys necessary to compute hash index.
    95  * @param item          Item to be inserted into the hash table.
     95 * @param h    Hash table.
     96 * @param key  Array of all keys necessary to compute hash index.
     97 * @param item Item to be inserted into the hash table.
    9698 */
    9799void hash_table_insert(hash_table_t *h, unsigned long key[], link_t *item)
    98100{
    99         hash_index_t chain;
    100 
    101101        assert(item);
    102102        assert(h && h->op && h->op->hash && h->op->compare);
    103 
    104         chain = h->op->hash(key);
     103       
     104        hash_index_t chain = h->op->hash(key);
    105105        assert(chain < h->entries);
    106106       
     
    110110/** Search hash table for an item matching keys.
    111111 *
    112  * @param h             Hash table.
    113  * @param key           Array of all keys needed to compute hash index.
    114  *
    115  * @return              Matching item on success, NULL if there is no such item.
     112 * @param h   Hash table.
     113 * @param key Array of all keys needed to compute hash index.
     114 *
     115 * @return Matching item on success, NULL if there is no such item.
     116 *
    116117 */
    117118link_t *hash_table_find(hash_table_t *h, unsigned long key[])
    118119{
     120        assert(h && h->op && h->op->hash && h->op->compare);
     121       
     122        hash_index_t chain = h->op->hash(key);
     123        assert(chain < h->entries);
     124       
    119125        link_t *cur;
    120         hash_index_t chain;
    121 
    122         assert(h && h->op && h->op->hash && h->op->compare);
    123 
    124         chain = h->op->hash(key);
    125         assert(chain < h->entries);
    126        
    127126        for (cur = h->entry[chain].next; cur != &h->entry[chain];
    128127            cur = cur->next) {
     
    142141 * For each removed item, h->remove_callback() is called.
    143142 *
    144  * @param h             Hash table.
    145  * @param key           Array of keys that will be compared against items of
    146  *                      the hash table.
    147  * @param keys          Number of keys in the 'key' array.
     143 * @param h    Hash table.
     144 * @param key  Array of keys that will be compared against items of
     145 *             the hash table.
     146 * @param keys Number of keys in the 'key' array.
     147 *
    148148 */
    149149void hash_table_remove(hash_table_t *h, unsigned long key[], hash_count_t keys)
    150150{
    151         hash_index_t chain;
    152         link_t *cur;
    153 
    154151        assert(h && h->op && h->op->hash && h->op->compare &&
    155152            h->op->remove_callback);
    156153        assert(keys <= h->max_keys);
    157154       
     155        link_t *cur;
     156       
    158157        if (keys == h->max_keys) {
    159 
    160158                /*
    161159                 * All keys are known, hash_table_find() can be used to find the
    162160                 * entry.
    163161                 */
    164        
     162               
    165163                cur = hash_table_find(h, key);
    166164                if (cur) {
     
    168166                        h->op->remove_callback(cur);
    169167                }
     168               
    170169                return;
    171170        }
     
    175174         * Any partially matching entries are to be removed.
    176175         */
     176        hash_index_t chain;
    177177        for (chain = 0; chain < h->entries; chain++) {
    178178                for (cur = h->entry[chain].next; cur != &h->entry[chain];
     
    195195/** Apply fucntion to all items in hash table.
    196196 *
    197  * @param h             Hash table.
    198  * @param f             Function to be applied.
    199  * @param arg           Argument to be passed to the function.
    200  */
    201 void
    202 hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
     197 * @param h   Hash table.
     198 * @param f   Function to be applied.
     199 * @param arg Argument to be passed to the function.
     200 *
     201 */
     202void hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg)
    203203{
    204204        hash_index_t bucket;
    205205        link_t *cur;
    206 
     206       
    207207        for (bucket = 0; bucket < h->entries; bucket++) {
    208208                for (cur = h->entry[bucket].next; cur != &h->entry[bucket];
  • uspace/lib/c/generic/async.c

    rcf8cc36 rc47e1a8  
    746746        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
    747747            &conn_hash_table_ops)) {
    748                 printf("%s: cannot create hash table\n", "async");
     748                printf("%s: Cannot create async hash table\n", "libc");
    749749                return ENOMEM;
    750750        }
     
    11011101}
    11021102
     1103/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
     1104 *
     1105 * Ask through phone for a new connection to some service.
     1106 *
     1107 * @param phoneid       Phone handle used for contacting the other side.
     1108 * @param arg1          User defined argument.
     1109 * @param arg2          User defined argument.
     1110 * @param arg3          User defined argument.
     1111 *
     1112 * @return              New phone handle on success or a negative error code.
     1113 */
     1114int
     1115async_connect_me_to(int phoneid, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3)
     1116{
     1117        int rc;
     1118        ipcarg_t newphid;
     1119
     1120        rc = async_req_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, NULL,
     1121            NULL, NULL, NULL, &newphid);
     1122       
     1123        if (rc != EOK) 
     1124                return rc;
     1125
     1126        return newphid;
     1127}
     1128
     1129/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
     1130 *
     1131 * Ask through phone for a new connection to some service and block until
     1132 * success.
     1133 *
     1134 * @param phoneid       Phone handle used for contacting the other side.
     1135 * @param arg1          User defined argument.
     1136 * @param arg2          User defined argument.
     1137 * @param arg3          User defined argument.
     1138 *
     1139 * @return              New phone handle on success or a negative error code.
     1140 */
     1141int
     1142async_connect_me_to_blocking(int phoneid, ipcarg_t arg1, ipcarg_t arg2,
     1143    ipcarg_t arg3)
     1144{
     1145        int rc;
     1146        ipcarg_t newphid;
     1147
     1148        rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1149            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
     1150       
     1151        if (rc != EOK) 
     1152                return rc;
     1153
     1154        return newphid;
     1155}
     1156
    11031157/** Wrapper for making IPC_M_SHARE_IN calls using the async framework.
    11041158 *
     
    13101364            IPC_FF_ROUTE_FROM_ME);
    13111365        if (retval != EOK) {
     1366                async_wait_for(msg, NULL);
    13121367                ipc_answer_0(callid, retval);
    13131368                return retval;
     
    13831438}
    13841439
    1385 /** Wrapper for receiving binary data
     1440/** Wrapper for receiving binary data or strings
    13861441 *
    13871442 * This wrapper only makes it more comfortable to use async_data_write_*
    1388  * functions to receive binary data.
     1443 * functions to receive binary data or strings.
    13891444 *
    13901445 * @param data       Pointer to data pointer (which should be later disposed
    13911446 *                   by free()). If the operation fails, the pointer is not
    13921447 *                   touched.
     1448 * @param nullterm   If true then the received data is always zero terminated.
     1449 *                   This also causes to allocate one extra byte beyond the
     1450 *                   raw transmitted data.
    13931451 * @param min_size   Minimum size (in bytes) of the data to receive.
    13941452 * @param max_size   Maximum size (in bytes) of the data to receive. 0 means
    13951453 *                   no limit.
    1396  * @param granulariy If non-zero, then the size of the received data has to
     1454 * @param granulariy If non-zero then the size of the received data has to
    13971455 *                   be divisible by this value.
    13981456 * @param received   If not NULL, the size of the received data is stored here.
     
    14011459 *
    14021460 */
    1403 int async_data_receive(void **data, const size_t min_size,
    1404     const size_t max_size, const size_t granularity, size_t *received)
     1461int async_data_write_accept(void **data, const bool nullterm,
     1462    const size_t min_size, const size_t max_size, const size_t granularity,
     1463    size_t *received)
    14051464{
    14061465        ipc_callid_t callid;
     
    14261485        }
    14271486       
    1428         void *_data = malloc(size);
     1487        void *_data;
     1488       
     1489        if (nullterm)
     1490                _data = malloc(size + 1);
     1491        else
     1492                _data = malloc(size);
     1493       
    14291494        if (_data == NULL) {
    14301495                ipc_answer_0(callid, ENOMEM);
     
    14381503        }
    14391504       
     1505        if (nullterm)
     1506                ((char *) _data)[size] = 0;
     1507       
    14401508        *data = _data;
    14411509        if (received != NULL)
     
    14451513}
    14461514
    1447 /** Wrapper for receiving strings
    1448  *
    1449  * This wrapper only makes it more comfortable to use async_data_write_*
    1450  * functions to receive strings.
    1451  *
    1452  * @param str      Pointer to string pointer (which should be later disposed
    1453  *                 by free()). If the operation fails, the pointer is not
    1454  *                 touched.
    1455  * @param max_size Maximum size (in bytes) of the string to receive. 0 means
    1456  *                 no limit.
    1457  * @param received If not NULL, the size of the received data is stored here.
    1458  *
    1459  * @return Zero on success or a value from @ref errno.h on failure.
    1460  *
    1461  */
    1462 int async_string_receive(char **str, const size_t max_size, size_t *received)
    1463 {
    1464         ipc_callid_t callid;
    1465         size_t size;
    1466         if (!async_data_write_receive(&callid, &size)) {
    1467                 ipc_answer_0(callid, EINVAL);
    1468                 return EINVAL;
    1469         }
    1470        
    1471         if ((max_size > 0) && (size > max_size)) {
    1472                 ipc_answer_0(callid, EINVAL);
    1473                 return EINVAL;
    1474         }
    1475        
    1476         char *data = (char *) malloc(size + 1);
    1477         if (data == NULL) {
    1478                 ipc_answer_0(callid, ENOMEM);
    1479                 return ENOMEM;
    1480         }
    1481        
    1482         int rc = async_data_write_finalize(callid, data, size);
    1483         if (rc != EOK) {
    1484                 free(data);
    1485                 return rc;
    1486         }
    1487        
    1488         data[size] = 0;
    1489         *str = data;
    1490         if (received != NULL)
    1491                 *received = size;
    1492        
    1493         return EOK;
    1494 }
    1495 
    14961515/** Wrapper for voiding any data that is about to be received
    14971516 *
     
    15011520 *
    15021521 */
    1503 void async_data_void(const int retval)
     1522void async_data_write_void(const int retval)
    15041523{
    15051524        ipc_callid_t callid;
     
    15121531 *
    15131532 */
    1514 int async_data_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
     1533int async_data_write_forward_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
    15151534    ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr)
    15161535{
     
    15311550            IPC_FF_ROUTE_FROM_ME);
    15321551        if (retval != EOK) {
     1552                async_wait_for(msg, NULL);
    15331553                ipc_answer_0(callid, retval);
    15341554                return retval;
  • uspace/lib/c/generic/clipboard.c

    rcf8cc36 rc47e1a8  
    4242#include <ipc/clipboard.h>
    4343#include <async.h>
    44 #include <string.h>
     44#include <str.h>
    4545#include <errno.h>
    4646#include <malloc.h>
     
    148148                        aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
    149149                        rc = async_data_read_start(clip_phone, (void *) sbuf, size);
    150                         if (rc == EOVERFLOW) {
     150                        if ((int) rc == EOVERFLOW) {
    151151                                /*
    152152                                 * The data in the clipboard has changed since
  • uspace/lib/c/generic/device/char.c

    rcf8cc36 rc47e1a8  
    6060       
    6161        aid_t req;
    62         int rc;
     62        int ret;
    6363       
    6464        if (read) {
    6565                req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_READ_DEV, &answer);
    66                 rc = async_data_read_start(dev_phone, buf, len);               
     66                ret = async_data_read_start(dev_phone, buf, len);               
    6767        } else {
    6868                req = async_send_1(dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE), CHAR_WRITE_DEV, &answer);
    69                 rc = async_data_write_start(dev_phone, buf, len);
     69                ret = async_data_write_start(dev_phone, buf, len);
    7070        }
    7171       
    72         if (rc != EOK) {
    73                 ipcarg_t rc_orig;
    74                 async_wait_for(req, &rc_orig);
     72        ipcarg_t rc;
     73        if (ret != EOK) {               
     74                async_wait_for(req, &rc);
    7575                async_serialize_end();
    76                 if (rc_orig == EOK) {
    77                         return rc;
     76                if (rc == EOK) {
     77                        return ret;
    7878                }
    7979                else {
    80                         return (int) rc_orig;
     80                        return (int) rc;
    8181                }
    8282        }
     
    8585        async_serialize_end();
    8686       
    87         if (EOK != rc) {
    88                 return rc;
     87        ret = (int)rc;
     88        if (EOK != ret) {
     89                return ret;
    8990        }
    9091       
  • uspace/lib/c/generic/devman.c

    rcf8cc36 rc47e1a8  
    3535 */
    3636
    37 #include <string.h>
     37#include <str.h>
    3838#include <stdio.h>
    3939#include <ipc/ipc.h>
  • uspace/lib/c/generic/devmap.c

    rcf8cc36 rc47e1a8  
    2828 */
    2929
    30 #include <string.h>
     30#include <str.h>
    3131#include <ipc/ipc.h>
    3232#include <ipc/services.h>
  • uspace/lib/c/generic/fibril.c

    rcf8cc36 rc47e1a8  
    4141#include <unistd.h>
    4242#include <stdio.h>
     43#include <arch/barrier.h>
    4344#include <libarch/faddr.h>
    4445#include <futex.h>
     
    4748
    4849#ifndef FIBRIL_INITIAL_STACK_PAGES_NO
    49 #define FIBRIL_INITIAL_STACK_PAGES_NO   1
     50        #define FIBRIL_INITIAL_STACK_PAGES_NO  1
    5051#endif
    5152
    5253/**
    53  * This futex serializes access to ready_list, serialized_list and manager_list.
    54  */
     54 * This futex serializes access to ready_list,
     55 * serialized_list and manager_list.
     56 */
    5557static atomic_t fibril_futex = FUTEX_INITIALIZER;
    5658
     
    5961static LIST_INITIALIZE(manager_list);
    6062
    61 static void fibril_main(void);
    62 
    6363/** Number of threads that are executing a manager fibril. */
    6464static int threads_in_manager;
    65 /** Number of threads that are executing a manager fibril and are serialized. */
    66 static int serialized_threads;  /* Protected by async_futex */
     65
     66/**
     67 * Number of threads that are executing a manager fibril
     68 * and are serialized. Protected by async_futex.
     69 */
     70static int serialized_threads;
     71
    6772/** Fibril-local count of serialization. If > 0, we must not preempt */
    6873static fibril_local int serialization_count;
    69 
    70 /** Setup fibril information into TCB structure */
    71 fibril_t *fibril_setup(void)
    72 {
    73         fibril_t *f;
    74         tcb_t *tcb;
    75 
    76         tcb = __make_tls();
    77         if (!tcb)
    78                 return NULL;
    79 
    80         f = malloc(sizeof(fibril_t));
    81         if (!f) {
    82                 __free_tls(tcb);
    83                 return NULL;
    84         }
    85 
    86         tcb->fibril_data = f;
    87         f->tcb = tcb;
    88 
    89         f->func = NULL;
    90         f->arg = NULL;
    91         f->stack = NULL;
    92         f->clean_after_me = NULL;
    93         f->retval = 0;
    94         f->flags = 0;
    95 
    96         return f;
    97 }
    98 
    99 void fibril_teardown(fibril_t *f)
    100 {
    101         __free_tls(f->tcb);
    102         free(f);
    103 }
    10474
    10575/** Function that spans the whole life-cycle of a fibril.
     
    10878 * the fibril logic is called.  After its return, the return value is saved.
    10979 * The fibril then switches to another fibril, which cleans up after it.
    110  */
    111 void fibril_main(void)
    112 {
    113         fibril_t *f = __tcb_get()->fibril_data;
    114 
     80 *
     81 */
     82static void fibril_main(void)
     83{
     84        fibril_t *fibril = __tcb_get()->fibril_data;
     85       
    11586        /* Call the implementing function. */
    116         f->retval = f->func(f->arg);
    117 
     87        fibril->retval = fibril->func(fibril->arg);
     88       
    11889        fibril_switch(FIBRIL_FROM_DEAD);
    119         /* not reached */
     90        /* Not reached */
     91}
     92
     93/** Setup fibril information into TCB structure
     94 *
     95 */
     96fibril_t *fibril_setup(void)
     97{
     98        tcb_t *tcb = __make_tls();
     99        if (!tcb)
     100                return NULL;
     101       
     102        fibril_t *fibril = malloc(sizeof(fibril_t));
     103        if (!fibril) {
     104                __free_tls(tcb);
     105                return NULL;
     106        }
     107       
     108        tcb->fibril_data = fibril;
     109        fibril->tcb = tcb;
     110       
     111        fibril->func = NULL;
     112        fibril->arg = NULL;
     113        fibril->stack = NULL;
     114        fibril->clean_after_me = NULL;
     115        fibril->retval = 0;
     116        fibril->flags = 0;
     117       
     118        return fibril;
     119}
     120
     121void fibril_teardown(fibril_t *fibril)
     122{
     123        __free_tls(fibril->tcb);
     124        free(fibril);
    120125}
    121126
     
    125130 * held.
    126131 *
    127  * @param stype         Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
    128  *                      FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter
    129  *                      describes the circumstances of the switch.
    130  * @return              Return 0 if there is no ready fibril,
    131  *                      return 1 otherwise.
     132 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
     133 *              FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter
     134 *              describes the circumstances of the switch.
     135 *
     136 * @return 0 if there is no ready fibril,
     137 * @return 1 otherwise.
     138 *
    132139 */
    133140int fibril_switch(fibril_switch_type_t stype)
    134141{
    135         fibril_t *srcf, *dstf;
    136142        int retval = 0;
    137143       
    138144        futex_down(&fibril_futex);
    139 
     145       
    140146        if (stype == FIBRIL_PREEMPT && list_empty(&ready_list))
    141147                goto ret_0;
    142 
     148       
    143149        if (stype == FIBRIL_FROM_MANAGER) {
    144                 if (list_empty(&ready_list) && list_empty(&serialized_list))
     150                if ((list_empty(&ready_list)) && (list_empty(&serialized_list)))
    145151                        goto ret_0;
     152               
    146153                /*
    147154                 * Do not preempt if there is not enough threads to run the
    148155                 * ready fibrils which are not serialized.
    149156                 */
    150                 if (list_empty(&serialized_list) &&
    151                     threads_in_manager <= serialized_threads) {
     157                if ((list_empty(&serialized_list)) &&
     158                    (threads_in_manager <= serialized_threads)) {
    152159                        goto ret_0;
    153160                }
    154161        }
     162       
    155163        /* If we are going to manager and none exists, create it */
    156         if (stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) {
     164        if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
    157165                while (list_empty(&manager_list)) {
    158166                        futex_up(&fibril_futex);
     
    162170        }
    163171       
    164         srcf = __tcb_get()->fibril_data;
     172        fibril_t *srcf = __tcb_get()->fibril_data;
    165173        if (stype != FIBRIL_FROM_DEAD) {
     174               
    166175                /* Save current state */
    167176                if (!context_save(&srcf->ctx)) {
    168177                        if (serialization_count)
    169178                                srcf->flags &= ~FIBRIL_SERIALIZED;
     179                       
    170180                        if (srcf->clean_after_me) {
    171181                                /*
     
    173183                                 * restored context here.
    174184                                 */
    175                                 void *stack = srcf->clean_after_me->stack; 
     185                                void *stack = srcf->clean_after_me->stack;
    176186                                if (stack) {
    177187                                        /*
     
    188198                                srcf->clean_after_me = NULL;
    189199                        }
     200                       
    190201                        return 1;       /* futex_up already done here */
    191202                }
    192 
     203               
    193204                /* Save myself to the correct run list */
    194205                if (stype == FIBRIL_PREEMPT)
     
    197208                        list_append(&srcf->link, &manager_list);
    198209                        threads_in_manager--;
    199                 } else {       
     210                } else {
    200211                        /*
    201212                         * If stype == FIBRIL_TO_MANAGER, don't put ourselves to
     
    207218       
    208219        /* Choose a new fibril to run */
    209         if (stype == FIBRIL_TO_MANAGER || stype == FIBRIL_FROM_DEAD) {
     220        fibril_t *dstf;
     221        if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
    210222                dstf = list_get_instance(manager_list.next, fibril_t, link);
    211223                if (serialization_count && stype == FIBRIL_TO_MANAGER) {
     
    214226                }
    215227                threads_in_manager++;
    216 
     228               
    217229                if (stype == FIBRIL_FROM_DEAD)
    218230                        dstf->clean_after_me = srcf;
     
    228240        }
    229241        list_remove(&dstf->link);
    230 
     242       
    231243        futex_up(&fibril_futex);
    232244        context_restore(&dstf->ctx);
    233245        /* not reached */
    234 
     246       
    235247ret_0:
    236248        futex_up(&fibril_futex);
     
    240252/** Create a new fibril.
    241253 *
    242  * @param func          Implementing function of the new fibril.
    243  * @param arg           Argument to pass to func.
    244  *
    245  * @return              Return 0 on failure or TLS of the new fibril.
     254 * @param func Implementing function of the new fibril.
     255 * @param arg Argument to pass to func.
     256 *
     257 * @return 0 on failure or TLS of the new fibril.
     258 *
    246259 */
    247260fid_t fibril_create(int (*func)(void *), void *arg)
    248261{
    249         fibril_t *f;
    250 
    251         f = fibril_setup();
    252         if (!f)
     262        fibril_t *fibril;
     263       
     264        fibril = fibril_setup();
     265        if (fibril == NULL)
    253266                return 0;
    254         f->stack = (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO *
    255             getpagesize());
    256         if (!f->stack) {
    257                 fibril_teardown(f);
     267       
     268        fibril->stack =
     269            (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize());
     270        if (!fibril->stack) {
     271                fibril_teardown(fibril);
    258272                return 0;
    259273        }
    260274       
    261         f->func = func;
    262         f->arg = arg;
    263 
    264         context_save(&f->ctx);
    265         context_set(&f->ctx, FADDR(fibril_main), f->stack,
    266             FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), f->tcb);
    267 
    268         return (fid_t) f;
     275        fibril->func = func;
     276        fibril->arg = arg;
     277       
     278        context_save(&fibril->ctx);
     279        context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack,
     280            FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), fibril->tcb);
     281
     282        return (fid_t) fibril;
    269283}
    270284
    271285/** Add a fibril to the ready list.
    272286 *
    273  * @param fid           Pointer to the fibril structure of the fibril to be
    274  *                      added.
     287 * @param fid Pointer to the fibril structure of the fibril to be
     288 *            added.
     289 *
    275290 */
    276291void fibril_add_ready(fid_t fid)
    277292{
    278         fibril_t *f;
    279 
    280         f = (fibril_t *) fid;
     293        fibril_t *fibril = (fibril_t *) fid;
     294       
    281295        futex_down(&fibril_futex);
    282         if ((f->flags & FIBRIL_SERIALIZED))
    283                 list_append(&f->link, &serialized_list);
     296       
     297        if ((fibril->flags & FIBRIL_SERIALIZED))
     298                list_append(&fibril->link, &serialized_list);
    284299        else
    285                 list_append(&f->link, &ready_list);
     300                list_append(&fibril->link, &ready_list);
     301       
    286302        futex_up(&fibril_futex);
    287303}
     
    289305/** Add a fibril to the manager list.
    290306 *
    291  * @param fid           Pointer to the fibril structure of the fibril to be
    292  *                      added.
     307 * @param fid Pointer to the fibril structure of the fibril to be
     308 *            added.
     309 *
    293310 */
    294311void fibril_add_manager(fid_t fid)
    295312{
    296         fibril_t *f;
    297 
    298         f = (fibril_t *) fid;
    299 
     313        fibril_t *fibril = (fibril_t *) fid;
     314       
    300315        futex_down(&fibril_futex);
    301         list_append(&f->link, &manager_list);
     316        list_append(&fibril->link, &manager_list);
    302317        futex_up(&fibril_futex);
    303318}
     
    307322{
    308323        futex_down(&fibril_futex);
    309         if (list_empty(&manager_list)) {
    310                 futex_up(&fibril_futex);
    311                 return;
    312         }
    313         list_remove(manager_list.next);
     324       
     325        if (!list_empty(&manager_list))
     326                list_remove(manager_list.next);
     327       
    314328        futex_up(&fibril_futex);
    315329}
  • uspace/lib/c/generic/futex.c

    rcf8cc36 rc47e1a8  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <futex.h>
     
    4040/** Initialize futex counter.
    4141 *
    42  * @param futex         Futex.
    43  * @param val           Initialization value.
     42 * @param futex Futex.
     43 * @param val   Initialization value.
     44 *
    4445 */
    4546void futex_initialize(futex_t *futex, int val)
     
    5051/** Try to down the futex.
    5152 *
    52  * @param futex         Futex.
    53  * @return              Non-zero if the futex was acquired.
    54  * @return              Zero if the futex was not acquired.
     53 * @param futex Futex.
     54 *
     55 * @return Non-zero if the futex was acquired.
     56 * @return Zero if the futex was not acquired.
     57 *
    5558 */
    5659int futex_trydown(futex_t *futex)
     
    6164/** Down the futex.
    6265 *
    63  * @param futex         Futex.
    64  * @return              ENOENT if there is no such virtual address.
    65  * @return              Zero in the uncontended case.
    66  * @return              Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
     66 * @param futex Futex.
     67 *
     68 * @return ENOENT if there is no such virtual address.
     69 * @return Zero in the uncontended case.
     70 * @return Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
     71 *
    6772 */
    6873int futex_down(futex_t *futex)
    6974{
    70         if (atomic_predec(futex) < 0)
     75        if ((atomic_signed_t) atomic_predec(futex) < 0)
    7176                return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
    72 
     77       
    7378        return 0;
    7479}
     
    7681/** Up the futex.
    7782 *
    78  * @param futex         Futex.
    79  * @return              ENOENT if there is no such virtual address.
    80  * @return              Zero in the uncontended case.
     83 * @param futex Futex.
     84 *
     85 * @return ENOENT if there is no such virtual address.
     86 * @return Zero in the uncontended case.
     87 *
    8188 */
    8289int futex_up(futex_t *futex)
    8390{
    84         if (atomic_postinc(futex) < 0)
     91        if ((atomic_signed_t) atomic_postinc(futex) < 0)
    8592                return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
    86                
     93       
    8794        return 0;
    8895}
  • uspace/lib/c/generic/getopt.c

    rcf8cc36 rc47e1a8  
    3838#include <getopt.h>
    3939#include <stdlib.h>
    40 #include <string.h>
     40#include <str.h>
    4141
    4242/* HelenOS Port : We're incorporating only the modern getopt_long with wrappers
  • uspace/lib/c/generic/io/asprintf.c

    rcf8cc36 rc47e1a8  
    3737#include <stdio.h>
    3838#include <stdlib.h>
    39 #include <string.h>
     39#include <str.h>
    4040#include <io/printf_core.h>
    4141
     
    6161int asprintf(char **strp, const char *fmt, ...)
    6262{
    63         struct printf_spec ps = {
     63        printf_spec_t ps = {
    6464                asprintf_str_write,
    6565                asprintf_wstr_write,
  • uspace/lib/c/generic/io/console.c

    rcf8cc36 rc47e1a8  
    4545}
    4646
    47 int console_get_size(int phone, int *cols, int *rows)
     47int console_get_size(int phone, ipcarg_t *cols, ipcarg_t *rows)
    4848{
    49         ipcarg_t cols_v;
    50         ipcarg_t rows_v;
    51         int rc;
    52 
    53         rc = async_req_0_2(phone, CONSOLE_GET_SIZE, &cols_v, &rows_v);
    54 
    55         *cols = (int) cols_v;
    56         *rows = (int) rows_v;
    57         return rc;
     49        return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows);
    5850}
    5951
    60 void console_set_style(int phone, int style)
     52void console_set_style(int phone, uint8_t style)
    6153{
    6254        async_msg_1(phone, CONSOLE_SET_STYLE, style);
    6355}
    6456
    65 void console_set_color(int phone, int fg_color, int bg_color, int flags)
     57void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color,
     58    uint8_t flags)
    6659{
    6760        async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
    6861}
    6962
    70 void console_set_rgb_color(int phone, int fg_color, int bg_color)
     63void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color)
    7164{
    7265        async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
     
    7568void console_cursor_visibility(int phone, bool show)
    7669{
    77         async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
     70        async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false));
    7871}
    7972
    80 int console_get_color_cap(int phone, int *ccap)
     73int console_get_color_cap(int phone, ipcarg_t *ccap)
    8174{
    82         ipcarg_t ccap_tmp;
    83         int rc;
    84 
    85         rc = async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, &ccap_tmp);
    86         *ccap = ccap_tmp;
    87 
    88         return rc;
     75        return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap);
    8976}
    9077
     
    9481}
    9582
    96 int console_get_pos(int phone, int *col, int *row)
     83int console_get_pos(int phone, ipcarg_t *col, ipcarg_t *row)
    9784{
    98         ipcarg_t col_v;
    99         ipcarg_t row_v;
    100         int rc;
    101 
    102         rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v);
    103 
    104         *col = (int) col_v;
    105         *row = (int) row_v;
    106         return rc;
     85        return async_req_0_2(phone, CONSOLE_GET_POS, col, row);
    10786}
    10887
    109 void console_goto(int phone, int col, int row)
     88void console_set_pos(int phone, ipcarg_t col, ipcarg_t row)
    11089{
    11190        async_msg_2(phone, CONSOLE_GOTO, col, row);
  • uspace/lib/c/generic/io/io.c

    rcf8cc36 rc47e1a8  
    3737#include <fcntl.h>
    3838#include <assert.h>
    39 #include <string.h>
     39#include <str.h>
    4040#include <errno.h>
    4141#include <bool.h>
     
    4646#include <adt/list.h>
    4747
     48static void _ffillbuf(FILE *stream);
    4849static void _fflushbuf(FILE *stream);
    4950
     
    5758        .buf = NULL,
    5859        .buf_size = 0,
    59         .buf_head = NULL
     60        .buf_head = NULL,
     61        .buf_tail = NULL,
     62        .buf_state = _bs_empty
    6063};
    6164
     
    6972        .buf = NULL,
    7073        .buf_size = BUFSIZ,
    71         .buf_head = NULL
     74        .buf_head = NULL,
     75        .buf_tail = NULL,
     76        .buf_state = _bs_empty
    7277};
    7378
     
    8186        .buf = NULL,
    8287        .buf_size = 0,
    83         .buf_head = NULL
     88        .buf_head = NULL,
     89        .buf_tail = NULL,
     90        .buf_state = _bs_empty
    8491};
    8592
     
    179186        stream->buf_size = size;
    180187        stream->buf_head = stream->buf;
     188        stream->buf_tail = stream->buf;
     189        stream->buf_state = _bs_empty;
    181190}
    182191
     
    210219       
    211220        stream->buf_head = stream->buf;
     221        stream->buf_tail = stream->buf;
    212222        return 0;
    213223}
     
    243253        stream->klog = false;
    244254        stream->phone = -1;
     255        stream->need_sync = false;
    245256        _setvbuf(stream);
    246257       
     
    264275        stream->klog = false;
    265276        stream->phone = -1;
     277        stream->need_sync = false;
    266278        _setvbuf(stream);
    267279       
     
    295307        stream->klog = false;
    296308        stream->phone = -1;
     309        stream->need_sync = false;
    297310        _setvbuf(stream);
    298311       
     
    331344}
    332345
    333 /** Read from a stream.
     346/** Read from a stream (unbuffered).
    334347 *
    335348 * @param buf    Destination buffer.
     
    337350 * @param nmemb  Number of records to read.
    338351 * @param stream Pointer to the stream.
    339  *
    340  */
    341 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
     352 */
     353static size_t _fread(void *buf, size_t size, size_t nmemb, FILE *stream)
    342354{
    343355        size_t left, done;
     
    345357        if (size == 0 || nmemb == 0)
    346358                return 0;
    347 
    348         /* Make sure no data is pending write. */
    349         _fflushbuf(stream);
    350359
    351360        left = size * nmemb;
     
    368377}
    369378
     379/** Write to a stream (unbuffered).
     380 *
     381 * @param buf    Source buffer.
     382 * @param size   Size of each record.
     383 * @param nmemb  Number of records to write.
     384 * @param stream Pointer to the stream.
     385 */
    370386static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
    371387{
     
    394410                }
    395411        }
     412
     413        if (done > 0)
     414                stream->need_sync = true;
    396415       
    397416        return (done / size);
    398417}
    399418
    400 /** Drain stream buffer, do not sync stream. */
     419/** Read some data in stream buffer. */
     420static void _ffillbuf(FILE *stream)
     421{
     422        ssize_t rc;
     423
     424        stream->buf_head = stream->buf_tail = stream->buf;
     425
     426        rc = read(stream->fd, stream->buf, stream->buf_size);
     427        if (rc < 0) {
     428                stream->error = true;
     429                return;
     430        }
     431
     432        if (rc == 0) {
     433                stream->eof = true;
     434                return;
     435        }
     436
     437        stream->buf_head += rc;
     438        stream->buf_state = _bs_read;
     439}
     440
     441/** Write out stream buffer, do not sync stream. */
    401442static void _fflushbuf(FILE *stream)
    402443{
    403444        size_t bytes_used;
    404        
     445
    405446        if ((!stream->buf) || (stream->btype == _IONBF) || (stream->error))
    406447                return;
    407        
    408         bytes_used = stream->buf_head - stream->buf;
     448
     449        bytes_used = stream->buf_head - stream->buf_tail;
    409450        if (bytes_used == 0)
    410451                return;
    411        
    412         (void) _fwrite(stream->buf, 1, bytes_used, stream);
     452
     453        /* If buffer has prefetched read data, we need to seek back. */
     454        if (stream->buf_state == _bs_read)
     455                lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR);
     456
     457        /* If buffer has unwritten data, we need to write them out. */
     458        if (stream->buf_state == _bs_write)
     459                (void) _fwrite(stream->buf_tail, 1, bytes_used, stream);
     460
    413461        stream->buf_head = stream->buf;
    414 }
     462        stream->buf_tail = stream->buf;
     463        stream->buf_state = _bs_empty;
     464}
     465
     466/** Read from a stream.
     467 *
     468 * @param dest   Destination buffer.
     469 * @param size   Size of each record.
     470 * @param nmemb  Number of records to read.
     471 * @param stream Pointer to the stream.
     472 *
     473 */
     474size_t fread(void *dest, size_t size, size_t nmemb, FILE *stream)
     475{
     476        uint8_t *dp;
     477        size_t bytes_left;
     478        size_t now;
     479        size_t data_avail;
     480        size_t total_read;
     481        size_t i;
     482
     483        if (size == 0 || nmemb == 0)
     484                return 0;
     485
     486        /* If not buffered stream, read in directly. */
     487        if (stream->btype == _IONBF) {
     488                now = _fread(dest, size, nmemb, stream);
     489                return now;
     490        }
     491
     492        /* Make sure no data is pending write. */
     493        if (stream->buf_state == _bs_write)
     494                _fflushbuf(stream);
     495
     496        /* Perform lazy allocation of stream buffer. */
     497        if (stream->buf == NULL) {
     498                if (_fallocbuf(stream) != 0)
     499                        return 0; /* Errno set by _fallocbuf(). */
     500        }
     501
     502        bytes_left = size * nmemb;
     503        total_read = 0;
     504        dp = (uint8_t *) dest;
     505
     506        while ((!stream->error) && (!stream->eof) && (bytes_left > 0)) {
     507                if (stream->buf_head == stream->buf_tail)
     508                        _ffillbuf(stream);
     509
     510                if (stream->error || stream->eof)
     511                        break;
     512
     513                data_avail = stream->buf_head - stream->buf_tail;
     514
     515                if (bytes_left > data_avail)
     516                        now = data_avail;
     517                else
     518                        now = bytes_left;
     519
     520                for (i = 0; i < now; i++) {
     521                        dp[i] = stream->buf_tail[i];
     522                }
     523
     524                dp += now;
     525                stream->buf_tail += now;
     526                bytes_left -= now;
     527                total_read += now;
     528        }
     529
     530        return (total_read / size);
     531}
     532
    415533
    416534/** Write to a stream.
     
    442560                return now;
    443561        }
    444        
     562
     563        /* Make sure buffer contains no prefetched data. */
     564        if (stream->buf_state == _bs_read)
     565                _fflushbuf(stream);
     566
     567
    445568        /* Perform lazy allocation of stream buffer. */
    446569        if (stream->buf == NULL) {
     
    482605        }
    483606       
     607        if (total_written > 0)
     608                stream->buf_state = _bs_write;
     609
    484610        if (need_flush)
    485611                fflush(stream);
     
    536662}
    537663
     664char *fgets(char *str, int size, FILE *stream)
     665{
     666        int c;
     667        int idx;
     668
     669        idx = 0;
     670        while (idx < size - 1) {
     671                c = fgetc(stream);
     672                if (c == EOF)
     673                        break;
     674
     675                str[idx++] = c;
     676
     677                if (c == '\n')
     678                        break;
     679        }
     680
     681        if (ferror(stream))
     682                return NULL;
     683
     684        if (idx == 0)
     685                return NULL;
     686
     687        str[idx] = '\0';
     688        return str;
     689}
     690
    538691int getchar(void)
    539692{
     
    541694}
    542695
    543 int fseek(FILE *stream, long offset, int origin)
    544 {
    545         off_t rc = lseek(stream->fd, offset, origin);
    546         if (rc == (off_t) (-1)) {
    547                 /* errno has been set by lseek. */
     696int fseek(FILE *stream, off64_t offset, int whence)
     697{
     698        off64_t rc;
     699
     700        _fflushbuf(stream);
     701
     702        rc = lseek(stream->fd, offset, whence);
     703        if (rc == (off64_t) (-1)) {
     704                /* errno has been set by lseek64. */
    548705                return -1;
    549706        }
    550        
     707
    551708        stream->eof = false;
    552        
    553709        return 0;
    554710}
    555711
    556 int ftell(FILE *stream)
    557 {
    558         off_t rc = lseek(stream->fd, 0, SEEK_CUR);
    559         if (rc == (off_t) (-1)) {
    560                 /* errno has been set by lseek. */
    561                 return -1;
    562         }
    563 
    564         return rc;
     712off64_t ftell(FILE *stream)
     713{
     714        return lseek(stream->fd, 0, SEEK_CUR);
    565715}
    566716
     
    579729        }
    580730       
    581         if (stream->fd >= 0)
     731        if (stream->fd >= 0 && stream->need_sync) {
     732                /**
     733                 * Better than syncing always, but probably still not the
     734                 * right thing to do.
     735                 */
     736                stream->need_sync = false;
    582737                return fsync(stream->fd);
     738        }
    583739       
    584740        return ENOENT;
  • uspace/lib/c/generic/io/klog.c

    rcf8cc36 rc47e1a8  
    3535
    3636#include <libc.h>
    37 #include <string.h>
     37#include <str.h>
    3838#include <sys/types.h>
    3939#include <unistd.h>
  • uspace/lib/c/generic/io/printf_core.c

    rcf8cc36 rc47e1a8  
    4141#include <io/printf_core.h>
    4242#include <ctype.h>
    43 #include <string.h>
     43#include <str.h>
    4444
    4545/** show prefixes 0x or 0 */
    4646#define __PRINTF_FLAG_PREFIX       0x00000001
     47
    4748/** signed / unsigned number */
    4849#define __PRINTF_FLAG_SIGNED       0x00000002
     50
    4951/** print leading zeroes */
    5052#define __PRINTF_FLAG_ZEROPADDED   0x00000004
     53
    5154/** align to left */
    5255#define __PRINTF_FLAG_LEFTALIGNED  0x00000010
     56
    5357/** always show + sign */
    5458#define __PRINTF_FLAG_SHOWPLUS     0x00000020
     59
    5560/** print space instead of plus */
    5661#define __PRINTF_FLAG_SPACESIGN    0x00000040
     62
    5763/** show big characters */
    5864#define __PRINTF_FLAG_BIGCHARS     0x00000080
     65
    5966/** number has - sign */
    6067#define __PRINTF_FLAG_NEGATIVE     0x00000100
     
    7885} qualifier_t;
    7986
    80 static char nullstr[] = "(NULL)";
    81 static char digits_small[] = "0123456789abcdef";
    82 static char digits_big[] = "0123456789ABCDEF";
    83 static char invalch = U_SPECIAL;
     87static const char *nullstr = "(NULL)";
     88static const char *digits_small = "0123456789abcdef";
     89static const char *digits_big = "0123456789ABCDEF";
     90static const char invalch = U_SPECIAL;
    8491
    8592/** Print one or more characters without adding newline.
     
    253260        if (str == NULL)
    254261                return printf_putstr(nullstr, ps);
    255 
     262       
    256263        /* Print leading spaces. */
    257264        size_t strw = str_length(str);
    258265        if (precision == 0)
    259266                precision = strw;
    260 
     267       
    261268        /* Left padding */
    262269        size_t counter = 0;
     
    268275                }
    269276        }
    270 
     277       
    271278        /* Part of @a str fitting into the alloted space. */
    272279        int retval;
     
    350357    uint32_t flags, printf_spec_t *ps)
    351358{
    352         char *digits;
     359        const char *digits;
    353360        if (flags & __PRINTF_FLAG_BIGCHARS)
    354361                digits = digits_big;
     
    383390         */
    384391        if (flags & __PRINTF_FLAG_PREFIX) {
    385                 switch(base) {
     392                switch (base) {
    386393                case 2:
    387394                        /* Binary formating is not standard, but usefull */
     
    447454        /* Print prefix */
    448455        if (flags & __PRINTF_FLAG_PREFIX) {
    449                 switch(base) {
     456                switch (base) {
    450457                case 2:
    451458                        /* Binary formating is not standard, but usefull */
     
    562569 *
    563570 *  - P, p Print value of a pointer. Void * value is expected and it is
    564  *         printed in hexadecimal notation with prefix (as with \%#X / \%#x
    565  *         for 32-bit or \%#X / \%#x for 64-bit long pointers).
     571 *         printed in hexadecimal notation with prefix (as with
     572 *         \%#0.8X / \%#0.8x for 32-bit or \%#0.16lX / \%#0.16lx for 64-bit
     573 *         long pointers).
    566574 *
    567575 *  - b Print value as unsigned binary number. Prefix is not printed by
     
    776784                        case 'p':
    777785                                flags |= __PRINTF_FLAG_PREFIX;
     786                                flags |= __PRINTF_FLAG_ZEROPADDED;
    778787                                base = 16;
    779788                                qualifier = PrintfQualifierPointer;
     
    838847                        case PrintfQualifierPointer:
    839848                                size = sizeof(void *);
    840                                 number = (uint64_t) (unsigned long) va_arg(ap, void *);
     849                                precision = size << 1;
     850                                number = (uint64_t) (uintptr_t) va_arg(ap, void *);
    841851                                break;
    842852                        default:
  • uspace/lib/c/generic/io/screenbuffer.c

    rcf8cc36 rc47e1a8  
    3434
    3535#include <io/style.h>
     36#include <io/screenbuffer.h>
    3637#include <malloc.h>
    3738#include <unistd.h>
    38 #include "screenbuffer.h"
    3939
    4040/** Store one character to screenbuffer.
     
    6767 *
    6868 */
    69 screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, size_t size_x, size_t size_y)
     69screenbuffer_t *screenbuffer_init(screenbuffer_t *scr, ipcarg_t size_x,
     70    ipcarg_t size_y)
    7071{
    7172        scr->buffer = (keyfield_t *) malloc(sizeof(keyfield_t) * size_x * size_y);
     
    109110 *
    110111 */
    111 void screenbuffer_clear_line(screenbuffer_t *scr, size_t line)
     112void screenbuffer_clear_line(screenbuffer_t *scr, ipcarg_t line)
    112113{
    113         size_t x;
     114        ipcarg_t x;
    114115       
    115116        for (x = 0; x < scr->size_x; x++) {
     
    140141 *
    141142 */
    142 void screenbuffer_goto(screenbuffer_t *scr, size_t x, size_t y)
     143void screenbuffer_goto(screenbuffer_t *scr, ipcarg_t x, ipcarg_t y)
    143144{
    144145        scr->position_x = x % scr->size_x;
     
    166167 *
    167168 */
    168 void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color, uint8_t bg_color, uint8_t flags)
     169void screenbuffer_set_color(screenbuffer_t *scr, uint8_t fg_color,
     170    uint8_t bg_color, uint8_t flags)
    169171{
    170172        scr->attrs.t = at_idx;
     
    181183 *
    182184 */
    183 void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color, uint32_t bg_color)
     185void screenbuffer_set_rgb_color(screenbuffer_t *scr, uint32_t fg_color,
     186    uint32_t bg_color)
    184187{
    185188        scr->attrs.t = at_rgb;
  • uspace/lib/c/generic/io/vprintf.c

    rcf8cc36 rc47e1a8  
    3939#include <futex.h>
    4040#include <async.h>
    41 #include <string.h>
     41#include <str.h>
    4242
    4343static atomic_t printf_futex = FUTEX_INITIALIZER;
     
    7676int vfprintf(FILE *stream, const char *fmt, va_list ap)
    7777{
    78         struct printf_spec ps = {
     78        printf_spec_t ps = {
    7979                vprintf_str_write,
    8080                vprintf_wstr_write,
  • uspace/lib/c/generic/io/vsnprintf.c

    rcf8cc36 rc47e1a8  
    3535#include <stdarg.h>
    3636#include <stdio.h>
    37 #include <string.h>
     37#include <str.h>
    3838#include <io/printf_core.h>
    3939#include <errno.h>
  • uspace/lib/c/generic/ipc.c

    rcf8cc36 rc47e1a8  
    728728    int *flags)
    729729{
    730         int res;
    731         sysarg_t tmp_flags;
    732         res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
     730        sysarg_t tmp_flags = 0;
     731        int res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
    733732            (ipcarg_t) size, arg, NULL, &tmp_flags);
     733       
    734734        if (flags)
    735735                *flags = tmp_flags;
     736       
    736737        return res;
    737738}
  • uspace/lib/c/generic/libc.c

    rcf8cc36 rc47e1a8  
    6262void __main(void *pcb_ptr)
    6363{
    64         int retval;
    65 
     64        /* Initialize user task run-time environment */
    6665        __heap_init();
    6766        __async_init();
     
    7574        char **argv;
    7675       
     76        /* Get command line arguments and initialize
     77           standard input and output */
    7778        if (__pcb == NULL) {
    7879                argc = 0;
     
    8687        }
    8788       
    88         retval = main(argc, argv);
    89 
    90         __stdio_done();
    91         (void) task_retval(retval);
     89        /* Run main() and set task return value
     90           according the result */
     91        (void) task_retval(main(argc, argv));
    9292}
    9393
    9494void __exit(void)
    9595{
     96        __stdio_done();
    9697        fibril_teardown(__tcb_get()->fibril_data);
    9798        _exit(0);
  • uspace/lib/c/generic/loader.c

    rcf8cc36 rc47e1a8  
    3838#include <libc.h>
    3939#include <task.h>
    40 #include <string.h>
     40#include <str.h>
    4141#include <stdlib.h>
    4242#include <async.h>
     
    183183 *
    184184 */
    185 int loader_set_args(loader_t *ldr, char *const argv[])
     185int loader_set_args(loader_t *ldr, const char *const argv[])
    186186{
    187187        /*
     
    189189         * compute size of the buffer needed.
    190190         */
    191         char *const *ap = argv;
     191        const char *const *ap = argv;
    192192        size_t buffer_size = 0;
    193193        while (*ap != NULL) {
  • uspace/lib/c/generic/malloc.c

    rcf8cc36 rc47e1a8  
    4343#include <bitops.h>
    4444#include <mem.h>
     45#include <futex.h>
    4546#include <adt/gcdlcm.h>
    4647
     
    7576#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
    7677
    77 
    7878/** Header of a heap block
    7979 *
     
    104104extern char _heap;
    105105
     106/** Futex for thread-safe heap manipulation */
     107static futex_t malloc_futex = FUTEX_INITIALIZER;
     108
    106109/** Address of heap start */
    107110static void *heap_start = 0;
     
    119122 *
    120123 * Fills in the structures related to a heap block.
     124 * Should be called only inside the critical section.
    121125 *
    122126 * @param addr Address of the block.
     
    144148 * Verifies that the structures related to a heap block still contain
    145149 * the magic constants. This helps detect heap corruption early on.
     150 * Should be called only inside the critical section.
    146151 *
    147152 * @param addr Address of the block.
     
    161166}
    162167
     168/** Increase the heap area size
     169 *
     170 * Should be called only inside the critical section.
     171 *
     172 * @param size Number of bytes to grow the heap by.
     173 *
     174 */
    163175static bool grow_heap(size_t size)
    164176{
    165177        if (size == 0)
     178                return false;
     179
     180        if ((heap_start + size < heap_start) || (heap_end + size < heap_end))
    166181                return false;
    167182       
     
    186201}
    187202
     203/** Decrease the heap area
     204 *
     205 * Should be called only inside the critical section.
     206 *
     207 * @param size Number of bytes to shrink the heap by.
     208 *
     209 */
    188210static void shrink_heap(void)
    189211{
     
    193215/** Initialize the heap allocator
    194216 *
    195  * Finds how much physical memory we have and creates
     217 * Find how much physical memory we have and create
    196218 * the heap management structures that mark the whole
    197219 * physical memory as a single free block.
     
    200222void __heap_init(void)
    201223{
     224        futex_down(&malloc_futex);
     225       
    202226        if (as_area_create((void *) &_heap, PAGE_SIZE,
    203227            AS_AREA_WRITE | AS_AREA_READ)) {
     
    210234                block_init(heap_start, heap_end - heap_start, true);
    211235        }
    212 }
    213 
     236       
     237        futex_up(&malloc_futex);
     238}
     239
     240/** Get maximum heap address
     241 *
     242 */
    214243uintptr_t get_max_heap_addr(void)
    215244{
     245        futex_down(&malloc_futex);
     246       
    216247        if (max_heap_size == (size_t) -1)
    217248                max_heap_size =
    218249                    max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
    219250       
    220         return ((uintptr_t) heap_start + max_heap_size);
    221 }
    222 
     251        uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size;
     252       
     253        futex_up(&malloc_futex);
     254       
     255        return max_heap_addr;
     256}
     257
     258/** Split heap block and mark it as used.
     259 *
     260 * Should be called only inside the critical section.
     261 *
     262 * @param cur  Heap block to split.
     263 * @param size Number of bytes to split and mark from the beginning
     264 *             of the block.
     265 *
     266 */
    223267static void split_mark(heap_block_head_t *cur, const size_t size)
    224268{
     
    240284
    241285/** Allocate a memory block
     286 *
     287 * Should be called only inside the critical section.
    242288 *
    243289 * @param size  The size of the block to allocate.
     
    353399}
    354400
     401/** Allocate memory by number of elements
     402 *
     403 * @param nmemb Number of members to allocate.
     404 * @param size  Size of one member in bytes.
     405 *
     406 * @return Allocated memory or NULL.
     407 *
     408 */
    355409void *calloc(const size_t nmemb, const size_t size)
    356410{
     
    358412        if (block == NULL)
    359413                return NULL;
    360 
     414       
    361415        memset(block, 0, nmemb * size);
    362416        return block;
    363417}
    364418
     419/** Allocate memory
     420 *
     421 * @param size Number of bytes to allocate.
     422 *
     423 * @return Allocated memory or NULL.
     424 *
     425 */
    365426void *malloc(const size_t size)
    366427{
    367         return malloc_internal(size, BASE_ALIGN);
    368 }
    369 
     428        futex_down(&malloc_futex);
     429        void *block = malloc_internal(size, BASE_ALIGN);
     430        futex_up(&malloc_futex);
     431       
     432        return block;
     433}
     434
     435/** Allocate memory with specified alignment
     436 *
     437 * @param align Alignment in byes.
     438 * @param size  Number of bytes to allocate.
     439 *
     440 * @return Allocated memory or NULL.
     441 *
     442 */
    370443void *memalign(const size_t align, const size_t size)
    371444{
     
    376449            1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
    377450       
    378         return malloc_internal(size, palign);
    379 }
    380 
     451        futex_down(&malloc_futex);
     452        void *block = malloc_internal(size, palign);
     453        futex_up(&malloc_futex);
     454       
     455        return block;
     456}
     457
     458/** Reallocate memory block
     459 *
     460 * @param addr Already allocated memory or NULL.
     461 * @param size New size of the memory block.
     462 *
     463 * @return Reallocated memory or NULL.
     464 *
     465 */
    381466void *realloc(const void *addr, const size_t size)
    382467{
    383468        if (addr == NULL)
    384469                return malloc(size);
     470       
     471        futex_down(&malloc_futex);
    385472       
    386473        /* Calculate the position of the header. */
     
    395482       
    396483        void *ptr = NULL;
     484        bool reloc = false;
    397485        size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN));
    398486        size_t orig_size = head->size;
     
    412500        } else {
    413501                /* Look at the next block. If it is free and the size is
    414                    sufficient then merge the two. */
     502                   sufficient then merge the two. Otherwise just allocate
     503                   a new block, copy the original data into it and
     504                   free the original block. */
    415505                heap_block_head_t *next_head =
    416506                    (heap_block_head_t *) (((void *) head) + head->size);
     
    424514                       
    425515                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    426                 } else {
    427                         ptr = malloc(size);
    428                         if (ptr != NULL) {
    429                                 memcpy(ptr, addr, NET_SIZE(orig_size));
    430                                 free(addr);
    431                         }
     516                } else
     517                        reloc = true;
     518        }
     519       
     520        futex_up(&malloc_futex);
     521       
     522        if (reloc) {
     523                ptr = malloc(size);
     524                if (ptr != NULL) {
     525                        memcpy(ptr, addr, NET_SIZE(orig_size));
     526                        free(addr);
    432527                }
    433528        }
     
    439534 *
    440535 * @param addr The address of the block.
     536 *
    441537 */
    442538void free(const void *addr)
    443539{
     540        futex_down(&malloc_futex);
     541       
    444542        /* Calculate the position of the header. */
    445543        heap_block_head_t *head
     
    480578       
    481579        shrink_heap();
     580       
     581        futex_up(&malloc_futex);
    482582}
    483583
  • uspace/lib/c/generic/mman.c

    rcf8cc36 rc47e1a8  
    3939
    4040void *mmap(void *start, size_t length, int prot, int flags, int fd,
    41     off_t offset)
     41    aoff64_t offset)
    4242{
    4343        if (!start)
  • uspace/lib/c/generic/str.c

    rcf8cc36 rc47e1a8  
    3434 */
    3535
    36 #include <string.h>
     36#include <str.h>
    3737#include <stdlib.h>
    3838#include <assert.h>
     
    4343#include <align.h>
    4444#include <mem.h>
    45 #include <string.h>
     45#include <str.h>
    4646
    4747/** Byte mask consisting of lowest @n bits (out of 8) */
     
    471471 * null-terminated and containing only complete characters.
    472472 *
    473  * @param dest   Destination buffer.
     473 * @param dest  Destination buffer.
    474474 * @param count Size of the destination buffer (must be > 0).
    475475 * @param src   Source string.
     
    477477void str_cpy(char *dest, size_t size, const char *src)
    478478{
    479         wchar_t ch;
    480         size_t src_off;
    481         size_t dest_off;
    482 
    483479        /* There must be space for a null terminator in the buffer. */
    484480        assert(size > 0);
    485481       
    486         src_off = 0;
    487         dest_off = 0;
    488 
     482        size_t src_off = 0;
     483        size_t dest_off = 0;
     484       
     485        wchar_t ch;
    489486        while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
    490487                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    491488                        break;
    492489        }
    493 
     490       
    494491        dest[dest_off] = '\0';
    495492}
     
    505502 * have to be null-terminated.
    506503 *
    507  * @param dest   Destination buffer.
     504 * @param dest  Destination buffer.
    508505 * @param count Size of the destination buffer (must be > 0).
    509506 * @param src   Source string.
    510  * @param n     Maximum number of bytes to read from @a src.
     507 * @param n     Maximum number of bytes to read from @a src.
    511508 */
    512509void str_ncpy(char *dest, size_t size, const char *src, size_t n)
    513510{
    514         wchar_t ch;
    515         size_t src_off;
    516         size_t dest_off;
    517 
    518511        /* There must be space for a null terminator in the buffer. */
    519512        assert(size > 0);
    520513       
    521         src_off = 0;
    522         dest_off = 0;
    523 
     514        size_t src_off = 0;
     515        size_t dest_off = 0;
     516       
     517        wchar_t ch;
    524518        while ((ch = str_decode(src, &src_off, n)) != 0) {
    525519                if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
    526520                        break;
    527521        }
    528 
     522       
    529523        dest[dest_off] = '\0';
    530524}
     
    896890}
    897891
     892/** Duplicate string.
     893 *
     894 * Allocate a new string and copy characters from the source
     895 * string into it. The duplicate string is allocated via sleeping
     896 * malloc(), thus this function can sleep in no memory conditions.
     897 *
     898 * The allocation cannot fail and the return value is always
     899 * a valid pointer. The duplicate string is always a well-formed
     900 * null-terminated UTF-8 string, but it can differ from the source
     901 * string on the byte level.
     902 *
     903 * @param src Source string.
     904 *
     905 * @return Duplicate string.
     906 *
     907 */
    898908char *str_dup(const char *src)
    899909{
    900         size_t size = str_size(src);
    901         void *dest = malloc(size + 1);
    902        
     910        size_t size = str_size(src) + 1;
     911        char *dest = (char *) malloc(size);
    903912        if (dest == NULL)
    904913                return (char *) NULL;
    905914       
    906         return (char *) memcpy(dest, src, size + 1);
    907 }
    908 
    909 char *str_ndup(const char *src, size_t max_size)
     915        str_cpy(dest, size, src);
     916        return dest;
     917}
     918
     919/** Duplicate string with size limit.
     920 *
     921 * Allocate a new string and copy up to @max_size bytes from the source
     922 * string into it. The duplicate string is allocated via sleeping
     923 * malloc(), thus this function can sleep in no memory conditions.
     924 * No more than @max_size + 1 bytes is allocated, but if the size
     925 * occupied by the source string is smaller than @max_size + 1,
     926 * less is allocated.
     927 *
     928 * The allocation cannot fail and the return value is always
     929 * a valid pointer. The duplicate string is always a well-formed
     930 * null-terminated UTF-8 string, but it can differ from the source
     931 * string on the byte level.
     932 *
     933 * @param src Source string.
     934 * @param n   Maximum number of bytes to duplicate.
     935 *
     936 * @return Duplicate string.
     937 *
     938 */
     939char *str_ndup(const char *src, size_t n)
    910940{
    911941        size_t size = str_size(src);
    912         if (size > max_size)
    913                 size = max_size;
     942        if (size > n)
     943                size = n;
    914944       
    915945        char *dest = (char *) malloc(size + 1);
    916        
    917946        if (dest == NULL)
    918947                return (char *) NULL;
    919948       
    920         memcpy(dest, src, size);
    921         dest[size] = 0;
     949        str_ncpy(dest, size + 1, src, size);
    922950        return dest;
    923951}
     
    9791007}
    9801008
     1009void order_suffix(const uint64_t val, uint64_t *rv, char *suffix)
     1010{
     1011        if (val > 10000000000000000000ULL) {
     1012                *rv = val / 1000000000000000000ULL;
     1013                *suffix = 'Z';
     1014        } else if (val > 1000000000000000000ULL) {
     1015                *rv = val / 1000000000000000ULL;
     1016                *suffix = 'E';
     1017        } else if (val > 1000000000000000ULL) {
     1018                *rv = val / 1000000000000ULL;
     1019                *suffix = 'T';
     1020        } else if (val > 1000000000000ULL) {
     1021                *rv = val / 1000000000ULL;
     1022                *suffix = 'G';
     1023        } else if (val > 1000000000ULL) {
     1024                *rv = val / 1000000ULL;
     1025                *suffix = 'M';
     1026        } else if (val > 1000000ULL) {
     1027                *rv = val / 1000ULL;
     1028                *suffix = 'k';
     1029        } else {
     1030                *rv = val;
     1031                *suffix = ' ';
     1032        }
     1033}
     1034
    9811035/** @}
    9821036 */
  • uspace/lib/c/generic/task.c

    rcf8cc36 rc47e1a8  
    3939#include <errno.h>
    4040#include <loader/loader.h>
    41 #include <string.h>
     41#include <str.h>
    4242#include <ipc/ns.h>
    4343#include <macros.h>
     
    7070 * loader API.
    7171 *
    72  * @param path pathname of the binary to execute
    73  * @param argv command-line arguments
     72 * @param path Pathname of the binary to execute.
     73 * @param argv Command-line arguments.
     74 * @param err  If not NULL, the error value is stored here.
    7475 *
    7576 * @return ID of the newly created task or zero on error.
    7677 *
    7778 */
    78 task_id_t task_spawn(const char *path, char *const args[])
     79task_id_t task_spawn(const char *path, const char *const args[], int *err)
    7980{
    8081        /* Connect to a program loader. */
    8182        loader_t *ldr = loader_connect();
    82         if (ldr == NULL)
     83        if (ldr == NULL) {
     84                if (err != NULL)
     85                        *err = EREFUSED;
     86               
    8387                return 0;
     88        }
    8489       
    8590        /* Get task ID. */
     
    143148        /* Success */
    144149        free(ldr);
     150       
     151        if (err != NULL)
     152                *err = EOK;
     153       
    145154        return task_id;
    146155       
     
    149158        loader_abort(ldr);
    150159        free(ldr);
     160       
     161        if (err != NULL)
     162                *err = rc;
    151163       
    152164        return 0;
  • uspace/lib/c/generic/thread.c

    rcf8cc36 rc47e1a8  
    3939#include <kernel/proc/uarg.h>
    4040#include <fibril.h>
    41 #include <string.h>
     41#include <str.h>
    4242#include <async.h>
    4343
     
    8686 * @return Zero on success or a code from @ref errno.h on failure.
    8787 */
    88 int thread_create(void (* function)(void *), void *arg, char *name,
     88int thread_create(void (* function)(void *), void *arg, const char *name,
    8989    thread_id_t *tid)
    9090{
  • uspace/lib/c/generic/tls.c

    rcf8cc36 rc47e1a8  
    4040#include <tls.h>
    4141#include <malloc.h>
    42 #include <string.h>
     42#include <str.h>
    4343#include <align.h>
    4444
  • uspace/lib/c/generic/vfs/vfs.c

    rcf8cc36 rc47e1a8  
    3535#include <vfs/vfs.h>
    3636#include <vfs/canonify.h>
     37#include <macros.h>
    3738#include <stdlib.h>
    3839#include <unistd.h>
     
    4849#include <futex.h>
    4950#include <errno.h>
    50 #include <string.h>
     51#include <str.h>
    5152#include <devmap.h>
    5253#include <ipc/vfs.h>
     
    434435}
    435436
    436 off_t lseek(int fildes, off_t offset, int whence)
    437 {
    438         ipcarg_t rc;
    439 
    440         futex_down(&vfs_phone_futex);
    441         async_serialize_start();
    442         vfs_connect();
    443        
    444         ipcarg_t newoffs;
    445         rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
    446             &newoffs);
    447 
    448         async_serialize_end();
    449         futex_up(&vfs_phone_futex);
    450 
     437off64_t lseek(int fildes, off64_t offset, int whence)
     438{
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
     442       
     443        ipcarg_t newoff_lo;
     444        ipcarg_t newoff_hi;
     445        ipcarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     446            LOWER32(offset), UPPER32(offset), whence,
     447            &newoff_lo, &newoff_hi);
     448       
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
     451       
    451452        if (rc != EOK)
    452                 return (off_t) -1;
    453        
    454         return (off_t) newoffs;
    455 }
    456 
    457 int ftruncate(int fildes, off_t length)
    458 {
    459         ipcarg_t rc;
    460        
    461         futex_down(&vfs_phone_futex);
    462         async_serialize_start();
    463         vfs_connect();
    464        
    465         rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
    466         async_serialize_end();
    467         futex_up(&vfs_phone_futex);
     453                return (off64_t) -1;
     454       
     455        return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi);
     456}
     457
     458int ftruncate(int fildes, aoff64_t length)
     459{
     460        ipcarg_t rc;
     461       
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
     465       
     466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     467            LOWER32(length), UPPER32(length));
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
     470       
    468471        return (int) rc;
    469472}
     
    479482       
    480483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    481         rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
     484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    482485        if (rc != EOK) {
    483486                ipcarg_t rc_orig;
     
    553556        if (!abs) {
    554557                free(dirp);
    555                 return ENOMEM;
     558                return NULL;
    556559        }
    557560       
Note: See TracChangeset for help on using the changeset viewer.