Changeset 1b20da0 in mainline for uspace/lib/c/generic
- Timestamp:
- 2018-02-28T17:52:03Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3061bc1
- Parents:
- df6ded8
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:26:03)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:52:03)
- Location:
- uspace/lib/c/generic
- Files:
-
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/hash_table.c
rdf6ded8 r1b20da0 2 2 * Copyright (c) 2008 Jakub Jermar 3 3 * Copyright (c) 2012 Adam Hraska 4 * 4 * 5 5 * All rights reserved. 6 6 * … … 37 37 /* 38 38 * This is an implementation of a generic resizable chained hash table. 39 * 40 * The table grows to 2*n+1 buckets each time, starting at n == 89, 39 * 40 * The table grows to 2*n+1 buckets each time, starting at n == 89, 41 41 * per Thomas Wang's recommendation: 42 42 * http://www.concentric.net/~Ttwang/tech/hashsize.htm 43 * 43 * 44 44 * This policy produces prime table sizes for the first five resizes 45 * and generally produces table sizes which are either prime or 45 * and generally produces table sizes which are either prime or 46 46 * have fairly large (prime/odd) divisors. Having a prime table size 47 47 * mitigates the use of suboptimal hash functions and distributes … … 79 79 * @param h Hash table structure. Will be initialized by this call. 80 80 * @param init_size Initial desired number of hash table buckets. Pass zero 81 * if you want the default initial size. 81 * if you want the default initial size. 82 82 * @param max_load The table is resized when the average load per bucket 83 83 * exceeds this number. Pass zero if you want the default. … … 86 86 * upon removal. equal() is optional if and only if 87 87 * hash_table_insert_unique() will never be invoked. 88 * All other operations are mandatory. 88 * All other operations are mandatory. 89 89 * 90 90 * @return True on success … … 210 210 * @param h Hash table. 211 211 * @param item Item to be inserted into the hash table. 212 * 213 * @return False if such an item had already been inserted. 212 * 213 * @return False if such an item had already been inserted. 214 214 * @return True if the inserted item was the only item with such a lookup key. 215 215 */ … … 225 225 /* Check for duplicates. */ 226 226 list_foreach(h->bucket[idx], link, ht_link_t, cur_link) { 227 /* 228 * We could filter out items using their hashes first, but 227 /* 228 * We could filter out items using their hashes first, but 229 229 * calling equal() might very well be just as fast. 230 230 */ … … 255 255 256 256 list_foreach(h->bucket[idx], link, ht_link_t, cur_link) { 257 /* 258 * Is this is the item we are looking for? We could have first 259 * checked if the hashes match but op->key_equal() may very well be 257 /* 258 * Is this is the item we are looking for? We could have first 259 * checked if the hashes match but op->key_equal() may very well be 260 260 * just as fast as op->hash(). 261 261 */ … … 278 278 assert(cur); 279 279 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 280 /* 281 * Is this is the item we are looking for? We could have first 282 * checked if the hashes match but op->equal() may very well be 280 /* 281 * Is this is the item we are looking for? We could have first 282 * checked if the hashes match but op->equal() may very well be 283 283 * just as fast as op->hash(). 284 284 */ … … 299 299 * the hash table. 300 300 * @param keys Number of keys in the 'key' array. 301 * 301 * 302 302 * @return Returns the number of removed items. 303 303 */ … … 343 343 * 344 344 * @param h Hash table. 345 * @param f Function to be applied. Return false if no more items 345 * @param f Function to be applied. Return false if no more items 346 346 * should be visited. The functor may only delete the supplied 347 * item. It must not delete the successor of the item passed 347 * item. It must not delete the successor of the item passed 348 348 * in the first argument. 349 349 * @param arg Argument to be passed to the function. 350 350 */ 351 351 void hash_table_apply(hash_table_t *h, bool (*f)(ht_link_t *, void *), void *arg) 352 { 352 { 353 353 assert(f); 354 354 assert(h && h->bucket); … … 362 362 list_foreach_safe(h->bucket[idx], cur, next) { 363 363 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 364 /* 365 * The next pointer had already been saved. f() may safely 364 /* 365 * The next pointer had already been saved. f() may safely 366 366 * delete cur (but not next!). 367 367 */ … … 410 410 { 411 411 if (h->item_cnt <= h->full_item_cnt / 4 && HT_MIN_BUCKETS < h->bucket_cnt) { 412 /* 413 * Keep the bucket_cnt odd (possibly also prime). 412 /* 413 * Keep the bucket_cnt odd (possibly also prime). 414 414 * Shrink from 2n + 1 to n. Integer division discards the +1. 415 415 */ … … 431 431 432 432 /** Allocates and rehashes items to a new table. Frees the old table. */ 433 static void resize(hash_table_t *h, size_t new_bucket_cnt) 433 static void resize(hash_table_t *h, size_t new_bucket_cnt) 434 434 { 435 435 assert(h && h->bucket); -
uspace/lib/c/generic/adt/list.c
rdf6ded8 r1b20da0 79 79 void list_splice(list_t *list, link_t *pos) 80 80 { 81 if (list_empty(list)) 81 if (list_empty(list)) 82 82 return; 83 83 -
uspace/lib/c/generic/adt/odict.c
rdf6ded8 r1b20da0 1084 1084 * visit_tree(A->a), visit(A), visit(A->b). If key(A) < key(B), 1085 1085 * we will first visit A, then while visiting all nodes with values 1086 * between A and B we will not leave subtree A->b. 1086 * between A and B we will not leave subtree A->b. 1087 1087 */ 1088 1088 -
uspace/lib/c/generic/async.c
rdf6ded8 r1b20da0 1087 1087 /** Unsubscribe from IRQ notification. 1088 1088 * 1089 * @param cap IRQ capability handle. 1089 * @param cap IRQ capability handle. 1090 1090 * 1091 1091 * @return Zero on success or an error code. -
uspace/lib/c/generic/ddi.c
rdf6ded8 r1b20da0 211 211 * 212 212 * @param range I/O range to be enable. 213 * @param virt Virtual address for application's PIO operations. 213 * @param virt Virtual address for application's PIO operations. 214 214 */ 215 215 errno_t pio_enable_range(addr_range_t *range, void **virt) … … 257 257 } 258 258 259 return pio_enable((void *) addr, size, virt); 259 return pio_enable((void *) addr, size, virt); 260 260 } 261 261 -
uspace/lib/c/generic/device/hw_res_parsed.c
rdf6ded8 r1b20da0 268 268 rc = pio_window_get(sess, &pio_window); 269 269 if (rc != EOK) 270 return rc; 270 return rc; 271 271 272 272 rc = hw_res_get_resource_list(sess, &hw_resources); -
uspace/lib/c/generic/device/pio_window.c
rdf6ded8 r1b20da0 1 1 /* 2 * Copyright (c) 2013 Jakub Jermar 2 * Copyright (c) 2013 Jakub Jermar 3 3 * All rights reserved. 4 4 * -
uspace/lib/c/generic/dlfcn.c
rdf6ded8 r1b20da0 30 30 * @brief 31 31 * @{ 32 */ 32 */ 33 33 /** 34 34 * @file -
uspace/lib/c/generic/double_to_str.c
rdf6ded8 r1b20da0 103 103 104 104 /* Denote 32 bit parts of x a y as: x == a b, y == c d. Then: 105 * a b 105 * a b 106 106 * * c d 107 107 * ---------- … … 126 126 ret.exponent = x.exponent + y.exponent + significand_width; 127 127 128 return ret; 128 return ret; 129 129 } 130 130 … … 146 146 147 147 /** Returns the interval [low, high] of numbers that convert to binary val. */ 148 static void get_normalized_bounds(ieee_double_t val, fp_num_t *high, 148 static void get_normalized_bounds(ieee_double_t val, fp_num_t *high, 149 149 fp_num_t *low, fp_num_t *val_dist) 150 150 { 151 /* 151 /* 152 152 * Only works if val comes directly from extract_ieee_double without 153 * being manipulated in any way (eg it must not be normalized). 153 * being manipulated in any way (eg it must not be normalized). 154 154 */ 155 155 assert(!is_normalized(val.pos_val)); … … 173 173 *high = normalize(*high); 174 174 175 /* 175 /* 176 176 * Lower bound may not be normalized if subtracting 1 unit 177 * reset the most-significant bit to 0. 177 * reset the most-significant bit to 0. 178 178 */ 179 179 low->significand = low->significand << (low->exponent - high->exponent); 180 180 low->exponent = high->exponent; 181 181 182 val_dist->significand = 182 val_dist->significand = 183 183 val_dist->significand << (val_dist->exponent - high->exponent); 184 184 val_dist->exponent = high->exponent; 185 185 } 186 186 187 /** Determines the interval of numbers that have the binary representation 187 /** Determines the interval of numbers that have the binary representation 188 188 * of val. 189 * 189 * 190 190 * Numbers in the range [scaled_upper_bound - bounds_delta, scaled_upper_bound] 191 * have the same double binary representation as val. 191 * have the same double binary representation as val. 192 192 * 193 193 * Bounds are scaled by 10^scale so that alpha <= exponent <= gamma. … … 197 197 * val_dist == (upper_bound - val) * 10^scale 198 198 */ 199 static void calc_scaled_bounds(ieee_double_t val, fp_num_t *scaled_upper_bound, 199 static void calc_scaled_bounds(ieee_double_t val, fp_num_t *scaled_upper_bound, 200 200 fp_num_t *bounds_delta, fp_num_t *val_dist, int *scale) 201 201 { … … 208 208 assert(normalize(val.pos_val).exponent == upper_bound.exponent); 209 209 210 /* 210 /* 211 211 * Find such a cached normalized power of 10 that if multiplied 212 * by upper_bound the binary exponent of upper_bound almost vanishes, 212 * by upper_bound the binary exponent of upper_bound almost vanishes, 213 213 * ie: 214 214 * upper_scaled := upper_bound * 10^scale … … 231 231 assert(alpha <= upper_scaled.exponent && upper_scaled.exponent <= gamma); 232 232 233 /* 233 /* 234 234 * Any value between lower and upper bound would be represented 235 235 * in binary as the double val originated from. The bounds were 236 * however scaled by an imprecise power of 10 (error less than 237 * 1 ulp) so the scaled bounds have an error of less than 1 ulp. 238 * Conservatively round the lower bound up and the upper bound 236 * however scaled by an imprecise power of 10 (error less than 237 * 1 ulp) so the scaled bounds have an error of less than 1 ulp. 238 * Conservatively round the lower bound up and the upper bound 239 239 * down by 1 ulp just to be on the safe side. It avoids pronouncing 240 240 * produced decimal digits as correct if such a decimal number 241 * is close to the bounds to within 1 ulp. 241 * is close to the bounds to within 1 ulp. 242 242 */ 243 243 upper_scaled.significand -= 1; … … 263 263 * 264 264 * delta = upper - lower .. conservative/safe interval 265 * w_dist = upper - w 265 * w_dist = upper - w 266 266 * upper = "number represented by digits in buf" + rest 267 * 268 * Changing buf[len - 1] changes the value represented by buf 267 * 268 * Changing buf[len - 1] changes the value represented by buf 269 269 * by digit_val_diff * scaling, where scaling is shared by 270 * all parameters. 270 * all parameters. 271 271 * 272 272 */ … … 277 277 bool next_in_val_rng = cur_greater_w && (rest + digit_val_diff < delta); 278 278 /* Rounding down by one would bring buf closer to the processed number. */ 279 bool next_closer = next_in_val_rng 279 bool next_closer = next_in_val_rng 280 280 && (rest + digit_val_diff < w_dist || rest - w_dist < w_dist - rest); 281 281 282 /* Of the shortest strings pick the one that is closest to the actual 282 /* Of the shortest strings pick the one that is closest to the actual 283 283 floating point number. */ 284 284 while (next_closer) { … … 291 291 cur_greater_w = rest < w_dist; 292 292 next_in_val_rng = cur_greater_w && (rest + digit_val_diff < delta); 293 next_closer = next_in_val_rng 293 next_closer = next_in_val_rng 294 294 && (rest + digit_val_diff < w_dist || rest - w_dist < w_dist - rest); 295 295 } … … 299 299 /** Generates the shortest accurate decimal string representation. 300 300 * 301 * Outputs (mostly) the shortest accurate string representation 301 * Outputs (mostly) the shortest accurate string representation 302 302 * for the number scaled_upper - val_dist. Numbers in the interval 303 303 * [scaled_upper - delta, scaled_upper] have the same binary … … 305 305 * shortest string representation (up to the rounding of the last 306 306 * digit to bring the shortest string also the closest to the 307 * actual number). 307 * actual number). 308 308 * 309 309 * @param scaled_upper Scaled upper bound of numbers that have the … … 315 315 * decimal string we're generating. 316 316 * @param scale Decimal scaling of the value to convert (ie scaled_upper). 317 * @param buf Buffer to store the string representation. Must be large 317 * @param buf Buffer to store the string representation. Must be large 318 318 * enough to store all digits and a null terminator. At most 319 319 * MAX_DOUBLE_STR_LEN digits will be written (not counting 320 320 * the null terminator). 321 * @param buf_size Size of buf in bytes. 322 * @param dec_exponent Will be set to the decimal exponent of the number 321 * @param buf_size Size of buf in bytes. 322 * @param dec_exponent Will be set to the decimal exponent of the number 323 323 * string in buf. 324 324 * 325 325 * @return Number of digits; negative on failure (eg buffer too small). 326 326 */ 327 static int gen_dec_digits(fp_num_t scaled_upper, fp_num_t delta, 327 static int gen_dec_digits(fp_num_t scaled_upper, fp_num_t delta, 328 328 fp_num_t val_dist, int scale, char *buf, size_t buf_size, int *dec_exponent) 329 329 { 330 /* 331 * The integral part of scaled_upper is 5 to 32 bits long while 330 /* 331 * The integral part of scaled_upper is 5 to 32 bits long while 332 332 * the remaining fractional part is 59 to 32 bits long because: 333 333 * -59 == alpha <= scaled_upper.e <= gamma == -32 … … 341 341 * ` lower 342 342 * 343 */ 343 */ 344 344 assert(scaled_upper.significand != 0); 345 345 assert(alpha <= scaled_upper.exponent && scaled_upper.exponent <= gamma); … … 359 359 360 360 /* 361 * Extract the integral part of scaled_upper. 362 * upper / one == upper >> -one.e 361 * Extract the integral part of scaled_upper. 362 * upper / one == upper >> -one.e 363 363 */ 364 364 uint32_t int_part = (uint32_t)(scaled_upper.significand >> (-one.exponent)); 365 365 366 /* 366 /* 367 367 * Fractional part of scaled_upper. 368 * upper % one == upper & (one.f - 1) 368 * upper % one == upper & (one.f - 1) 369 369 */ 370 370 uint64_t frac_part = scaled_upper.significand & (one.significand - 1); 371 371 372 372 /* 373 * The integral part of upper has at least 5 bits (64 + alpha) and 374 * at most 32 bits (64 + gamma). The integral part has at most 10 375 * decimal digits, so kappa <= 10. 373 * The integral part of upper has at least 5 bits (64 + alpha) and 374 * at most 32 bits (64 + gamma). The integral part has at most 10 375 * decimal digits, so kappa <= 10. 376 376 */ 377 377 int kappa = 10; … … 397 397 } 398 398 399 /* 399 /* 400 400 * Difference between the so far produced decimal number and upper 401 * is calculated as: remaining_int_part * one + frac_part 401 * is calculated as: remaining_int_part * one + frac_part 402 402 */ 403 403 uint64_t remainder = (((uint64_t)int_part) << -one.exponent) + frac_part; … … 422 422 /* 423 423 * Does not overflow because at least 5 upper bits were 424 * taken by the integral part and are now unused in frac_part. 424 * taken by the integral part and are now unused in frac_part. 425 425 */ 426 426 frac_part *= 10; … … 456 456 457 457 /* Of the shortest representations choose the numerically closest one. */ 458 round_last_digit(frac_part, val_dist.significand, delta.significand, 458 round_last_digit(frac_part, val_dist.significand, delta.significand, 459 459 one.significand, buf, len); 460 460 … … 476 476 477 477 478 /** Converts a non-special double into its shortest accurate string 478 /** Converts a non-special double into its shortest accurate string 479 479 * representation. 480 480 * 481 * Produces an accurate string representation, ie the string will 481 * Produces an accurate string representation, ie the string will 482 482 * convert back to the same binary double (eg via strtod). In the 483 483 * vast majority of cases (99%) the string will be the shortest such … … 492 492 * @param ieee_val Binary double description to convert. Must be the product 493 493 * of extract_ieee_double and it must not be a special number. 494 * @param buf Buffer to store the string representation. Must be large 494 * @param buf Buffer to store the string representation. Must be large 495 495 * enough to store all digits and a null terminator. At most 496 496 * MAX_DOUBLE_STR_LEN digits will be written (not counting 497 497 * the null terminator). 498 498 * @param buf_size Size of buf in bytes. 499 * @param dec_exponent Will be set to the decimal exponent of the number 499 * @param dec_exponent Will be set to the decimal exponent of the number 500 500 * string in buf. 501 501 * … … 503 503 * an error: buf too small (or ieee_val.is_special). 504 504 */ 505 int double_to_short_str(ieee_double_t ieee_val, char *buf, size_t buf_size, 505 int double_to_short_str(ieee_double_t ieee_val, char *buf, size_t buf_size, 506 506 int *dec_exponent) 507 507 { … … 523 523 int scale; 524 524 525 calc_scaled_bounds(ieee_val, &scaled_upper_bound, 525 calc_scaled_bounds(ieee_val, &scaled_upper_bound, 526 526 &delta, &val_dist, &scale); 527 527 528 int len = gen_dec_digits(scaled_upper_bound, delta, val_dist, scale, 528 int len = gen_dec_digits(scaled_upper_bound, delta, val_dist, scale, 529 529 buf, buf_size, dec_exponent); 530 530 … … 540 540 * alpha <= exponent <= gamma 541 541 * @param scale Decimal scaling of the value to convert (ie w_scaled). 542 * @param signif_d_cnt Maximum number of significant digits to output. 542 * @param signif_d_cnt Maximum number of significant digits to output. 543 543 * Negative if as many as possible are requested. 544 544 * @param frac_d_cnt Maximum number of fractional digits to output. 545 545 * Negative if as many as possible are requested. 546 546 * Eg. if 2 then 1.234 -> "1.23"; if 2 then 3e-9 -> "0". 547 * @param buf Buffer to store the string representation. Must be large 547 * @param buf Buffer to store the string representation. Must be large 548 548 * enough to store all digits and a null terminator. At most 549 549 * MAX_DOUBLE_STR_LEN digits will be written (not counting 550 550 * the null terminator). 551 * @param buf_size Size of buf in bytes. 551 * @param buf_size Size of buf in bytes. 552 552 * 553 553 * @return Number of digits; negative on failure (eg buffer too small). 554 554 */ 555 static int gen_fixed_dec_digits(fp_num_t w_scaled, int scale, int signif_d_cnt, 555 static int gen_fixed_dec_digits(fp_num_t w_scaled, int scale, int signif_d_cnt, 556 556 int frac_d_cnt, char *buf, size_t buf_size, int *dec_exponent) 557 557 { … … 561 561 } 562 562 563 /* 564 * The integral part of w_scaled is 5 to 32 bits long while the 563 /* 564 * The integral part of w_scaled is 5 to 32 bits long while the 565 565 * remaining fractional part is 59 to 32 bits long because: 566 566 * -59 == alpha <= w_scaled.e <= gamma == -32 567 * 567 * 568 568 * Therefore: 569 569 * | 5..32 bits | 32..59 bits | == w_scaled == w * 10^scale 570 570 * | int_part | frac_part | 571 571 * |0 0 .. 0 1|0 0 .. 0 0| == one == 1.0 572 * | 0 |0 0 .. 0 1| == w_err == 1 * 2^w_scaled.e 572 * | 0 |0 0 .. 0 1| == w_err == 1 * 2^w_scaled.e 573 573 */ 574 574 assert(alpha <= w_scaled.exponent && w_scaled.exponent <= gamma); 575 575 assert(0 != w_scaled.significand); 576 576 577 /* 577 /* 578 578 * Scaling the number being converted by 10^scale introduced 579 579 * an error of less that 1 ulp. The actual value of w_scaled 580 * could lie anywhere between w_scaled.signif +/- w_err. 580 * could lie anywhere between w_scaled.signif +/- w_err. 581 581 * Scale the error locally as we scale the fractional part 582 582 * of w_scaled. … … 589 589 one.exponent = w_scaled.exponent; 590 590 591 /* Extract the integral part of w_scaled. 591 /* Extract the integral part of w_scaled. 592 592 w_scaled / one == w_scaled >> -one.e */ 593 593 uint32_t int_part = (uint32_t)(w_scaled.significand >> (-one.exponent)); … … 598 598 599 599 size_t len = 0; 600 /* 601 * The integral part of w_scaled has at least 5 bits (64 + alpha = 5) 602 * and at most 32 bits (64 + gamma = 32). The integral part has 603 * at most 10 decimal digits, so kappa <= 10. 600 /* 601 * The integral part of w_scaled has at least 5 bits (64 + alpha = 5) 602 * and at most 32 bits (64 + gamma = 32). The integral part has 603 * at most 10 decimal digits, so kappa <= 10. 604 604 */ 605 605 int kappa = 10; … … 607 607 608 608 int rem_signif_d_cnt = signif_d_cnt; 609 int rem_frac_d_cnt = 609 int rem_frac_d_cnt = 610 610 (frac_d_cnt >= 0) ? (kappa - scale + frac_d_cnt) : INT_MAX; 611 611 … … 638 638 /* 639 639 * Does not overflow because at least 5 upper bits were 640 * taken by the integral part and are now unused in frac_part. 640 * taken by the integral part and are now unused in frac_part. 641 641 */ 642 642 frac_part *= 10; … … 673 673 assert(frac_d_cnt < 0 || -frac_d_cnt <= *dec_exponent); 674 674 } else { 675 /* 676 * The number of fractional digits was too limiting to produce 677 * any digits. 675 /* 676 * The number of fractional digits was too limiting to produce 677 * any digits. 678 678 */ 679 679 assert(rem_frac_d_cnt <= 0 || w_scaled.significand == 0); … … 699 699 * Conversion errors are tracked, so all produced digits except the 700 700 * last one are accurate. Garbage digits are never produced. 701 * If the requested number of digits cannot be produced accurately 702 * due to conversion errors less digits are produced than requested 701 * If the requested number of digits cannot be produced accurately 702 * due to conversion errors less digits are produced than requested 703 703 * and the last digit has an error of +/- 1 (so if '7' is the last 704 704 * converted digit it might have been converted to any of '6'..'8' 705 * had the conversion been completely precise). 706 * 707 * If no error occurs at least one digit is output. 708 * 709 * The conversion stops once the requested number of significant or 710 * fractional digits is reached or the conversion error is too large 705 * had the conversion been completely precise). 706 * 707 * If no error occurs at least one digit is output. 708 * 709 * The conversion stops once the requested number of significant or 710 * fractional digits is reached or the conversion error is too large 711 711 * to generate any more digits (whichever happens first). 712 712 * … … 731 731 * of extract_ieee_double and it must not be a special number. 732 732 * @param signif_d_cnt Maximum number of significant digits to produce. 733 * The output is not rounded. 733 * The output is not rounded. 734 734 * Set to a negative value to generate as many digits 735 735 * as accurately possible. 736 736 * @param frac_d_cnt Maximum number of fractional digits to produce including 737 * any zeros immediately trailing the decimal point. 738 * The output is not rounded. 737 * any zeros immediately trailing the decimal point. 738 * The output is not rounded. 739 739 * Set to a negative value to generate as many digits 740 740 * as accurately possible. 741 * @param buf Buffer to store the string representation. Must be large 741 * @param buf Buffer to store the string representation. Must be large 742 742 * enough to store all digits and a null terminator. At most 743 743 * MAX_DOUBLE_STR_LEN digits will be written (not counting 744 744 * the null terminator). 745 745 * @param buf_size Size of buf in bytes. 746 * @param dec_exponent Set to the decimal exponent of the number string 746 * @param dec_exponent Set to the decimal exponent of the number string 747 747 * in buf. 748 748 * 749 749 * @return The number of output digits. A negative value indicates 750 * an error: buf too small (or ieee_val.is_special, or 750 * an error: buf too small (or ieee_val.is_special, or 751 751 * signif_d_cnt == 0). 752 752 */ … … 779 779 780 780 /* Produce decimal digits from the scaled number. */ 781 int len = gen_fixed_dec_digits(w_scaled, scale, signif_d_cnt, frac_d_cnt, 781 int len = gen_fixed_dec_digits(w_scaled, scale, signif_d_cnt, frac_d_cnt, 782 782 buf, buf_size, dec_exponent); 783 783 -
uspace/lib/c/generic/elf/elf_load.c
rdf6ded8 r1b20da0 51 51 /** Load ELF program. 52 52 * 53 * @param file File handle 53 * @param file File handle 54 54 * @param info Place to store ELF program information 55 55 * @return EE_OK on success or an EE_x error code -
uspace/lib/c/generic/elf/elf_mod.c
rdf6ded8 r1b20da0 152 152 rc = vfs_read(elf->fd, &pos, header, sizeof(elf_header_t), &nr); 153 153 if (rc != EOK || nr != sizeof(elf_header_t)) { 154 DPRINTF("Read error.\n"); 154 DPRINTF("Read error.\n"); 155 155 return EE_IO; 156 156 } … … 160 160 /* Identify ELF */ 161 161 if (header->e_ident[EI_MAG0] != ELFMAG0 || 162 header->e_ident[EI_MAG1] != ELFMAG1 || 162 header->e_ident[EI_MAG1] != ELFMAG1 || 163 163 header->e_ident[EI_MAG2] != ELFMAG2 || 164 164 header->e_ident[EI_MAG3] != ELFMAG3) { … … 169 169 /* Identify ELF compatibility */ 170 170 if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING || 171 header->e_machine != ELF_MACHINE || 171 header->e_machine != ELF_MACHINE || 172 172 header->e_ident[EI_VERSION] != EV_CURRENT || 173 173 header->e_version != EV_CURRENT || -
uspace/lib/c/generic/event.c
rdf6ded8 r1b20da0 1 1 /* 2 * Copyright (c) 2009 Jakub Jermar 2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * -
uspace/lib/c/generic/fibril.c
rdf6ded8 r1b20da0 128 128 129 129 void fibril_teardown(fibril_t *fibril, bool locked) 130 { 130 { 131 131 if (!locked) 132 132 futex_lock(&fibril_futex); … … 236 236 link); 237 237 238 if (stype == FIBRIL_FROM_DEAD) 238 if (stype == FIBRIL_FROM_DEAD) 239 239 dstf->clean_after_me = srcf; 240 240 break; -
uspace/lib/c/generic/fibril_synch.c
rdf6ded8 r1b20da0 1 1 /* 2 * Copyright (c) 2009 Jakub Jermar 2 * Copyright (c) 2009 Jakub Jermar 3 3 * All rights reserved. 4 4 * … … 175 175 176 176 futex_down(&async_futex); 177 if (fm->counter <= 0) 177 if (fm->counter <= 0) 178 178 locked = true; 179 179 futex_up(&async_futex); -
uspace/lib/c/generic/getopt.c
rdf6ded8 r1b20da0 197 197 if (IN_ORDER) { 198 198 /* 199 * GNU extension: 199 * GNU extension: 200 200 * return non-option as argument to option 1 201 201 */ … … 243 243 if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ 244 244 /* XXX: what if no long options provided (called by getopt)? */ 245 if (*place) 245 if (*place) 246 246 return -2; 247 247 … … 450 450 *long_options[match].flag = long_options[match].val; 451 451 retval = 0; 452 } else 452 } else 453 453 retval = long_options[match].val; 454 454 if (idx) -
uspace/lib/c/generic/ieee_double.c
rdf6ded8 r1b20da0 54 54 bits.val = val; 55 55 56 /* 57 * Extract the binary ieee representation of the double. 56 /* 57 * Extract the binary ieee representation of the double. 58 58 * Relies on integers having the same endianness as doubles. 59 59 */ 60 uint64_t num = bits.num; 60 uint64_t num = bits.num; 61 61 62 62 ieee_double_t ret; … … 98 98 ret.pos_val.exponent = raw_exponent - exponent_bias; 99 99 100 /* The predecessor is closer to val than the successor 100 /* The predecessor is closer to val than the successor 101 101 * if val is a normal value of the form 2^k (hence 102 * raw_significand == 0) with the only exception being 103 * the smallest normal (raw_exponent == 1). The smallest 104 * normal's predecessor is the largest denormal and denormals 105 * do not get an extra bit of precision because their exponent 102 * raw_significand == 0) with the only exception being 103 * the smallest normal (raw_exponent == 1). The smallest 104 * normal's predecessor is the largest denormal and denormals 105 * do not get an extra bit of precision because their exponent 106 106 * stays the same (ie it does not decrease from k to k-1). 107 107 */ -
uspace/lib/c/generic/io/io.c
rdf6ded8 r1b20da0 54 54 static FILE stdin_null = { 55 55 .fd = -1, 56 .pos = 0, 56 .pos = 0, 57 57 .error = true, 58 58 .eof = true, … … 69 69 static FILE stdout_kio = { 70 70 .fd = -1, 71 .pos = 0, 71 .pos = 0, 72 72 .error = false, 73 73 .eof = false, … … 84 84 static FILE stderr_kio = { 85 85 .fd = -1, 86 .pos = 0, 86 .pos = 0, 87 87 .error = false, 88 88 .eof = false, … … 827 827 errno = rc; 828 828 stream->error = true; 829 return -1; 829 return -1; 830 830 } 831 831 stream->pos = st.size + offset; -
uspace/lib/c/generic/io/printf_core.c
rdf6ded8 r1b20da0 592 592 593 593 /** Prints a special double (ie NaN, infinity) padded to width characters. */ 594 static int print_special(ieee_double_t val, int width, uint32_t flags, 594 static int print_special(ieee_double_t val, int width, uint32_t flags, 595 595 printf_spec_t *ps) 596 596 { … … 615 615 /* Leading padding. */ 616 616 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 617 if ((ret = print_padding(' ', padding_len, ps)) < 0) 617 if ((ret = print_padding(' ', padding_len, ps)) < 0) 618 618 return -1; 619 619 … … 636 636 /* Trailing padding. */ 637 637 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 638 if ((ret = print_padding(' ', padding_len, ps)) < 0) 638 if ((ret = print_padding(' ', padding_len, ps)) < 0) 639 639 return -1; 640 640 … … 698 698 699 699 700 /** Format and print the double string repressentation according 701 * to the %f specifier. 702 */ 703 static int print_double_str_fixed(double_str_t *val_str, int precision, int width, 700 /** Format and print the double string repressentation according 701 * to the %f specifier. 702 */ 703 static int print_double_str_fixed(double_str_t *val_str, int precision, int width, 704 704 uint32_t flags, printf_spec_t *ps) 705 705 { … … 742 742 743 743 if (!(flags & (__PRINTF_FLAG_LEFTALIGNED | __PRINTF_FLAG_ZEROPADDED))) { 744 if ((ret = print_padding(' ', padding_len, ps)) < 0) 744 if ((ret = print_padding(' ', padding_len, ps)) < 0) 745 745 return -1; 746 746 … … 749 749 750 750 if (sign) { 751 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 751 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 752 752 return -1; 753 753 … … 756 756 757 757 if (flags & __PRINTF_FLAG_ZEROPADDED) { 758 if ((ret = print_padding('0', padding_len, ps)) < 0) 758 if ((ret = print_padding('0', padding_len, ps)) < 0) 759 759 return -1; 760 760 … … 767 767 768 768 if (0 < buf_int_len) { 769 if ((ret = ps->str_write(buf, buf_int_len, ps->data)) < 0) 769 if ((ret = ps->str_write(buf, buf_int_len, ps->data)) < 0) 770 770 return -1; 771 771 … … 773 773 774 774 /* Print trailing zeros of the integral part of the number. */ 775 if ((ret = print_padding('0', int_len - buf_int_len, ps)) < 0) 775 if ((ret = print_padding('0', int_len - buf_int_len, ps)) < 0) 776 776 return -1; 777 777 } else { 778 778 /* Single leading integer 0. */ 779 779 char ch = '0'; 780 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 780 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 781 781 return -1; 782 782 } … … 788 788 char ch = '.'; 789 789 790 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 790 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 791 791 return -1; 792 792 … … 794 794 795 795 /* Print leading zeros of the fractional part of the number. */ 796 if ((ret = print_padding('0', leading_frac_zeros, ps)) < 0) 796 if ((ret = print_padding('0', leading_frac_zeros, ps)) < 0) 797 797 return -1; 798 798 … … 801 801 /* Print significant digits of the fractional part of the number. */ 802 802 if (0 < signif_frac_figs) { 803 if ((ret = ps->str_write(buf_frac, signif_frac_figs, ps->data)) < 0) 803 if ((ret = ps->str_write(buf_frac, signif_frac_figs, ps->data)) < 0) 804 804 return -1; 805 805 … … 808 808 809 809 /* Print trailing zeros of the fractional part of the number. */ 810 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 810 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 811 811 return -1; 812 812 … … 816 816 /* Trailing padding. */ 817 817 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 818 if ((ret = print_padding(' ', padding_len, ps)) < 0) 818 if ((ret = print_padding(' ', padding_len, ps)) < 0) 819 819 return -1; 820 820 … … 826 826 827 827 828 /** Convert, format and print a double according to the %f specifier. 828 /** Convert, format and print a double according to the %f specifier. 829 829 * 830 830 * @param g Double to print. … … 832 832 * decimal point will be printed unless the flag 833 833 * __PRINTF_FLAG_DECIMALPT is specified. 834 * @param width Minimum number of characters to display. Pads 834 * @param width Minimum number of characters to display. Pads 835 835 * with '0' or ' ' depending on the set flags; 836 836 * @param flags Printf flags. … … 839 839 * @return The number of characters printed; negative on failure. 840 840 */ 841 static int print_double_fixed(double g, int precision, int width, uint32_t flags, 841 static int print_double_fixed(double g, int precision, int width, uint32_t flags, 842 842 printf_spec_t *ps) 843 843 { … … 854 854 if (val.is_special) { 855 855 return print_special(val, width, flags, ps); 856 } 856 } 857 857 858 858 char buf[MAX_DOUBLE_STR_BUF_SIZE]; … … 864 864 865 865 if (0 <= precision) { 866 /* 866 /* 867 867 * Request one more digit so we can round the result. The last 868 * digit it returns may have an error of at most +/- 1. 868 * digit it returns may have an error of at most +/- 1. 869 869 */ 870 val_str.len = double_to_fixed_str(val, -1, precision + 1, buf, buf_size, 870 val_str.len = double_to_fixed_str(val, -1, precision + 1, buf, buf_size, 871 871 &val_str.dec_exp); 872 872 873 /* 874 * Round using the last digit to produce precision fractional digits. 875 * If less than precision+1 fractional digits were output the last 876 * digit is definitely inaccurate so also round to get rid of it. 873 /* 874 * Round using the last digit to produce precision fractional digits. 875 * If less than precision+1 fractional digits were output the last 876 * digit is definitely inaccurate so also round to get rid of it. 877 877 */ 878 878 fp_round_up(buf, &val_str.len, &val_str.dec_exp); … … 901 901 char exp_ch = (flags & __PRINTF_FLAG_BIGCHARS) ? 'E' : 'e'; 902 902 903 if ((ret = ps->str_write(&exp_ch, 1, ps->data)) < 0) 903 if ((ret = ps->str_write(&exp_ch, 1, ps->data)) < 0) 904 904 return -1; 905 905 … … 925 925 const char *exp_str_start = &exp_str[3] - exp_len; 926 926 927 if ((ret = ps->str_write(exp_str_start, exp_len, ps->data)) < 0) 927 if ((ret = ps->str_write(exp_str_start, exp_len, ps->data)) < 0) 928 928 return -1; 929 929 … … 934 934 935 935 936 /** Format and print the double string repressentation according 937 * to the %e specifier. 938 */ 939 static int print_double_str_scient(double_str_t *val_str, int precision, 936 /** Format and print the double string repressentation according 937 * to the %e specifier. 938 */ 939 static int print_double_str_scient(double_str_t *val_str, int precision, 940 940 int width, uint32_t flags, printf_spec_t *ps) 941 941 { … … 972 972 973 973 if (!(flags & (__PRINTF_FLAG_LEFTALIGNED | __PRINTF_FLAG_ZEROPADDED))) { 974 if ((ret = print_padding(' ', padding_len, ps)) < 0) 974 if ((ret = print_padding(' ', padding_len, ps)) < 0) 975 975 return -1; 976 976 … … 979 979 980 980 if (sign) { 981 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 981 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 982 982 return -1; 983 983 … … 986 986 987 987 if (flags & __PRINTF_FLAG_ZEROPADDED) { 988 if ((ret = print_padding('0', padding_len, ps)) < 0) 988 if ((ret = print_padding('0', padding_len, ps)) < 0) 989 989 return -1; 990 990 … … 993 993 994 994 /* Single leading integer. */ 995 if ((ret = ps->str_write(buf, 1, ps->data)) < 0) 995 if ((ret = ps->str_write(buf, 1, ps->data)) < 0) 996 996 return -1; 997 997 … … 1002 1002 char ch = '.'; 1003 1003 1004 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 1004 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 1005 1005 return -1; 1006 1006 … … 1009 1009 /* Print significant digits of the fractional part of the number. */ 1010 1010 if (0 < signif_frac_figs) { 1011 if ((ret = ps->str_write(buf + 1, signif_frac_figs, ps->data)) < 0) 1011 if ((ret = ps->str_write(buf + 1, signif_frac_figs, ps->data)) < 0) 1012 1012 return -1; 1013 1013 … … 1016 1016 1017 1017 /* Print trailing zeros of the fractional part of the number. */ 1018 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 1018 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 1019 1019 return -1; 1020 1020 … … 1023 1023 1024 1024 /* Print the exponent. */ 1025 if ((ret = print_exponent(exp_val, flags, ps)) < 0) 1025 if ((ret = print_exponent(exp_val, flags, ps)) < 0) 1026 1026 return -1; 1027 1027 … … 1029 1029 1030 1030 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 1031 if ((ret = print_padding(' ', padding_len, ps)) < 0) 1031 if ((ret = print_padding(' ', padding_len, ps)) < 0) 1032 1032 return -1; 1033 1033 … … 1039 1039 1040 1040 1041 /** Convert, format and print a double according to the %e specifier. 1042 * 1043 * Note that if g is large, the output may be huge (3e100 prints 1041 /** Convert, format and print a double according to the %e specifier. 1042 * 1043 * Note that if g is large, the output may be huge (3e100 prints 1044 1044 * with at least 100 digits). 1045 1045 * … … 1054 1054 * __PRINTF_FLAG_DECIMALPT is specified. If negative 1055 1055 * the shortest accurate number will be printed. 1056 * @param width Minimum number of characters to display. Pads 1056 * @param width Minimum number of characters to display. Pads 1057 1057 * with '0' or ' ' depending on the set flags; 1058 1058 * @param flags Printf flags. … … 1061 1061 * @return The number of characters printed; negative on failure. 1062 1062 */ 1063 static int print_double_scientific(double g, int precision, int width, 1063 static int print_double_scientific(double g, int precision, int width, 1064 1064 uint32_t flags, printf_spec_t *ps) 1065 1065 { … … 1072 1072 if (val.is_special) { 1073 1073 return print_special(val, width, flags, ps); 1074 } 1074 } 1075 1075 1076 1076 char buf[MAX_DOUBLE_STR_BUF_SIZE]; … … 1082 1082 1083 1083 if (0 <= precision) { 1084 /* 1085 * Request one more digit (in addition to the leading integer) 1086 * so we can round the result. The last digit it returns may 1087 * have an error of at most +/- 1. 1084 /* 1085 * Request one more digit (in addition to the leading integer) 1086 * so we can round the result. The last digit it returns may 1087 * have an error of at most +/- 1. 1088 1088 */ 1089 val_str.len = double_to_fixed_str(val, precision + 2, -1, buf, buf_size, 1089 val_str.len = double_to_fixed_str(val, precision + 2, -1, buf, buf_size, 1090 1090 &val_str.dec_exp); 1091 1091 1092 /* 1093 * Round the extra digit to produce precision+1 significant digits. 1094 * If less than precision+2 significant digits were returned the last 1095 * digit is definitely inaccurate so also round to get rid of it. 1092 /* 1093 * Round the extra digit to produce precision+1 significant digits. 1094 * If less than precision+2 significant digits were returned the last 1095 * digit is definitely inaccurate so also round to get rid of it. 1096 1096 */ 1097 1097 fp_round_up(buf, &val_str.len, &val_str.dec_exp); … … 1113 1113 1114 1114 1115 /** Convert, format and print a double according to the %g specifier. 1116 * 1117 * %g style chooses between %f and %e. 1115 /** Convert, format and print a double according to the %g specifier. 1116 * 1117 * %g style chooses between %f and %e. 1118 1118 * 1119 1119 * @param g Double to print. … … 1121 1121 * any leading zeros from this count. If negative 1122 1122 * the shortest accurate number will be printed. 1123 * @param width Minimum number of characters to display. Pads 1123 * @param width Minimum number of characters to display. Pads 1124 1124 * with '0' or ' ' depending on the set flags; 1125 1125 * @param flags Printf flags. … … 1128 1128 * @return The number of characters printed; negative on failure. 1129 1129 */ 1130 static int print_double_generic(double g, int precision, int width, 1130 static int print_double_generic(double g, int precision, int width, 1131 1131 uint32_t flags, printf_spec_t *ps) 1132 1132 { … … 1135 1135 if (val.is_special) { 1136 1136 return print_special(val, width, flags, ps); 1137 } 1137 } 1138 1138 1139 1139 char buf[MAX_DOUBLE_STR_BUF_SIZE]; … … 1144 1144 /* Honor the user requested number of significant digits. */ 1145 1145 if (0 <= precision) { 1146 /* 1147 * Do a quick and dirty conversion of a single digit to determine 1146 /* 1147 * Do a quick and dirty conversion of a single digit to determine 1148 1148 * the decimal exponent. 1149 1149 */ … … 1155 1155 if (-4 <= dec_exp && dec_exp < precision) { 1156 1156 precision = precision - (dec_exp + 1); 1157 return print_double_fixed(g, precision, width, 1157 return print_double_fixed(g, precision, width, 1158 1158 flags | __PRINTF_FLAG_NOFRACZEROS, ps); 1159 1159 } else { 1160 1160 --precision; 1161 return print_double_scientific(g, precision, width, 1161 return print_double_scientific(g, precision, width, 1162 1162 flags | __PRINTF_FLAG_NOFRACZEROS, ps); 1163 1163 } … … 1194 1194 1195 1195 1196 /** Convert, format and print a double according to the specifier. 1196 /** Convert, format and print a double according to the specifier. 1197 1197 * 1198 1198 * Depending on the specifier it prints the double using the styles … … 1206 1206 * the shortest accurate number will be printed for style %g; 1207 1207 * negative precision defaults to 6 for styles %f, %e. 1208 * @param width Minimum number of characters to display. Pads 1208 * @param width Minimum number of characters to display. Pads 1209 1209 * with '0' or ' ' depending on the set flags; 1210 1210 * @param flags Printf flags. … … 1213 1213 * @return The number of characters printed; negative on failure. 1214 1214 */ 1215 static int print_double(double g, char spec, int precision, int width, 1215 static int print_double(double g, char spec, int precision, int width, 1216 1216 uint32_t flags, printf_spec_t *ps) 1217 1217 { … … 1542 1542 case 'E': 1543 1543 case 'e': 1544 retval = print_double(va_arg(ap, double), uc, precision, 1544 retval = print_double(va_arg(ap, double), uc, precision, 1545 1545 width, flags, ps); 1546 1546 -
uspace/lib/c/generic/malloc.c
rdf6ded8 r1b20da0 216 216 /* 217 217 * Malloc never switches fibrils while the heap is locked. 218 * Similarly, it never creates new threads from within the 219 * locked region. Therefore, if there are no other threads 220 * except this one, the whole operation will complete without 218 * Similarly, it never creates new threads from within the 219 * locked region. Therefore, if there are no other threads 220 * except this one, the whole operation will complete without 221 221 * any interruptions. 222 222 */ … … 232 232 /* 233 233 * Malloc never switches fibrils while the heap is locked. 234 * Similarly, it never creates new threads from within the 235 * locked region. Therefore, if there are no other threads 236 * except this one, the whole operation will complete without 234 * Similarly, it never creates new threads from within the 235 * locked region. Therefore, if there are no other threads 236 * except this one, the whole operation will complete without 237 237 * any interruptions. 238 238 */ -
uspace/lib/c/generic/mem.c
rdf6ded8 r1b20da0 197 197 198 198 /* Non-overlapping? */ 199 if (dst >= src + n || src >= dst + n) { 199 if (dst >= src + n || src >= dst + n) { 200 200 return memcpy(dst, src, n); 201 201 } -
uspace/lib/c/generic/power_of_ten.c
rdf6ded8 r1b20da0 39 39 * 40 40 * The smallest interval of binary exponents computed by hand 41 * is [-1083, 987]. Add 200 (exponent change > 3 * 64 bits) 41 * is [-1083, 987]. Add 200 (exponent change > 3 * 64 bits) 42 42 * to both bounds just to be on the safe side; ie [-1283, 1187]. 43 43 */ … … 144 144 145 145 146 /** 147 * Returns the smallest precomputed power of 10 such that 146 /** 147 * Returns the smallest precomputed power of 10 such that 148 148 * binary_exp <= power_of_10.bin_exp 149 149 * where 150 * 10^decimal_exp = power_of_10.significand * 2^bin_exp 150 * 10^decimal_exp = power_of_10.significand * 2^bin_exp 151 151 * with an error of 0.5 ulp in the significand. 152 152 */ … … 160 160 assert(min_bin_exp <= binary_exp && binary_exp <= max_bin_exp); 161 161 162 /* 163 * Binary exponent difference between adjacent powers of 10 162 /* 163 * Binary exponent difference between adjacent powers of 10 164 164 * is lg(10^8) = 26.575. The starting search index seed_idx 165 165 * undershoots the actual position by less than 1.6%, ie it 166 166 * skips 26.575/27 = 98.4% of all the smaller powers. This 167 * translates to at most three extra tests. 167 * translates to at most three extra tests. 168 168 */ 169 169 int seed_idx = (binary_exp - min_bin_exp) / max_bin_exp_diff; -
uspace/lib/c/generic/rcu.c
rdf6ded8 r1b20da0 32 32 /** 33 33 * @file 34 * 35 * User space RCU is based on URCU utilizing signals [1]. This 36 * implementation does not however signal each thread of the process 34 * 35 * User space RCU is based on URCU utilizing signals [1]. This 36 * implementation does not however signal each thread of the process 37 37 * to issue a memory barrier. Instead, we introduced a syscall that 38 38 * issues memory barriers (via IPIs) on cpus that are running threads 39 39 * of the current process. First, it does not require us to schedule 40 * and run every thread of the process. Second, IPIs are less intrusive 40 * and run every thread of the process. Second, IPIs are less intrusive 41 41 * than switching contexts and entering user space. 42 * 42 * 43 43 * This algorithm is further modified to require a single instead of 44 44 * two reader group changes per grace period. Signal-URCU flips 45 * the reader group and waits for readers of the previous group 45 * the reader group and waits for readers of the previous group 46 46 * twice in succession in order to wait for new readers that were 47 * delayed and mistakenly associated with the previous reader group. 47 * delayed and mistakenly associated with the previous reader group. 48 48 * The modified algorithm ensures that the new reader group is 49 49 * always empty (by explicitly waiting for it to become empty). 50 50 * Only then does it flip the reader group and wait for preexisting 51 51 * readers of the old reader group (invariant of SRCU [2, 3]). 52 * 53 * 52 * 53 * 54 54 * [1] User-level implementations of read-copy update, 55 55 * 2012, appendix 56 56 * http://www.rdrop.com/users/paulmck/RCU/urcu-supp-accepted.2011.08.30a.pdf 57 * 57 * 58 58 * [2] linux/kernel/srcu.c in Linux 3.5-rc2, 59 59 * 2012 60 60 * http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/kernel/srcu.c?v=linux-3.5-rc2-ccs-1.8.3 61 61 * 62 * [3] [RFC PATCH 5/5 single-thread-version] implement 62 * [3] [RFC PATCH 5/5 single-thread-version] implement 63 63 * per-domain single-thread state machine, 64 64 * 2012, Lai … … 162 162 163 163 /** Registers a fibril so it may start using RCU read sections. 164 * 164 * 165 165 * A fibril must be registered with rcu before it can enter RCU critical 166 166 * sections delineated by rcu_read_lock() and rcu_read_unlock(). … … 178 178 179 179 /** Deregisters a fibril that had been using RCU read sections. 180 * 180 * 181 181 * A fibril must be deregistered before it exits if it had 182 182 * been registered with rcu via rcu_register_fibril(). … … 186 186 assert(fibril_rcu.registered); 187 187 188 /* 188 /* 189 189 * Forcefully unlock any reader sections. The fibril is exiting 190 190 * so it is not holding any references to data protected by the 191 * rcu section. Therefore, it is safe to unlock. Otherwise, 191 * rcu section. Therefore, it is safe to unlock. Otherwise, 192 192 * rcu_synchronize() would wait indefinitely. 193 193 */ … … 202 202 } 203 203 204 /** Delimits the start of an RCU reader critical section. 205 * 206 * RCU reader sections may be nested. 204 /** Delimits the start of an RCU reader critical section. 205 * 206 * RCU reader sections may be nested. 207 207 */ 208 208 void rcu_read_lock(void) … … 252 252 lock_sync(blocking_mode); 253 253 254 /* 255 * Exit early if we were stuck waiting for the mutex for a full grace 254 /* 255 * Exit early if we were stuck waiting for the mutex for a full grace 256 256 * period. Started waiting during gp_in_progress (or gp_in_progress + 1 257 257 * if the value propagated to this cpu too late) so wait for the next … … 267 267 ++ACCESS_ONCE(rcu.cur_gp); 268 268 269 /* 270 * Pairs up with MB_FORCE_L (ie CC_BAR_L). Makes changes prior 271 * to rcu_synchronize() visible to new readers. 269 /* 270 * Pairs up with MB_FORCE_L (ie CC_BAR_L). Makes changes prior 271 * to rcu_synchronize() visible to new readers. 272 272 */ 273 273 memory_barrier(); /* MB_A */ 274 274 275 /* 276 * Pairs up with MB_A. 277 * 275 /* 276 * Pairs up with MB_A. 277 * 278 278 * If the memory barrier is issued before CC_BAR_L in the target 279 279 * thread, it pairs up with MB_A and the thread sees all changes 280 280 * prior to rcu_synchronize(). Ie any reader sections are new 281 * rcu readers. 282 * 281 * rcu readers. 282 * 283 283 * If the memory barrier is issued after CC_BAR_L, it pairs up 284 284 * with MB_B and it will make the most recent nesting_cnt visible 285 285 * in this thread. Since the reader may have already accessed 286 286 * memory protected by RCU (it ran instructions passed CC_BAR_L), 287 * it is a preexisting reader. Seeing the most recent nesting_cnt 287 * it is a preexisting reader. Seeing the most recent nesting_cnt 288 288 * ensures the thread will be identified as a preexisting reader 289 289 * and we will wait for it in wait_for_readers(old_reader_group). … … 291 291 force_mb_in_all_threads(); /* MB_FORCE_L */ 292 292 293 /* 293 /* 294 294 * Pairs with MB_FORCE_L (ie CC_BAR_L, CC_BAR_U) and makes the most 295 295 * current fibril.nesting_cnt visible to this cpu. … … 321 321 static void force_mb_in_all_threads(void) 322 322 { 323 /* 324 * Only issue barriers in running threads. The scheduler will 323 /* 324 * Only issue barriers in running threads. The scheduler will 325 325 * execute additional memory barriers when switching to threads 326 326 * of the process that are currently not running. … … 339 339 while (!list_empty(&rcu.fibrils_list)) { 340 340 list_foreach_safe(rcu.fibrils_list, fibril_it, next_fibril) { 341 fibril_rcu_data_t *fib = member_to_inst(fibril_it, 341 fibril_rcu_data_t *fib = member_to_inst(fibril_it, 342 342 fibril_rcu_data_t, link); 343 343 … … 393 393 assert(rcu.sync_lock.locked); 394 394 395 /* 395 /* 396 396 * Blocked threads have a priority over fibrils when accessing sync(). 397 397 * Pass the lock onto a waiting thread. … … 421 421 { 422 422 assert(rcu.sync_lock.locked); 423 /* 424 * Release the futex to avoid deadlocks in singlethreaded apps 425 * but keep sync locked. 423 /* 424 * Release the futex to avoid deadlocks in singlethreaded apps 425 * but keep sync locked. 426 426 */ 427 427 futex_up(&rcu.sync_lock.futex); … … 446 446 static size_t get_other_group(size_t group) 447 447 { 448 if (group == RCU_GROUP_A) 448 if (group == RCU_GROUP_A) 449 449 return RCU_GROUP_B; 450 450 else -
uspace/lib/c/generic/rtld/dynamic.c
rdf6ded8 r1b20da0 30 30 * @brief 31 31 * @{ 32 */ 32 */ 33 33 /** 34 34 * @file -
uspace/lib/c/generic/rtld/module.c
rdf6ded8 r1b20da0 30 30 * @brief 31 31 * @{ 32 */ 32 */ 33 33 /** 34 34 * @file -
uspace/lib/c/generic/rtld/rtld.c
rdf6ded8 r1b20da0 30 30 * @brief 31 31 * @{ 32 */ 32 */ 33 33 /** 34 34 * @file -
uspace/lib/c/generic/rtld/symbol.c
rdf6ded8 r1b20da0 30 30 * @brief 31 31 * @{ 32 */ 32 */ 33 33 /** 34 34 * @file … … 113 113 * @param name Name of the symbol to search for. 114 114 * @param start Module in which to start the search.. 115 * @param mod (output) Will be filled with a pointer to the module 115 * @param mod (output) Will be filled with a pointer to the module 116 116 * that contains the symbol. 117 117 */ … … 131 131 */ 132 132 133 /* Mark all vertices (modules) as unvisited */ 133 /* Mark all vertices (modules) as unvisited */ 134 134 modules_untag(start->rtld); 135 135 … … 193 193 * @param flags @c ssf_none or @c ssf_noexec to not look for the symbol 194 194 * in the executable program. 195 * @param mod (output) Will be filled with a pointer to the module 195 * @param mod (output) Will be filled with a pointer to the module 196 196 * that contains the symbol. 197 197 */ -
uspace/lib/c/generic/str.c
rdf6ded8 r1b20da0 688 688 break; 689 689 690 ++len; 690 ++len; 691 691 } 692 692 -
uspace/lib/c/generic/task.c
rdf6ded8 r1b20da0 202 202 if (rc != EOK) 203 203 goto error; 204 } 204 } 205 205 206 206 /* Load the program. */ … … 313 313 314 314 /** Setup waiting for a task. 315 * 315 * 316 316 * If the task finishes after this call succeeds, it is guaranteed that 317 317 * task_wait(wait, &texit, &retval) will return correct return value for … … 361 361 * @param texit Store type of task exit here. 362 362 * @param retval Store return value of the task here. 363 * 363 * 364 364 * @return EOK on success, else error code. 365 365 */ … … 391 391 * @param texit Store type of task exit here. 392 392 * @param retval Store return value of the task here. 393 * 393 * 394 394 * @return EOK on success, else error code. 395 395 */ -
uspace/lib/c/generic/vfs/canonify.c
rdf6ded8 r1b20da0 27 27 */ 28 28 29 /** @addtogroup libc 29 /** @addtogroup libc 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** … … 338 338 if (lenp) 339 339 *lenp = (size_t)((tlcomp.stop - tfsl.start) + 1); 340 return tfsl.start; 340 return tfsl.start; 341 341 default: 342 342 abort(); -
uspace/lib/c/generic/vfs/inbox.c
rdf6ded8 r1b20da0 27 27 */ 28 28 29 /** @addtogroup libc 29 /** @addtogroup libc 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** … … 131 131 case 1: 132 132 return -1; 133 } 133 } 134 134 } 135 135 -
uspace/lib/c/generic/vfs/vfs.c
rdf6ded8 r1b20da0 63 63 * - functions that operate on integer file handles, such as: 64 64 * vfs_walk(), vfs_open(), vfs_read(), vfs_link(), ... 65 * 65 * 66 66 * - functions that operate on paths, such as: 67 67 * vfs_lookup(), vfs_link_path(), vfs_unlink_path(), vfs_rename_path(), ... … … 1079 1079 } 1080 1080 1081 /** Get file information 1081 /** Get file information 1082 1082 * 1083 1083 * @param path File path to get information about … … 1143 1143 vfs_put(file); 1144 1144 1145 return rc; 1145 return rc; 1146 1146 } 1147 1147
Note:
See TracChangeset
for help on using the changeset viewer.