Changeset 1787e527 in mainline for uspace/lib
- Timestamp:
- 2009-11-16T21:22:54Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5ebdf94
- Parents:
- fcbd1be (diff), 9c70ed6 (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. - Location:
- uspace/lib
- Files:
-
- 11 added
- 1 deleted
- 47 edited
- 2 moved
-
libblock/Makefile (modified) (1 diff)
-
libblock/Makefile.build (added)
-
libblock/Makefile.common (added)
-
libblock/libblock.c (modified) (32 diffs)
-
libblock/libblock.h (modified) (3 diffs)
-
libc/Makefile (modified) (1 diff)
-
libc/Makefile.build (added)
-
libc/Makefile.common (added)
-
libc/Makefile.toolchain (modified) (5 diffs)
-
libc/arch/amd64/Makefile.inc (modified) (1 diff)
-
libc/arch/arm32/Makefile.inc (modified) (2 diffs)
-
libc/arch/ia32/Makefile.inc (modified) (1 diff)
-
libc/arch/ia32/_link.ld.in (modified) (4 diffs)
-
libc/arch/ia32/include/syscall.h (modified) (1 diff)
-
libc/arch/ia32/src/entry.s (modified) (3 diffs)
-
libc/arch/ia32/src/syscall.S (modified) (3 diffs)
-
libc/arch/ia64/Makefile.inc (modified) (1 diff)
-
libc/arch/ia64/include/atomic.h (modified) (2 diffs)
-
libc/arch/mips32/Makefile.inc (modified) (2 diffs)
-
libc/arch/mips32eb/Makefile.inc (modified) (1 diff)
-
libc/arch/mips32eb/include/stackarg.h (deleted)
-
libc/arch/ppc32/Makefile.inc (modified) (2 diffs)
-
libc/arch/sparc64/Makefile.inc (modified) (1 diff)
-
libc/generic/async.c (modified) (17 diffs)
-
libc/generic/devmap.c (modified) (4 diffs)
-
libc/generic/fibril_sync.c (modified) (8 diffs)
-
libc/generic/io/console.c (modified) (2 diffs)
-
libc/generic/io/klog.c (modified) (1 diff)
-
libc/generic/ipc.c (modified) (6 diffs)
-
libc/generic/libc.c (modified) (1 diff)
-
libc/generic/loader.c (modified) (4 diffs)
-
libc/generic/malloc.c (modified) (1 diff)
-
libc/generic/task.c (modified) (2 diffs)
-
libc/generic/vfs/vfs.c (modified) (19 diffs)
-
libc/include/async.h (modified) (2 diffs)
-
libc/include/async_priv.h (moved) (moved from uspace/lib/libc/arch/ia32/include/stackarg.h ) (3 diffs)
-
libc/include/fcntl.h (modified) (1 diff)
-
libc/include/fibril_sync.h (modified) (2 diffs)
-
libc/include/io/console.h (modified) (1 diff)
-
libc/include/ipc/bd.h (modified) (1 diff)
-
libc/include/ipc/ipc.h (modified) (2 diffs)
-
libc/include/ipc/loader.h (modified) (1 diff)
-
libc/include/ipc/vfs.h (modified) (1 diff)
-
libc/include/loader/loader.h (modified) (1 diff)
-
libc/include/loader/pcb.h (modified) (1 diff)
-
libc/include/malloc.h (modified) (1 diff)
-
libc/include/stdarg.h (modified) (1 diff)
-
libc/include/unistd.h (modified) (1 diff)
-
libfs/Makefile (modified) (1 diff)
-
libfs/Makefile.build (added)
-
libfs/Makefile.common (added)
-
libfs/libfs.c (modified) (24 diffs)
-
libfs/libfs.h (modified) (1 diff)
-
softfloat/Makefile (modified) (2 diffs)
-
softfloat/Makefile.build (added)
-
softfloat/Makefile.common (added)
-
softint/Makefile (modified) (2 diffs)
-
softint/Makefile.build (added)
-
softint/Makefile.common (added)
-
softint/generic/multiplication.c (added)
-
softint/include/multiplication.h (moved) (moved from kernel/arch/ia32/include/arg.h ) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/Makefile
rfcbd1be r1787e527 28 28 # 29 29 30 ## Common compiler flags 31 # 30 include Makefile.common 32 31 33 LIBC_PREFIX = ../libc 32 .PHONY: all clean 34 33 35 ## Setup toolchain 36 # 37 38 include $(LIBC_PREFIX)/Makefile.toolchain 39 40 CFLAGS += -Iinclude 41 42 ## Sources 43 # 44 45 SOURCES = \ 46 libblock.c 47 48 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 49 50 .PHONY: all clean depend 51 52 all: libblock.a 53 54 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 55 37 56 38 clean: 57 -rm -f libblock.a Makefile.depend39 rm -f $(DEPEND) $(DEPEND_PREV) $(LIBBLOCK) 58 40 find . -name '*.o' -follow -exec rm \{\} \; 59 60 depend:61 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null62 63 libblock.a: depend $(OBJECTS)64 $(AR) rc libblock.a $(OBJECTS)65 66 %.o: %.c67 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ -
uspace/lib/libblock/libblock.c
rfcbd1be r1787e527 50 50 #include <adt/list.h> 51 51 #include <adt/hash_table.h> 52 #include <macros.h> 52 53 #include <mem.h> 53 54 … … 62 63 typedef struct { 63 64 fibril_mutex_t lock; 64 size_t block_size; /**< Block size. */65 size_t lblock_size; /**< Logical block size. */ 65 66 unsigned block_count; /**< Total number of blocks. */ 66 67 unsigned blocks_cached; /**< Number of cached blocks. */ … … 74 75 dev_handle_t dev_handle; 75 76 int dev_phone; 76 fibril_mutex_t com _area_lock;77 void *com _area;78 size_t com _size;77 fibril_mutex_t comm_area_lock; 78 void *comm_area; 79 size_t comm_size; 79 80 void *bb_buf; 80 off_t bb_off;81 size_t bb_size;81 bn_t bb_addr; 82 size_t pblock_size; /**< Physical block size. */ 82 83 cache_t *cache; 83 84 } devcon_t; 84 85 85 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size); 86 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size); 86 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt); 87 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt); 88 static int get_block_size(int dev_phone, size_t *bsize); 87 89 88 90 static devcon_t *devcon_search(dev_handle_t dev_handle) … … 102 104 } 103 105 104 static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area,105 size_t com_size)106 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize, 107 void *comm_area, size_t comm_size) 106 108 { 107 109 link_t *cur; 108 110 devcon_t *devcon; 111 112 if (comm_size < bsize) 113 return EINVAL; 109 114 110 115 devcon = malloc(sizeof(devcon_t)); … … 115 120 devcon->dev_handle = dev_handle; 116 121 devcon->dev_phone = dev_phone; 117 fibril_mutex_initialize(&devcon->com _area_lock);118 devcon->com _area = com_area;119 devcon->com _size = com_size;122 fibril_mutex_initialize(&devcon->comm_area_lock); 123 devcon->comm_area = comm_area; 124 devcon->comm_size = comm_size; 120 125 devcon->bb_buf = NULL; 121 devcon->bb_ off= 0;122 devcon-> bb_size = 0;126 devcon->bb_addr = 0; 127 devcon->pblock_size = bsize; 123 128 devcon->cache = NULL; 124 129 … … 144 149 } 145 150 146 int block_init(dev_handle_t dev_handle, size_t com _size)151 int block_init(dev_handle_t dev_handle, size_t comm_size) 147 152 { 148 153 int rc; 149 154 int dev_phone; 150 void *com_area; 151 152 com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE, 155 void *comm_area; 156 size_t bsize; 157 158 comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 153 159 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 154 if (!com _area) {160 if (!comm_area) { 155 161 return ENOMEM; 156 162 } … … 158 164 dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING); 159 165 if (dev_phone < 0) { 160 munmap(com _area, com_size);166 munmap(comm_area, comm_size); 161 167 return dev_phone; 162 168 } 163 169 164 rc = ipc_share_out_start(dev_phone, com_area,170 rc = async_share_out_start(dev_phone, comm_area, 165 171 AS_AREA_READ | AS_AREA_WRITE); 166 172 if (rc != EOK) { 167 munmap(com _area, com_size);173 munmap(comm_area, comm_size); 168 174 ipc_hangup(dev_phone); 169 175 return rc; 170 176 } 171 172 rc = devcon_add(dev_handle, dev_phone, com_area, com_size); 177 178 if (get_block_size(dev_phone, &bsize) != EOK) { 179 munmap(comm_area, comm_size); 180 ipc_hangup(dev_phone); 181 return rc; 182 } 183 184 rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size); 173 185 if (rc != EOK) { 174 munmap(com _area, com_size);186 munmap(comm_area, comm_size); 175 187 ipc_hangup(dev_phone); 176 188 return rc; … … 195 207 } 196 208 197 munmap(devcon->com _area, devcon->com_size);209 munmap(devcon->comm_area, devcon->comm_size); 198 210 ipc_hangup(devcon->dev_phone); 199 211 … … 201 213 } 202 214 203 int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size)215 int block_bb_read(dev_handle_t dev_handle, bn_t ba) 204 216 { 205 217 void *bb_buf; … … 211 223 if (devcon->bb_buf) 212 224 return EEXIST; 213 bb_buf = malloc( size);225 bb_buf = malloc(devcon->pblock_size); 214 226 if (!bb_buf) 215 227 return ENOMEM; 216 217 fibril_mutex_lock(&devcon->com _area_lock);218 rc = read_block (devcon, 0, size);228 229 fibril_mutex_lock(&devcon->comm_area_lock); 230 rc = read_blocks(devcon, 0, 1); 219 231 if (rc != EOK) { 220 fibril_mutex_unlock(&devcon->com _area_lock);232 fibril_mutex_unlock(&devcon->comm_area_lock); 221 233 free(bb_buf); 222 234 return rc; 223 235 } 224 memcpy(bb_buf, devcon->com _area,size);225 fibril_mutex_unlock(&devcon->com _area_lock);236 memcpy(bb_buf, devcon->comm_area, devcon->pblock_size); 237 fibril_mutex_unlock(&devcon->comm_area_lock); 226 238 227 239 devcon->bb_buf = bb_buf; 228 devcon->bb_off = off; 229 devcon->bb_size = size; 240 devcon->bb_addr = ba; 230 241 231 242 return EOK; … … 275 286 fibril_mutex_initialize(&cache->lock); 276 287 list_initialize(&cache->free_head); 277 cache-> block_size = size;288 cache->lblock_size = size; 278 289 cache->block_count = blocks; 279 290 cache->blocks_cached = 0; 280 291 cache->mode = mode; 292 293 /* No block size translation a.t.m. */ 294 assert(cache->lblock_size == devcon->pblock_size); 281 295 282 296 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, … … 306 320 b->refcnt = 1; 307 321 b->dirty = false; 322 b->toxic = false; 308 323 fibril_rwlock_initialize(&b->contents_lock); 309 324 link_initialize(&b->free_link); … … 313 328 /** Instantiate a block in memory and get a reference to it. 314 329 * 330 * @param block Pointer to where the function will store the 331 * block pointer on success. 315 332 * @param dev_handle Device handle of the block device. 316 333 * @param boff Block offset. … … 319 336 * device. 320 337 * 321 * @return Block structure.322 */ 323 block_t *block_get(dev_handle_t dev_handle, bn_t boff, int flags)338 * @return EOK on success or a negative error code. 339 */ 340 int block_get(block_t **block, dev_handle_t dev_handle, bn_t boff, int flags) 324 341 { 325 342 devcon_t *devcon; … … 328 345 link_t *l; 329 346 unsigned long key = boff; 330 bn_t oboff;347 int rc; 331 348 332 349 devcon = devcon_search(dev_handle); … … 336 353 337 354 cache = devcon->cache; 355 356 retry: 357 rc = EOK; 358 b = NULL; 359 338 360 fibril_mutex_lock(&cache->lock); 339 361 l = hash_table_find(&cache->block_hash, &key); … … 346 368 if (b->refcnt++ == 0) 347 369 list_remove(&b->free_link); 370 if (b->toxic) 371 rc = EIO; 348 372 fibril_mutex_unlock(&b->lock); 349 373 fibril_mutex_unlock(&cache->lock); … … 352 376 * The block was not found in the cache. 353 377 */ 354 int rc;355 bool sync = false;356 357 378 if (cache_can_grow(cache)) { 358 379 /* … … 364 385 if (!b) 365 386 goto recycle; 366 b->data = malloc(cache-> block_size);387 b->data = malloc(cache->lblock_size); 367 388 if (!b->data) { 368 389 free(b); … … 376 397 unsigned long temp_key; 377 398 recycle: 378 assert(!list_empty(&cache->free_head)); 399 if (list_empty(&cache->free_head)) { 400 fibril_mutex_unlock(&cache->lock); 401 rc = ENOMEM; 402 goto out; 403 } 379 404 l = cache->free_head.next; 380 list_remove(l);381 405 b = list_get_instance(l, block_t, free_link); 382 sync = b->dirty; 383 oboff = b->boff; 406 407 fibril_mutex_lock(&b->lock); 408 if (b->dirty) { 409 /* 410 * The block needs to be written back to the 411 * device before it changes identity. Do this 412 * while not holding the cache lock so that 413 * concurrency is not impeded. Also move the 414 * block to the end of the free list so that we 415 * do not slow down other instances of 416 * block_get() draining the free list. 417 */ 418 list_remove(&b->free_link); 419 list_append(&b->free_link, &cache->free_head); 420 fibril_mutex_unlock(&cache->lock); 421 fibril_mutex_lock(&devcon->comm_area_lock); 422 memcpy(devcon->comm_area, b->data, b->size); 423 rc = write_blocks(devcon, b->boff, 1); 424 fibril_mutex_unlock(&devcon->comm_area_lock); 425 if (rc != EOK) { 426 /* 427 * We did not manage to write the block 428 * to the device. Keep it around for 429 * another try. Hopefully, we will grab 430 * another block next time. 431 */ 432 fibril_mutex_unlock(&b->lock); 433 goto retry; 434 } 435 b->dirty = false; 436 if (!fibril_mutex_trylock(&cache->lock)) { 437 /* 438 * Somebody is probably racing with us. 439 * Unlock the block and retry. 440 */ 441 fibril_mutex_unlock(&b->lock); 442 goto retry; 443 } 444 445 } 446 fibril_mutex_unlock(&b->lock); 447 448 /* 449 * Unlink the block from the free list and the hash 450 * table. 451 */ 452 list_remove(&b->free_link); 384 453 temp_key = b->boff; 385 454 hash_table_remove(&cache->block_hash, &temp_key, 1); … … 388 457 block_initialize(b); 389 458 b->dev_handle = dev_handle; 390 b->size = cache-> block_size;459 b->size = cache->lblock_size; 391 460 b->boff = boff; 392 461 hash_table_insert(&cache->block_hash, &key, &b->hash_link); … … 394 463 /* 395 464 * Lock the block before releasing the cache lock. Thus we don't 396 * kill concur ent operations on the cache while doing I/O on the397 * block.465 * kill concurrent operations on the cache while doing I/O on 466 * the block. 398 467 */ 399 468 fibril_mutex_lock(&b->lock); 400 469 fibril_mutex_unlock(&cache->lock); 401 470 402 if (sync) {403 /*404 * The block is dirty and needs to be written back to405 * the device before we can read in the new contents.406 */407 fibril_mutex_lock(&devcon->com_area_lock);408 memcpy(devcon->com_area, b->data, b->size);409 rc = write_block(devcon, oboff, cache->block_size);410 assert(rc == EOK);411 fibril_mutex_unlock(&devcon->com_area_lock);412 }413 471 if (!(flags & BLOCK_FLAGS_NOREAD)) { 414 472 /* … … 416 474 * the new contents from the device. 417 475 */ 418 fibril_mutex_lock(&devcon->com_area_lock); 419 rc = read_block(devcon, b->boff, cache->block_size); 420 assert(rc == EOK); 421 memcpy(b->data, devcon->com_area, cache->block_size); 422 fibril_mutex_unlock(&devcon->com_area_lock); 423 } 476 fibril_mutex_lock(&devcon->comm_area_lock); 477 rc = read_blocks(devcon, b->boff, 1); 478 memcpy(b->data, devcon->comm_area, cache->lblock_size); 479 fibril_mutex_unlock(&devcon->comm_area_lock); 480 if (rc != EOK) 481 b->toxic = true; 482 } else 483 rc = EOK; 424 484 425 485 fibril_mutex_unlock(&b->lock); 426 486 } 427 return b; 487 out: 488 if ((rc != EOK) && b) { 489 assert(b->toxic); 490 (void) block_put(b); 491 b = NULL; 492 } 493 *block = b; 494 return rc; 428 495 } 429 496 … … 433 500 * 434 501 * @param block Block of which a reference is to be released. 435 */ 436 void block_put(block_t *block) 502 * 503 * @return EOK on success or a negative error code. 504 */ 505 int block_put(block_t *block) 437 506 { 438 507 devcon_t *devcon = devcon_search(block->dev_handle); 439 508 cache_t *cache; 440 int rc; 509 unsigned blocks_cached; 510 enum cache_mode mode; 511 int rc = EOK; 441 512 442 513 assert(devcon); … … 444 515 445 516 cache = devcon->cache; 517 518 retry: 519 fibril_mutex_lock(&cache->lock); 520 blocks_cached = cache->blocks_cached; 521 mode = cache->mode; 522 fibril_mutex_unlock(&cache->lock); 523 524 /* 525 * Determine whether to sync the block. Syncing the block is best done 526 * when not holding the cache lock as it does not impede concurrency. 527 * Since the situation may have changed when we unlocked the cache, the 528 * blocks_cached and mode variables are mere hints. We will recheck the 529 * conditions later when the cache lock is held again. 530 */ 531 fibril_mutex_lock(&block->lock); 532 if (block->toxic) 533 block->dirty = false; /* will not write back toxic block */ 534 if (block->dirty && (block->refcnt == 1) && 535 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 536 fibril_mutex_lock(&devcon->comm_area_lock); 537 memcpy(devcon->comm_area, block->data, block->size); 538 rc = write_blocks(devcon, block->boff, 1); 539 fibril_mutex_unlock(&devcon->comm_area_lock); 540 block->dirty = false; 541 } 542 fibril_mutex_unlock(&block->lock); 543 446 544 fibril_mutex_lock(&cache->lock); 447 545 fibril_mutex_lock(&block->lock); … … 449 547 /* 450 548 * Last reference to the block was dropped. Either free the 451 * block or put it on the free list. 549 * block or put it on the free list. In case of an I/O error, 550 * free the block. 452 551 */ 453 if (cache->blocks_cached > CACHE_HI_WATERMARK) { 552 if ((cache->blocks_cached > CACHE_HI_WATERMARK) || 553 (rc != EOK)) { 454 554 /* 455 * Currently there are too many cached blocks. 555 * Currently there are too many cached blocks or there 556 * was an I/O error when writing the block back to the 557 * device. 456 558 */ 457 559 if (block->dirty) { 458 fibril_mutex_lock(&devcon->com_area_lock); 459 memcpy(devcon->com_area, block->data, 460 block->size); 461 rc = write_block(devcon, block->boff, 462 block->size); 463 assert(rc == EOK); 464 fibril_mutex_unlock(&devcon->com_area_lock); 560 /* 561 * We cannot sync the block while holding the 562 * cache lock. Release everything and retry. 563 */ 564 block->refcnt++; 565 fibril_mutex_unlock(&block->lock); 566 fibril_mutex_unlock(&cache->lock); 567 goto retry; 465 568 } 466 569 /* … … 473 576 cache->blocks_cached--; 474 577 fibril_mutex_unlock(&cache->lock); 475 return ;578 return rc; 476 579 } 477 580 /* 478 581 * Put the block on the free list. 479 582 */ 583 if (cache->mode != CACHE_MODE_WB && block->dirty) { 584 /* 585 * We cannot sync the block while holding the cache 586 * lock. Release everything and retry. 587 */ 588 block->refcnt++; 589 fibril_mutex_unlock(&block->lock); 590 fibril_mutex_unlock(&cache->lock); 591 goto retry; 592 } 480 593 list_append(&block->free_link, &cache->free_head); 481 if (cache->mode != CACHE_MODE_WB && block->dirty) {482 fibril_mutex_lock(&devcon->com_area_lock);483 memcpy(devcon->com_area, block->data, block->size);484 rc = write_block(devcon, block->boff, block->size);485 assert(rc == EOK);486 fibril_mutex_unlock(&devcon->com_area_lock);487 488 block->dirty = false;489 }490 594 } 491 595 fibril_mutex_unlock(&block->lock); 492 596 fibril_mutex_unlock(&cache->lock); 597 598 return rc; 493 599 } 494 600 … … 508 614 */ 509 615 int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen, 510 off_t *pos, void *dst, size_t size , size_t block_size)616 off_t *pos, void *dst, size_t size) 511 617 { 512 618 off_t offset = 0; 513 619 size_t left = size; 514 devcon_t *devcon = devcon_search(dev_handle); 515 assert(devcon); 516 517 fibril_mutex_lock(&devcon->com_area_lock); 620 size_t block_size; 621 devcon_t *devcon; 622 623 devcon = devcon_search(dev_handle); 624 assert(devcon); 625 block_size = devcon->pblock_size; 626 627 fibril_mutex_lock(&devcon->comm_area_lock); 518 628 while (left > 0) { 519 629 size_t rd; … … 529 639 * destination buffer. 530 640 */ 531 memcpy(dst + offset, devcon->com _area + *bufpos, rd);641 memcpy(dst + offset, devcon->comm_area + *bufpos, rd); 532 642 offset += rd; 533 643 *bufpos += rd; … … 540 650 int rc; 541 651 542 rc = read_block (devcon, *pos / block_size, block_size);652 rc = read_blocks(devcon, *pos / block_size, 1); 543 653 if (rc != EOK) { 544 fibril_mutex_unlock(&devcon->com _area_lock);654 fibril_mutex_unlock(&devcon->comm_area_lock); 545 655 return rc; 546 656 } … … 550 660 } 551 661 } 552 fibril_mutex_unlock(&devcon->com _area_lock);662 fibril_mutex_unlock(&devcon->comm_area_lock); 553 663 554 664 return EOK; 555 665 } 556 666 557 /** Read block from block device. 667 /** Read blocks directly from device (bypass cache). 668 * 669 * @param dev_handle Device handle of the block device. 670 * @param ba Address of first block. 671 * @param cnt Number of blocks. 672 * @param src Buffer for storing the data. 673 * 674 * @return EOK on success or negative error code on failure. 675 */ 676 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf) 677 { 678 devcon_t *devcon; 679 int rc; 680 681 devcon = devcon_search(dev_handle); 682 assert(devcon); 683 684 fibril_mutex_lock(&devcon->comm_area_lock); 685 686 rc = read_blocks(devcon, ba, cnt); 687 if (rc == EOK) 688 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt); 689 690 fibril_mutex_unlock(&devcon->comm_area_lock); 691 692 return rc; 693 } 694 695 /** Write blocks directly to device (bypass cache). 696 * 697 * @param dev_handle Device handle of the block device. 698 * @param ba Address of first block. 699 * @param cnt Number of blocks. 700 * @param src The data to be written. 701 * 702 * @return EOK on success or negative error code on failure. 703 */ 704 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, 705 const void *data) 706 { 707 devcon_t *devcon; 708 int rc; 709 710 devcon = devcon_search(dev_handle); 711 assert(devcon); 712 713 fibril_mutex_lock(&devcon->comm_area_lock); 714 715 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 716 rc = read_blocks(devcon, ba, cnt); 717 718 fibril_mutex_unlock(&devcon->comm_area_lock); 719 720 return rc; 721 } 722 723 /** Get device block size. 724 * 725 * @param dev_handle Device handle of the block device. 726 * @param bsize Output block size. 727 * 728 * @return EOK on success or negative error code on failure. 729 */ 730 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize) 731 { 732 devcon_t *devcon; 733 734 devcon = devcon_search(dev_handle); 735 assert(devcon); 736 737 return get_block_size(devcon->dev_phone, bsize); 738 } 739 740 /** Read blocks from block device. 558 741 * 559 742 * @param devcon Device connection. 560 * @param b off Block index.561 * @param block_size Block size.743 * @param ba Address of first block. 744 * @param cnt Number of blocks. 562 745 * @param src Buffer for storing the data. 563 746 * 564 747 * @return EOK on success or negative error code on failure. 565 748 */ 566 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size) 567 { 568 ipcarg_t retval; 749 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt) 750 { 569 751 int rc; 570 752 571 753 assert(devcon); 572 rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size, 573 &retval); 574 if ((rc != EOK) || (retval != EOK)) 575 return (rc != EOK ? rc : (int) retval); 576 577 return EOK; 754 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba), 755 UPPER32(ba), cnt); 756 return rc; 578 757 } 579 758 … … 581 760 * 582 761 * @param devcon Device connection. 583 * @param b off Block index.584 * @param block_size Block size.762 * @param ba Address of first block. 763 * @param cnt Number of blocks. 585 764 * @param src Buffer containing the data to write. 586 765 * 587 766 * @return EOK on success or negative error code on failure. 588 767 */ 589 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size) 590 { 591 ipcarg_t retval; 768 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt) 769 { 592 770 int rc; 593 771 594 772 assert(devcon); 595 rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size, 596 &retval); 597 if ((rc != EOK) || (retval != EOK)) 598 return (rc != EOK ? rc : (int) retval); 599 600 return EOK; 773 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba), 774 UPPER32(ba), cnt); 775 return rc; 776 } 777 778 /** Get block size used by the device. */ 779 static int get_block_size(int dev_phone, size_t *bsize) 780 { 781 ipcarg_t bs; 782 int rc; 783 784 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 785 if (rc == EOK) 786 *bsize = (size_t) bs; 787 788 return rc; 601 789 } 602 790 -
uspace/lib/libblock/libblock.h
rfcbd1be r1787e527 60 60 #define BLOCK_FLAGS_NOREAD 1 61 61 62 typedef u nsignedbn_t; /**< Block number type. */62 typedef uint64_t bn_t; /**< Block number type. */ 63 63 64 64 typedef struct block { … … 69 69 /** If true, the block needs to be written back to the block device. */ 70 70 bool dirty; 71 /** If true, the blcok does not contain valid data. */ 72 bool toxic; 71 73 /** Readers / Writer lock protecting the contents of the block. */ 72 74 fibril_rwlock_t contents_lock; … … 96 98 extern void block_fini(dev_handle_t); 97 99 98 extern int block_bb_read(dev_handle_t, off_t, size_t);100 extern int block_bb_read(dev_handle_t, bn_t); 99 101 extern void *block_bb_get(dev_handle_t); 100 102 101 103 extern int block_cache_init(dev_handle_t, size_t, unsigned, enum cache_mode); 102 104 103 extern block_t *block_get(dev_handle_t, bn_t, int);104 extern voidblock_put(block_t *);105 extern int block_get(block_t **, dev_handle_t, bn_t, int); 106 extern int block_put(block_t *); 105 107 106 108 extern int block_seqread(dev_handle_t, off_t *, size_t *, off_t *, void *, 107 size_t, size_t); 109 size_t); 110 111 extern int block_get_bsize(dev_handle_t, size_t *); 112 extern int block_read_direct(dev_handle_t, bn_t, size_t, void *); 113 extern int block_write_direct(dev_handle_t, bn_t, size_t, const void *); 108 114 109 115 #endif -
uspace/lib/libc/Makefile
rfcbd1be r1787e527 27 27 # 28 28 29 ## Common compiler flags 30 # 29 include Makefile.common 31 30 32 LIBC_PREFIX = $(shell pwd) 33 SOFTINT_PREFIX = ../softint 31 .PHONY: all clean 34 32 35 36 ## Setup toolchain 37 # 38 39 include $(LIBC_PREFIX)/Makefile.toolchain 40 41 42 ## Sources 43 # 44 45 GENERIC_SOURCES = \ 46 generic/libc.c \ 47 generic/ddi.c \ 48 generic/as.c \ 49 generic/cap.c \ 50 generic/devmap.c \ 51 generic/event.c \ 52 generic/errno.c \ 53 generic/mem.c \ 54 generic/string.c \ 55 generic/fibril.c \ 56 generic/fibril_sync.c \ 57 generic/pcb.c \ 58 generic/smc.c \ 59 generic/thread.c \ 60 generic/tls.c \ 61 generic/task.c \ 62 generic/futex.c \ 63 generic/io/asprintf.c \ 64 generic/io/io.c \ 65 generic/io/printf.c \ 66 generic/io/klog.c \ 67 generic/io/snprintf.c \ 68 generic/io/vprintf.c \ 69 generic/io/vsnprintf.c \ 70 generic/io/printf_core.c \ 71 generic/io/console.c \ 72 generic/malloc.c \ 73 generic/sysinfo.c \ 74 generic/ipc.c \ 75 generic/async.c \ 76 generic/loader.c \ 77 generic/getopt.c \ 78 generic/adt/list.o \ 79 generic/adt/hash_table.o \ 80 generic/time.c \ 81 generic/err.c \ 82 generic/stdlib.c \ 83 generic/mman.c \ 84 generic/udebug.c \ 85 generic/vfs/vfs.c \ 86 generic/vfs/canonify.c 87 88 ARCH_SOURCES += \ 89 arch/$(UARCH)/src/entry.s \ 90 arch/$(UARCH)/src/thread_entry.s 91 92 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 93 ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) 94 OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS) 95 96 .PHONY: all clean depend kerninc 97 98 all: kerninc libc.a arch/$(UARCH)/_link.ld 99 100 kerninc: 101 ln -sfn ../../../../kernel/generic/include include/kernel 102 ln -sfn kernel/arch include/arch 103 ln -sfn ../arch/$(UARCH)/include include/libarch 104 105 -include Makefile.depend 33 all: ../../../Makefile.config ../../../config.h ../../../config.defs 34 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 35 $(MAKE) -f Makefile.build 106 36 107 37 clean: 108 -rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend 109 find generic/ arch/$(UARCH)/ -name '*.o' -follow -exec rm \{\} \; 110 111 depend: kerninc 112 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null 113 114 libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 115 $(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 116 117 arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in 118 $(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ 119 120 %.o: %.S 121 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 122 123 %.o: %.s 124 $(AS) $(AFLAGS) $< -o $@ 125 126 %.o: %.c 127 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 38 rm -f $(DEPEND) $(DEPEND_PREV) $(INCLUDE_KERNEL) $(INCLUDE_ARCH) $(INCLUDE_LIBARCH) $(LIBC) arch/*/_link.ld 39 find generic/ arch/*/ -name '*.o' -follow -exec rm \{\} \; -
uspace/lib/libc/Makefile.toolchain
rfcbd1be r1787e527 27 27 # 28 28 29 CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \29 GCC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ 30 30 -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \ 31 -finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \ 32 -Wmissing-prototypes -Werror-implicit-function-declaration -nostdlib \ 33 -nostdinc -pipe -g -D__$(ENDIANESS)__ 31 -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \ 32 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ 33 -Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__ 34 35 ICC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ 36 -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \ 37 -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \ 38 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ 39 -Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__ 40 41 CLANG_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \ 42 -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \ 43 -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \ 44 -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \ 45 -Werror-implicit-function-declaration -pipe -g -arch $(CLANG_ARCH) \ 46 -D__$(ENDIANESS)__ 47 34 48 LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a 35 49 AFLAGS = … … 45 59 # 46 60 47 -include $(LIBC_PREFIX)/../../../Makefile.config48 -include $(LIBC_PREFIX)/../../../config.defs49 -include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc61 include $(LIBC_PREFIX)/../../../Makefile.config 62 include $(LIBC_PREFIX)/../../../config.defs 63 include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc 50 64 51 65 ## Simple detection of the host system … … 64 78 # 65 79 80 ifeq ($(COMPILER),gcc_cross) 81 CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc 82 GCC = $(CC) 83 AS = $(TOOLCHAIN_DIR)/$(TARGET)-as 84 LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld 85 AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar 86 OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy 87 OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump 88 CFLAGS = $(GCC_CFLAGS) 89 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 90 endif 91 66 92 ifeq ($(COMPILER),gcc_native) 67 93 CC = gcc 94 GCC = $(CC) 68 95 AS = $(BINUTILS_PREFIX)as 69 96 LD = $(BINUTILS_PREFIX)ld … … 71 98 OBJCOPY = $(BINUTILS_PREFIX)objcopy 72 99 OBJDUMP = $(BINUTILS_PREFIX)objdump 100 CFLAGS = $(GCC_CFLAGS) 73 101 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 74 102 endif 75 103 76 ifeq ($(COMPILER),icc _native)104 ifeq ($(COMPILER),icc) 77 105 CC = icc 106 GCC = gcc 78 107 AS = as 79 108 LD = ld … … 81 110 OBJCOPY = objcopy 82 111 OBJDUMP = objdump 112 CFLAGS = $(ICC_CFLAGS) 83 113 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 84 114 endif 85 115 86 ifeq ($(COMPILER),gcc_cross) 87 CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc 88 AS = $(TOOLCHAIN_DIR)/$(TARGET)-as 89 LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld 90 AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar 91 OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy 92 OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump 116 ifeq ($(COMPILER),clang) 117 CC = clang 118 GCC = gcc 119 AS = $(BINUTILS_PREFIX)as 120 LD = $(BINUTILS_PREFIX)ld 121 AR = $(BINUTILS_PREFIX)ar 122 OBJCOPY = $(BINUTILS_PREFIX)objcopy 123 OBJDUMP = $(BINUTILS_PREFIX)objdump 124 CFLAGS = $(CLANG_CFLAGS) 93 125 DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) 94 126 endif -
uspace/lib/libc/arch/amd64/Makefile.inc
rfcbd1be r1787e527 31 31 32 32 TARGET = amd64-linux-gnu 33 CLANG_ARCH = x86_64 33 34 TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin 34 35 -
uspace/lib/libc/arch/arm32/Makefile.inc
rfcbd1be r1787e527 32 32 33 33 TARGET = arm-linux-gnu 34 TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm /bin34 TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm32/bin 35 35 36 36 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ … … 39 39 arch/$(UARCH)/src/eabi.S 40 40 41 CFLAGS += -ffixed-r9 -mtp=soft41 GCC_CFLAGS += -ffixed-r9 -mtp=soft 42 42 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a 43 43 -
uspace/lib/libc/arch/ia32/Makefile.inc
rfcbd1be r1787e527 31 31 32 32 TARGET = i686-pc-linux-gnu 33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin 33 CLANG_ARCH = i386 34 TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia32/bin 34 35 35 36 ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ -
uspace/lib/libc/arch/ia32/_link.ld.in
rfcbd1be r1787e527 3 3 4 4 PHDRS { 5 text PT_LOAD FLAGS(5);5 text PT_LOAD FLAGS(5); 6 6 data PT_LOAD FLAGS(6); 7 7 } … … 9 9 SECTIONS { 10 10 . = 0x1000 + SIZEOF_HEADERS; 11 11 12 12 .init : { 13 13 *(.init); 14 14 } :text 15 15 16 .text : { 16 17 *(.text); 17 *(.rodata*);18 *(.rodata*); 18 19 } :text 19 20 20 21 . = . + 0x1000; 21 22 22 23 .data : { 23 24 *(.data); 24 25 } :data 26 25 27 .tdata : { 26 28 _tdata_start = .; 27 29 *(.tdata); 30 *(.gnu.linkonce.tb.*); 28 31 _tdata_end = .; 29 32 _tbss_start = .; … … 31 34 _tbss_end = .; 32 35 } :data 36 33 37 _tls_alignment = ALIGNOF(.tdata); 38 34 39 .bss : { 35 *(COMMON);36 *(.bss);40 *(COMMON); 41 *(.bss); 37 42 } :data 38 43 39 44 . = ALIGN(0x1000); 45 40 46 _heap = .; 41 47 … … 43 49 *(*); 44 50 } 45 46 51 } -
uspace/lib/libc/arch/ia32/include/syscall.h
rfcbd1be r1787e527 40 40 #include <kernel/syscall/syscall.h> 41 41 42 #define __syscall0 __syscall_ sysenter43 #define __syscall1 __syscall_ sysenter44 #define __syscall2 __syscall_ sysenter45 #define __syscall3 __syscall_ sysenter46 #define __syscall4 __syscall_ sysenter47 #define __syscall5 __syscall_ int48 #define __syscall6 __syscall_ int42 #define __syscall0 __syscall_fast_func 43 #define __syscall1 __syscall_fast_func 44 #define __syscall2 __syscall_fast_func 45 #define __syscall3 __syscall_fast_func 46 #define __syscall4 __syscall_fast_func 47 #define __syscall5 __syscall_slow 48 #define __syscall6 __syscall_slow 49 49 50 50 extern sysarg_t 51 __syscall_sysenter(const sysarg_t,const sysarg_t, const sysarg_t, const sysarg_t,52 const sysarg_t, const sysarg_t, const syscall_t);51 (* __syscall_fast_func)(const sysarg_t, const sysarg_t, const sysarg_t, 52 const sysarg_t, const sysarg_t, const sysarg_t, const syscall_t); 53 53 54 54 extern sysarg_t 55 __syscall_ int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,56 const sysarg_t, const sysarg_t, const syscall_t);55 __syscall_slow(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t, 56 const sysarg_t, const sysarg_t, const syscall_t); 57 57 58 58 #endif -
uspace/lib/libc/arch/ia32/src/entry.s
rfcbd1be r1787e527 27 27 # 28 28 29 INTEL_CPUID_STANDARD = 1 30 INTEL_SEP = 11 31 29 32 .section .init, "ax" 30 33 … … 35 38 ## User-space task entry point 36 39 # 37 # %e bxcontains the PCB pointer40 # %edi contains the PCB pointer 38 41 # 39 42 __entry: … … 44 47 # Do not set %gs, it contains descriptor that can see TLS 45 48 49 # Detect the mechanism used for making syscalls 50 movl $(INTEL_CPUID_STANDARD), %eax 51 cpuid 52 bt $(INTEL_SEP), %edx 53 jnc 0f 54 leal __syscall_fast_func, %eax 55 movl $__syscall_fast, (%eax) 56 0: 57 46 58 # Pass the PCB pointer to __main as the first argument 47 pushl %e bx59 pushl %edi 48 60 call __main 49 61 -
uspace/lib/libc/arch/ia32/src/syscall.S
rfcbd1be r1787e527 27 27 # 28 28 29 .data 30 31 .global __syscall_fast_func 32 __syscall_fast_func: 33 .long __syscall_slow 34 29 35 .text 30 36 … … 35 41 * could benefit from this and not save unused registers on the stack. 36 42 */ 37 .global __syscall_ int38 __syscall_ int:43 .global __syscall_slow 44 __syscall_slow: 39 45 pushl %ebx 40 46 pushl %esi … … 64 70 * segment, otherwise the SYSENTER wouldn't work in the first place). 65 71 */ 66 .global __syscall_ sysenter67 __syscall_ sysenter:72 .global __syscall_fast 73 __syscall_fast: 68 74 pushl %ebx 69 75 pushl %esi -
uspace/lib/libc/arch/ia64/Makefile.inc
rfcbd1be r1787e527 38 38 arch/$(UARCH)/src/ddi.c 39 39 40 CFLAGS += -fno-unwind-tables40 GCC_CFLAGS += -fno-unwind-tables 41 41 LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a 42 42 -
uspace/lib/libc/arch/ia64/include/atomic.h
rfcbd1be r1787e527 27 27 */ 28 28 29 /** @addtogroup libcia64 29 /** @addtogroup libcia64 30 30 * @{ 31 31 */ … … 36 36 #define LIBC_ia64_ATOMIC_H_ 37 37 38 /** Atomic addition. 39 * 40 * @param val Atomic value. 41 * @param imm Value to add. 42 * 43 * @return Value before addition. 44 */ 45 static inline long atomic_add(atomic_t *val, int imm) 38 static inline void atomic_inc(atomic_t *val) 46 39 { 47 40 long v; 41 42 asm volatile ( 43 "fetchadd8.rel %[v] = %[count], 1\n" 44 : [v] "=r" (v), 45 [count] "+m" (val->count) 46 ); 47 } 48 48 49 asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm)); 50 49 static inline void atomic_dec(atomic_t *val) 50 { 51 long v; 52 53 asm volatile ( 54 "fetchadd8.rel %[v] = %[count], -1\n" 55 : [v] "=r" (v), 56 [count] "+m" (val->count) 57 ); 58 } 59 60 static inline long atomic_preinc(atomic_t *val) 61 { 62 long v; 63 64 asm volatile ( 65 "fetchadd8.rel %[v] = %[count], 1\n" 66 : [v] "=r" (v), 67 [count] "+m" (val->count) 68 ); 69 70 return (v + 1); 71 } 72 73 static inline long atomic_predec(atomic_t *val) 74 { 75 long v; 76 77 asm volatile ( 78 "fetchadd8.rel %[v] = %[count], -1\n" 79 : [v] "=r" (v), 80 [count] "+m" (val->count) 81 ); 82 83 return (v - 1); 84 } 85 86 static inline long atomic_postinc(atomic_t *val) 87 { 88 long v; 89 90 asm volatile ( 91 "fetchadd8.rel %[v] = %[count], 1\n" 92 : [v] "=r" (v), 93 [count] "+m" (val->count) 94 ); 95 51 96 return v; 52 97 } 53 98 54 static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); } 55 static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); } 56 57 static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; } 58 static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; } 59 60 static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); } 61 static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); } 99 static inline long atomic_postdec(atomic_t *val) 100 { 101 long v; 102 103 asm volatile ( 104 "fetchadd8.rel %[v] = %[count], -1\n" 105 : [v] "=r" (v), 106 [count] "+m" (val->count) 107 ); 108 109 return v; 110 } 62 111 63 112 #endif -
uspace/lib/libc/arch/mips32/Makefile.inc
rfcbd1be r1787e527 31 31 32 32 TARGET = mipsel-linux-gnu 33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips el/bin33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32/bin 34 34 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ … … 37 37 arch/$(UARCH)/src/tls.c 38 38 39 CFLAGS += -mips339 GCC_CFLAGS += -mips3 40 40 41 41 ENDIANESS = LE -
uspace/lib/libc/arch/mips32eb/Makefile.inc
rfcbd1be r1787e527 31 31 32 32 TARGET = mips-linux-gnu 33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips /bin33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb/bin 34 34 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ 36 arch/$(UARCH)/src/fibril.S \37 arch/$(UARCH)/src/tls.c36 arch/$(UARCH)/src/fibril.S \ 37 arch/$(UARCH)/src/tls.c 38 38 39 CFLAGS += -mips339 GCC_CFLAGS += -mips3 40 40 LFLAGS += -N 41 41 -
uspace/lib/libc/arch/ppc32/Makefile.inc
rfcbd1be r1787e527 31 31 32 32 TARGET = ppc-linux-gnu 33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc /bin33 TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc32/bin 34 34 35 35 ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ … … 37 37 arch/$(UARCH)/src/tls.c 38 38 39 CFLAGS += -mcpu=powerpc -msoft-float -m3239 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 40 40 AFLAGS += -a32 41 41 LFLAGS += -N -
uspace/lib/libc/arch/sparc64/Makefile.inc
rfcbd1be r1787e527 36 36 arch/$(UARCH)/src/tls.c 37 37 38 CFLAGS += -mcpu=ultrasparc -m6438 GCC_CFLAGS += -mcpu=ultrasparc -m64 39 39 LFLAGS += -no-check-sections -N 40 40 -
uspace/lib/libc/generic/async.c
rfcbd1be r1787e527 83 83 * 84 84 * callid = async_get_call(&call); 85 * handle_call(callid, call);85 * somehow_handle_the_call(callid, call); 86 86 * ipc_answer_2(callid, 1, 2, 3); 87 87 * … … 94 94 #include <futex.h> 95 95 #include <async.h> 96 #include <async_priv.h> 96 97 #include <fibril.h> 97 98 #include <stdio.h> … … 107 108 atomic_t async_futex = FUTEX_INITIALIZER; 108 109 109 /** Structures of this type represent a waiting fibril. */ 110 typedef struct { 111 /** Expiration time. */ 112 struct timeval expires; 113 114 /** If true, this struct is in the timeout list. */ 115 bool inlist; 116 117 /** Timeout list link. */ 118 link_t link; 119 120 /** Identification of and link to the waiting fibril. */ 121 fid_t fid; 122 123 /** If true, this fibril is currently active. */ 124 bool active; 125 126 /** If true, we have timed out. */ 127 bool timedout; 128 } awaiter_t; 110 /** Number of threads waiting for IPC in the kernel. */ 111 atomic_t threads_in_ipc_wait = { 0 }; 129 112 130 113 typedef struct { … … 250 233 * 251 234 */ 252 static voidinsert_timeout(awaiter_t *wd)253 { 254 wd->t imedout= false;255 wd-> inlist = true;235 void async_insert_timeout(awaiter_t *wd) 236 { 237 wd->to_event.occurred = false; 238 wd->to_event.inlist = true; 256 239 257 240 link_t *tmp = timeout_list.next; 258 241 while (tmp != &timeout_list) { 259 awaiter_t *cur = list_get_instance(tmp, awaiter_t, link); 260 261 if (tv_gteq(&cur->expires, &wd->expires)) 242 awaiter_t *cur; 243 244 cur = list_get_instance(tmp, awaiter_t, to_event.link); 245 if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires)) 262 246 break; 263 264 247 tmp = tmp->next; 265 248 } 266 249 267 list_append(&wd-> link, tmp);250 list_append(&wd->to_event.link, tmp); 268 251 } 269 252 … … 312 295 313 296 /* If in timeout list, remove it */ 314 if (conn->wdata. inlist) {315 conn->wdata. inlist = false;316 list_remove(&conn->wdata. link);297 if (conn->wdata.to_event.inlist) { 298 conn->wdata.to_event.inlist = false; 299 list_remove(&conn->wdata.to_event.link); 317 300 } 318 301 … … 402 385 403 386 if (usecs) { 404 gettimeofday(&conn->wdata. expires, NULL);405 tv_add(&conn->wdata. expires, usecs);387 gettimeofday(&conn->wdata.to_event.expires, NULL); 388 tv_add(&conn->wdata.to_event.expires, usecs); 406 389 } else 407 conn->wdata. inlist = false;390 conn->wdata.to_event.inlist = false; 408 391 409 392 /* If nothing in queue, wait until something arrives */ 410 393 while (list_empty(&conn->msg_queue)) { 411 394 if (usecs) 412 insert_timeout(&conn->wdata);395 async_insert_timeout(&conn->wdata); 413 396 414 397 conn->wdata.active = false; … … 427 410 */ 428 411 futex_down(&async_futex); 429 if ((usecs) && (conn->wdata.t imedout)412 if ((usecs) && (conn->wdata.to_event.occurred) 430 413 && (list_empty(&conn->msg_queue))) { 431 414 /* If we timed out -> exit */ … … 622 605 link_t *cur = timeout_list.next; 623 606 while (cur != &timeout_list) { 624 awaiter_t *waiter = list_get_instance(cur, awaiter_t, link); 625 626 if (tv_gt(&waiter->expires, &tv)) 607 awaiter_t *waiter; 608 609 waiter = list_get_instance(cur, awaiter_t, to_event.link); 610 if (tv_gt(&waiter->to_event.expires, &tv)) 627 611 break; 628 612 629 613 cur = cur->next; 630 631 list_remove(&waiter-> link);632 waiter-> inlist = false;633 waiter->t imedout= true;614 615 list_remove(&waiter->to_event.link); 616 waiter->to_event.inlist = false; 617 waiter->to_event.occurred = true; 634 618 635 619 /* … … 668 652 if (!list_empty(&timeout_list)) { 669 653 awaiter_t *waiter = list_get_instance(timeout_list.next, 670 awaiter_t, link);654 awaiter_t, to_event.link); 671 655 672 656 struct timeval tv; 673 657 gettimeofday(&tv, NULL); 674 658 675 if (tv_gteq(&tv, &waiter-> expires)) {659 if (tv_gteq(&tv, &waiter->to_event.expires)) { 676 660 futex_up(&async_futex); 677 661 handle_expired_timeouts(); 678 662 continue; 679 663 } else 680 timeout = tv_sub(&waiter->expires, &tv); 664 timeout = tv_sub(&waiter->to_event.expires, 665 &tv); 681 666 } else 682 667 timeout = SYNCH_NO_TIMEOUT; 683 668 684 669 futex_up(&async_futex); 670 671 atomic_inc(&threads_in_ipc_wait); 685 672 686 673 ipc_call_t call; … … 688 675 SYNCH_FLAGS_NONE); 689 676 677 atomic_dec(&threads_in_ipc_wait); 678 690 679 if (!callid) { 691 680 handle_expired_timeouts(); … … 775 764 776 765 /* Remove message from timeout list */ 777 if (msg->wdata. inlist)778 list_remove(&msg->wdata. link);766 if (msg->wdata.to_event.inlist) 767 list_remove(&msg->wdata.to_event.link); 779 768 780 769 msg->done = true; … … 815 804 msg->dataptr = dataptr; 816 805 817 msg->wdata. inlist = false;806 msg->wdata.to_event.inlist = false; 818 807 /* We may sleep in the next method, but it will use its own mechanism */ 819 808 msg->wdata.active = true; … … 855 844 msg->dataptr = dataptr; 856 845 857 msg->wdata. inlist = false;846 msg->wdata.to_event.inlist = false; 858 847 /* We may sleep in next method, but it will use its own mechanism */ 859 848 msg->wdata.active = true; … … 884 873 msg->wdata.fid = fibril_get_id(); 885 874 msg->wdata.active = false; 886 msg->wdata. inlist = false;875 msg->wdata.to_event.inlist = false; 887 876 888 877 /* Leave the async_futex locked when entering this function */ … … 922 911 } 923 912 924 gettimeofday(&msg->wdata. expires, NULL);925 tv_add(&msg->wdata. expires, timeout);913 gettimeofday(&msg->wdata.to_event.expires, NULL); 914 tv_add(&msg->wdata.to_event.expires, timeout); 926 915 927 916 msg->wdata.fid = fibril_get_id(); 928 917 msg->wdata.active = false; 929 insert_timeout(&msg->wdata);918 async_insert_timeout(&msg->wdata); 930 919 931 920 /* Leave the async_futex locked when entering this function */ … … 963 952 msg->wdata.active = false; 964 953 965 gettimeofday(&msg->wdata. expires, NULL);966 tv_add(&msg->wdata. expires, timeout);954 gettimeofday(&msg->wdata.to_event.expires, NULL); 955 tv_add(&msg->wdata.to_event.expires, timeout); 967 956 968 957 futex_down(&async_futex); 969 958 970 insert_timeout(&msg->wdata);959 async_insert_timeout(&msg->wdata); 971 960 972 961 /* Leave the async_futex locked when entering this function */ … … 1098 1087 } 1099 1088 1089 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework. 1090 * 1091 * @param phoneid Phone that will be used to contact the receiving side. 1092 * @param dst Destination address space area base. 1093 * @param size Size of the destination address space area. 1094 * @param arg User defined argument. 1095 * @param flags Storage where the received flags will be stored. Can be 1096 * NULL. 1097 * 1098 * @return Zero on success or a negative error code from errno.h. 1099 */ 1100 int async_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg, 1101 int *flags) 1102 { 1103 int res; 1104 sysarg_t tmp_flags; 1105 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, 1106 (ipcarg_t) size, arg, NULL, &tmp_flags); 1107 if (flags) 1108 *flags = tmp_flags; 1109 return res; 1110 } 1111 1112 /** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework. 1113 * 1114 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls 1115 * so that the user doesn't have to remember the meaning of each IPC argument. 1116 * 1117 * So far, this wrapper is to be used from within a connection fibril. 1118 * 1119 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will 1120 * be stored. 1121 * @param size Destination address space area size. 1122 * 1123 * @return Non-zero on success, zero on failure. 1124 */ 1125 int async_share_in_receive(ipc_callid_t *callid, size_t *size) 1126 { 1127 ipc_call_t data; 1128 1129 assert(callid); 1130 assert(size); 1131 1132 *callid = async_get_call(&data); 1133 if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN) 1134 return 0; 1135 *size = (size_t) IPC_GET_ARG2(data); 1136 return 1; 1137 } 1138 1139 /** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework. 1140 * 1141 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1142 * so that the user doesn't have to remember the meaning of each IPC argument. 1143 * 1144 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1145 * @param src Source address space base. 1146 * @param flags Flags to be used for sharing. Bits can be only cleared. 1147 * 1148 * @return Zero on success or a value from @ref errno.h on failure. 1149 */ 1150 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags) 1151 { 1152 return ipc_share_in_finalize(callid, src, flags); 1153 } 1154 1155 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework. 1156 * 1157 * @param phoneid Phone that will be used to contact the receiving side. 1158 * @param src Source address space area base address. 1159 * @param flags Flags to be used for sharing. Bits can be only cleared. 1160 * 1161 * @return Zero on success or a negative error code from errno.h. 1162 */ 1163 int async_share_out_start(int phoneid, void *src, int flags) 1164 { 1165 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, 1166 (ipcarg_t) flags); 1167 } 1168 1169 /** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework. 1170 * 1171 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls 1172 * so that the user doesn't have to remember the meaning of each IPC argument. 1173 * 1174 * So far, this wrapper is to be used from within a connection fibril. 1175 * 1176 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will 1177 * be stored. 1178 * @param size Storage where the source address space area size will be 1179 * stored. 1180 * @param flags Storage where the sharing flags will be stored. 1181 * 1182 * @return Non-zero on success, zero on failure. 1183 */ 1184 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags) 1185 { 1186 ipc_call_t data; 1187 1188 assert(callid); 1189 assert(size); 1190 assert(flags); 1191 1192 *callid = async_get_call(&data); 1193 if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT) 1194 return 0; 1195 *size = (size_t) IPC_GET_ARG2(data); 1196 *flags = (int) IPC_GET_ARG3(data); 1197 return 1; 1198 } 1199 1200 /** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework. 1201 * 1202 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls 1203 * so that the user doesn't have to remember the meaning of each IPC argument. 1204 * 1205 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1206 * @param dst Destination address space area base address. 1207 * 1208 * @return Zero on success or a value from @ref errno.h on failure. 1209 */ 1210 int async_share_out_finalize(ipc_callid_t callid, void *dst) 1211 { 1212 return ipc_share_out_finalize(callid, dst); 1213 } 1214 1215 1216 /** Wrapper for making IPC_M_DATA_READ calls using the async framework. 1217 * 1218 * @param phoneid Phone that will be used to contact the receiving side. 1219 * @param dst Address of the beginning of the destination buffer. 1220 * @param size Size of the destination buffer. 1221 * 1222 * @return Zero on success or a negative error code from errno.h. 1223 */ 1224 int async_data_read_start(int phoneid, void *dst, size_t size) 1225 { 1226 return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, 1227 (ipcarg_t) size); 1228 } 1229 1230 /** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework. 1231 * 1232 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls 1233 * so that the user doesn't have to remember the meaning of each IPC argument. 1234 * 1235 * So far, this wrapper is to be used from within a connection fibril. 1236 * 1237 * @param callid Storage where the hash of the IPC_M_DATA_READ call will 1238 * be stored. 1239 * @param size Storage where the maximum size will be stored. Can be 1240 * NULL. 1241 * 1242 * @return Non-zero on success, zero on failure. 1243 */ 1244 int async_data_read_receive(ipc_callid_t *callid, size_t *size) 1245 { 1246 ipc_call_t data; 1247 1248 assert(callid); 1249 1250 *callid = async_get_call(&data); 1251 if (IPC_GET_METHOD(data) != IPC_M_DATA_READ) 1252 return 0; 1253 if (size) 1254 *size = (size_t) IPC_GET_ARG2(data); 1255 return 1; 1256 } 1257 1258 /** Wrapper for answering the IPC_M_DATA_READ calls using the async framework. 1259 * 1260 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls 1261 * so that the user doesn't have to remember the meaning of each IPC argument. 1262 * 1263 * @param callid Hash of the IPC_M_DATA_READ call to answer. 1264 * @param src Source address for the IPC_M_DATA_READ call. 1265 * @param size Size for the IPC_M_DATA_READ call. Can be smaller than 1266 * the maximum size announced by the sender. 1267 * 1268 * @return Zero on success or a value from @ref errno.h on failure. 1269 */ 1270 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 1271 { 1272 return ipc_data_read_finalize(callid, src, size); 1273 } 1274 1275 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework. 1276 * 1277 * @param phoneid Phone that will be used to contact the receiving side. 1278 * @param src Address of the beginning of the source buffer. 1279 * @param size Size of the source buffer. 1280 * 1281 * @return Zero on success or a negative error code from errno.h. 1282 */ 1283 int async_data_write_start(int phoneid, const void *src, size_t size) 1284 { 1285 return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, 1286 (ipcarg_t) size); 1287 } 1288 1289 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework. 1290 * 1291 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls 1292 * so that the user doesn't have to remember the meaning of each IPC argument. 1293 * 1294 * So far, this wrapper is to be used from within a connection fibril. 1295 * 1296 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will 1297 * be stored. 1298 * @param size Storage where the suggested size will be stored. May be 1299 * NULL 1300 * 1301 * @return Non-zero on success, zero on failure. 1302 */ 1303 int async_data_write_receive(ipc_callid_t *callid, size_t *size) 1304 { 1305 ipc_call_t data; 1306 1307 assert(callid); 1308 1309 *callid = async_get_call(&data); 1310 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE) 1311 return 0; 1312 if (size) 1313 *size = (size_t) IPC_GET_ARG2(data); 1314 return 1; 1315 } 1316 1317 /** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework. 1318 * 1319 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls 1320 * so that the user doesn't have to remember the meaning of each IPC argument. 1321 * 1322 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 1323 * @param dst Final destination address for the IPC_M_DATA_WRITE call. 1324 * @param size Final size for the IPC_M_DATA_WRITE call. 1325 * 1326 * @return Zero on success or a value from @ref errno.h on failure. 1327 */ 1328 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 1329 { 1330 return ipc_data_write_finalize(callid, dst, size); 1331 } 1332 1100 1333 /** @} 1101 1334 */ -
uspace/lib/libc/generic/devmap.c
rfcbd1be r1787e527 105 105 aid_t req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); 106 106 107 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);107 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 108 108 109 109 if (retval != EOK) { … … 143 143 &answer); 144 144 145 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);145 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 146 146 147 147 if (retval != EOK) { … … 180 180 &answer); 181 181 182 ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1);182 ipcarg_t retval = async_data_write_start(phone, name, str_size(name) + 1); 183 183 184 184 if (retval != EOK) { … … 271 271 aid_t req = async_send_0(phone, DEVMAP_DEVICE_GET_DEVICES, &answer); 272 272 273 ipcarg_t retval = ipc_data_read_start(phone, data, count * sizeof(dev_desc_t));273 ipcarg_t retval = async_data_read_start(phone, data, count * sizeof(dev_desc_t)); 274 274 275 275 if (retval != EOK) { -
uspace/lib/libc/generic/fibril_sync.c
rfcbd1be r1787e527 36 36 #include <fibril.h> 37 37 #include <async.h> 38 #include <async_priv.h> 38 39 #include <adt/list.h> 39 40 #include <futex.h> 41 #include <sys/time.h> 42 #include <errno.h> 40 43 #include <assert.h> 44 45 static void optimize_execution_power(void) 46 { 47 /* 48 * When waking up a worker fibril previously blocked in fibril 49 * synchronization, chances are that there is an idle manager fibril 50 * waiting for IPC, that could start executing the awakened worker 51 * fibril right away. We try to detect this and bring the manager 52 * fibril back to fruitful work. 53 */ 54 if (atomic_get(&threads_in_ipc_wait) > 0) 55 ipc_poke(); 56 } 41 57 42 58 void fibril_mutex_initialize(fibril_mutex_t *fm) … … 50 66 futex_down(&async_futex); 51 67 if (fm->counter-- <= 0) { 52 fibril_t *f = (fibril_t *) fibril_get_id(); 53 list_append(&f->link, &fm->waiters); 68 awaiter_t wdata; 69 70 wdata.fid = fibril_get_id(); 71 wdata.active = false; 72 wdata.wu_event.inlist = true; 73 link_initialize(&wdata.wu_event.link); 74 list_append(&wdata.wu_event.link, &fm->waiters); 54 75 fibril_switch(FIBRIL_TO_MANAGER); 55 76 } else { … … 77 98 if (fm->counter++ < 0) { 78 99 link_t *tmp; 79 fibril_t *f;100 awaiter_t *wdp; 80 101 81 102 assert(!list_empty(&fm->waiters)); 82 103 tmp = fm->waiters.next; 83 f = list_get_instance(tmp, fibril_t, link); 84 list_remove(&f->link); 85 fibril_add_ready((fid_t) f); 104 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 105 wdp->active = true; 106 wdp->wu_event.inlist = false; 107 list_remove(&wdp->wu_event.link); 108 fibril_add_ready(wdp->fid); 109 optimize_execution_power(); 86 110 } 87 111 } … … 106 130 if (frw->writers) { 107 131 fibril_t *f = (fibril_t *) fibril_get_id(); 132 awaiter_t wdata; 133 134 wdata.fid = (fid_t) f; 135 wdata.active = false; 136 wdata.wu_event.inlist = true; 137 link_initialize(&wdata.wu_event.link); 108 138 f->flags &= ~FIBRIL_WRITER; 109 list_append(& f->link, &frw->waiters);139 list_append(&wdata.wu_event.link, &frw->waiters); 110 140 fibril_switch(FIBRIL_TO_MANAGER); 111 141 } else { … … 120 150 if (frw->writers || frw->readers) { 121 151 fibril_t *f = (fibril_t *) fibril_get_id(); 152 awaiter_t wdata; 153 154 wdata.fid = (fid_t) f; 155 wdata.active = false; 156 wdata.wu_event.inlist = true; 157 link_initialize(&wdata.wu_event.link); 122 158 f->flags |= FIBRIL_WRITER; 123 list_append(& f->link, &frw->waiters);159 list_append(&wdata.wu_event.link, &frw->waiters); 124 160 fibril_switch(FIBRIL_TO_MANAGER); 125 161 } else { … … 144 180 while (!list_empty(&frw->waiters)) { 145 181 link_t *tmp = frw->waiters.next; 146 fibril_t *f = list_get_instance(tmp, fibril_t, link); 182 awaiter_t *wdp; 183 fibril_t *f; 184 185 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 186 f = (fibril_t *) wdp->fid; 147 187 148 188 if (f->flags & FIBRIL_WRITER) { 149 189 if (frw->readers) 150 190 break; 151 list_remove(&f->link); 152 fibril_add_ready((fid_t) f); 191 wdp->active = true; 192 wdp->wu_event.inlist = false; 193 list_remove(&wdp->wu_event.link); 194 fibril_add_ready(wdp->fid); 153 195 frw->writers++; 196 optimize_execution_power(); 154 197 break; 155 198 } else { 156 list_remove(&f->link); 157 fibril_add_ready((fid_t) f); 199 wdp->active = true; 200 wdp->wu_event.inlist = false; 201 list_remove(&wdp->wu_event.link); 202 fibril_add_ready(wdp->fid); 158 203 frw->readers++; 204 optimize_execution_power(); 159 205 } 160 206 } … … 178 224 } 179 225 180 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 181 { 182 fibril_t *f = (fibril_t *) fibril_get_id(); 183 184 futex_down(&async_futex); 185 list_append(&f->link, &fcv->waiters); 226 int 227 fibril_condvar_wait_timeout(fibril_condvar_t *fcv, fibril_mutex_t *fm, 228 suseconds_t timeout) 229 { 230 awaiter_t wdata; 231 232 if (timeout < 0) 233 return ETIMEOUT; 234 235 wdata.fid = fibril_get_id(); 236 wdata.active = false; 237 238 wdata.to_event.inlist = timeout > 0; 239 wdata.to_event.occurred = false; 240 link_initialize(&wdata.to_event.link); 241 242 wdata.wu_event.inlist = true; 243 link_initialize(&wdata.wu_event.link); 244 245 futex_down(&async_futex); 246 if (timeout) { 247 gettimeofday(&wdata.to_event.expires, NULL); 248 tv_add(&wdata.to_event.expires, timeout); 249 async_insert_timeout(&wdata); 250 } 251 list_append(&wdata.wu_event.link, &fcv->waiters); 186 252 _fibril_mutex_unlock_unsafe(fm); 187 253 fibril_switch(FIBRIL_TO_MANAGER); 188 254 fibril_mutex_lock(fm); 255 256 /* async_futex not held after fibril_switch() */ 257 futex_down(&async_futex); 258 if (wdata.to_event.inlist) 259 list_remove(&wdata.to_event.link); 260 if (wdata.wu_event.inlist) 261 list_remove(&wdata.wu_event.link); 262 futex_up(&async_futex); 263 264 return wdata.to_event.occurred ? ETIMEOUT : EOK; 265 } 266 267 void fibril_condvar_wait(fibril_condvar_t *fcv, fibril_mutex_t *fm) 268 { 269 int rc; 270 271 rc = fibril_condvar_wait_timeout(fcv, fm, 0); 272 assert(rc == EOK); 189 273 } 190 274 … … 192 276 { 193 277 link_t *tmp; 194 fibril_t *f;278 awaiter_t *wdp; 195 279 196 280 futex_down(&async_futex); 197 281 while (!list_empty(&fcv->waiters)) { 198 282 tmp = fcv->waiters.next; 199 f = list_get_instance(tmp, fibril_t, link); 200 list_remove(&f->link); 201 fibril_add_ready((fid_t) f); 202 if (once) 203 break; 283 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 284 list_remove(&wdp->wu_event.link); 285 wdp->wu_event.inlist = false; 286 if (!wdp->active) { 287 wdp->active = true; 288 fibril_add_ready(wdp->fid); 289 optimize_execution_power(); 290 if (once) 291 break; 292 } 204 293 } 205 294 futex_up(&async_futex); -
uspace/lib/libc/generic/io/console.c
rfcbd1be r1787e527 45 45 } 46 46 47 int console_get_size(int phone, i pcarg_t *rows, ipcarg_t *cols)47 int console_get_size(int phone, int *cols, int *rows) 48 48 { 49 return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols); 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; 50 58 } 51 59 … … 86 94 } 87 95 88 void console_goto(int phone, i pcarg_t row, ipcarg_t col)96 void console_goto(int phone, int col, int row) 89 97 { 90 async_msg_2(phone, CONSOLE_GOTO, row, col);98 async_msg_2(phone, CONSOLE_GOTO, col, row); 91 99 } 92 100 -
uspace/lib/libc/generic/io/klog.c
rfcbd1be r1787e527 42 42 size_t klog_write(const void *buf, size_t size) 43 43 { 44 return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); 44 ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size); 45 46 if (ret >= 0) 47 return (size_t) ret; 48 49 return 0; 45 50 } 46 51 -
uspace/lib/libc/generic/ipc.c
rfcbd1be r1787e527 565 565 } 566 566 567 /** Interrupt one thread of this task from waiting for IPC. */ 568 void ipc_poke(void) 569 { 570 __SYSCALL0(SYS_IPC_POKE); 571 } 572 567 573 /** Ask destination to do a callback connection. 568 574 * … … 724 730 int res; 725 731 sysarg_t tmp_flags; 726 res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,732 res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, 727 733 (ipcarg_t) size, arg, NULL, &tmp_flags); 728 734 if (flags) … … 731 737 } 732 738 733 /** Wrapper for receiving the IPC_M_SHARE_IN calls.734 *735 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls736 * so that the user doesn't have to remember the meaning of each IPC argument.737 *738 * So far, this wrapper is to be used from within a connection fibril.739 *740 * @param callid Storage where the hash of the IPC_M_SHARE_IN call will741 * be stored.742 * @param size Destination address space area size.743 *744 * @return Non-zero on success, zero on failure.745 */746 int ipc_share_in_receive(ipc_callid_t *callid, size_t *size)747 {748 ipc_call_t data;749 750 assert(callid);751 assert(size);752 753 *callid = async_get_call(&data);754 if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)755 return 0;756 *size = (size_t) IPC_GET_ARG2(data);757 return 1;758 }759 760 739 /** Wrapper for answering the IPC_M_SHARE_IN calls. 761 740 * … … 784 763 int ipc_share_out_start(int phoneid, void *src, int flags) 785 764 { 786 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,765 return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, 787 766 (ipcarg_t) flags); 788 }789 790 /** Wrapper for receiving the IPC_M_SHARE_OUT calls.791 *792 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls793 * so that the user doesn't have to remember the meaning of each IPC argument.794 *795 * So far, this wrapper is to be used from within a connection fibril.796 *797 * @param callid Storage where the hash of the IPC_M_SHARE_OUT call will798 * be stored.799 * @param size Storage where the source address space area size will be800 * stored.801 * @param flags Storage where the sharing flags will be stored.802 *803 * @return Non-zero on success, zero on failure.804 */805 int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)806 {807 ipc_call_t data;808 809 assert(callid);810 assert(size);811 assert(flags);812 813 *callid = async_get_call(&data);814 if (IPC_GET_METHOD(data) != IPC_M_SHARE_OUT)815 return 0;816 *size = (size_t) IPC_GET_ARG2(data);817 *flags = (int) IPC_GET_ARG3(data);818 return 1;819 767 } 820 768 … … 845 793 int ipc_data_read_start(int phoneid, void *dst, size_t size) 846 794 { 847 return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst,795 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, 848 796 (ipcarg_t) size); 849 }850 851 /** Wrapper for receiving the IPC_M_DATA_READ calls.852 *853 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls854 * so that the user doesn't have to remember the meaning of each IPC argument.855 *856 * So far, this wrapper is to be used from within a connection fibril.857 *858 * @param callid Storage where the hash of the IPC_M_DATA_READ call will859 * be stored.860 * @param size Storage where the maximum size will be stored. Can be861 * NULL.862 *863 * @return Non-zero on success, zero on failure.864 */865 int ipc_data_read_receive(ipc_callid_t *callid, size_t *size)866 {867 ipc_call_t data;868 869 assert(callid);870 871 *callid = async_get_call(&data);872 if (IPC_GET_METHOD(data) != IPC_M_DATA_READ)873 return 0;874 if (size)875 *size = (size_t) IPC_GET_ARG2(data);876 return 1;877 797 } 878 798 … … 904 824 int ipc_data_write_start(int phoneid, const void *src, size_t size) 905 825 { 906 return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src,826 return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, 907 827 (ipcarg_t) size); 908 }909 910 /** Wrapper for receiving the IPC_M_DATA_WRITE calls.911 *912 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls913 * so that the user doesn't have to remember the meaning of each IPC argument.914 *915 * So far, this wrapper is to be used from within a connection fibril.916 *917 * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will918 * be stored.919 * @param size Storage where the suggested size will be stored. May be920 * NULL921 *922 * @return Non-zero on success, zero on failure.923 */924 int ipc_data_write_receive(ipc_callid_t *callid, size_t *size)925 {926 ipc_call_t data;927 928 assert(callid);929 930 *callid = async_get_call(&data);931 if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)932 return 0;933 if (size)934 *size = (size_t) IPC_GET_ARG2(data);935 return 1;936 828 } 937 829 -
uspace/lib/libc/generic/libc.c
rfcbd1be r1787e527 83 83 argv = __pcb->argv; 84 84 __stdio_init(__pcb->filc, __pcb->filv); 85 (void) chdir(__pcb->cwd); 85 86 } 86 87 -
uspace/lib/libc/generic/loader.c
rfcbd1be r1787e527 90 90 ipc_call_t answer; 91 91 aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); 92 int rc = ipc_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 92 int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 93 if (rc != EOK) { 94 async_wait_for(req, NULL); 95 return rc; 96 } 97 98 ipcarg_t retval; 99 async_wait_for(req, &retval); 100 return (int) retval; 101 } 102 103 /** Set current working directory for the loaded task. 104 * 105 * Sets the current working directory for the loaded task. 106 * 107 * @param ldr Loader connection structure. 108 * 109 * @return Zero on success or negative error code. 110 * 111 */ 112 int loader_set_cwd(loader_t *ldr) 113 { 114 char *cwd; 115 size_t len; 116 117 cwd = (char *) malloc(MAX_PATH_LEN + 1); 118 if (!cwd) 119 return ENOMEM; 120 if (!getcwd(cwd, MAX_PATH_LEN + 1)) 121 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 122 len = str_length(cwd); 123 124 ipc_call_t answer; 125 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer); 126 int rc = async_data_write_start(ldr->phone_id, cwd, len); 127 free(cwd); 93 128 if (rc != EOK) { 94 129 async_wait_for(req, NULL); … … 123 158 ipc_call_t answer; 124 159 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); 125 int rc = ipc_data_write_start(ldr->phone_id, (void *) pa, pa_len);160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 126 161 if (rc != EOK) { 127 162 async_wait_for(req, NULL); … … 178 213 ipc_call_t answer; 179 214 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); 180 ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size);215 ipcarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size); 181 216 if (rc != EOK) { 182 217 async_wait_for(req, NULL); … … 232 267 ipc_call_t answer; 233 268 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer); 234 ipcarg_t rc = ipc_data_write_start(ldr->phone_id, (void *) files_buf,269 ipcarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf, 235 270 count * sizeof(fdi_node_t)); 236 271 if (rc != EOK) { -
uspace/lib/libc/generic/malloc.c
rfcbd1be r1787e527 353 353 } 354 354 355 void *calloc(const size_t nmemb, const size_t size) 356 { 357 void *block = malloc(nmemb * size); 358 if (block == NULL) 359 return NULL; 360 361 memset(block, 0, nmemb * size); 362 return block; 363 } 364 355 365 void *malloc(const size_t size) 356 366 { -
uspace/lib/libc/generic/task.c
rfcbd1be r1787e527 89 89 goto error; 90 90 91 /* Send spawner's current working directory. */ 92 rc = loader_set_cwd(ldr); 93 if (rc != EOK) 94 goto error; 95 91 96 /* Send program pathname. */ 92 97 rc = loader_set_pathname(ldr, path); … … 98 103 if (rc != EOK) 99 104 goto error; 100 101 105 102 106 /* Send default files */ -
uspace/lib/libc/generic/vfs/vfs.c
rfcbd1be r1787e527 57 57 static futex_t cwd_futex = FUTEX_INITIALIZER; 58 58 59 DIR *cwd_dir = NULL;60 char *cwd_path = NULL;61 s ize_t cwd_size = 0;59 static int cwd_fd = -1; 60 static char *cwd_path = NULL; 61 static size_t cwd_size = 0; 62 62 63 63 char *absolutize(const char *path, size_t *retlen) … … 140 140 141 141 req = async_send_2(vfs_phone, VFS_IN_MOUNT, dev_handle, flags, NULL); 142 rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size);142 rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 143 143 if (rc != EOK) { 144 144 async_wait_for(req, &rc_orig); … … 152 152 } 153 153 154 rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts));154 rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts)); 155 155 if (rc != EOK) { 156 156 async_wait_for(req, &rc_orig); … … 164 164 } 165 165 166 rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));166 rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); 167 167 if (rc != EOK) { 168 168 async_wait_for(req, &rc_orig); … … 197 197 } 198 198 199 static int _open(const char *path, int lflag, int oflag, ...) 200 { 201 ipcarg_t rc; 199 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 200 { 201 futex_down(&vfs_phone_futex); 202 async_serialize_start(); 203 vfs_connect(); 204 202 205 ipc_call_t answer; 203 aid_t req; 204 205 size_t pa_size; 206 char *pa = absolutize(path, &pa_size); 207 if (!pa) 208 return ENOMEM; 209 210 futex_down(&vfs_phone_futex); 211 async_serialize_start(); 212 vfs_connect(); 213 214 req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 215 rc = ipc_data_write_start(vfs_phone, pa, pa_size); 206 aid_t req = async_send_3(vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer); 207 ipcarg_t rc = async_data_write_start(vfs_phone, abs, abs_size); 208 216 209 if (rc != EOK) { 217 210 ipcarg_t rc_orig; 218 219 async_wait_for(req, &rc_orig);220 async_serialize_end(); 221 futex_up(&vfs_phone_futex); 222 free(pa);223 if (rc_orig == EOK) 224 return (int) rc; 225 else 226 return (int) rc_orig; 227 } 228 async_wait_for(req, &rc);229 async_ serialize_end();230 futex_up(&vfs_phone_futex);231 f ree(pa);211 async_wait_for(req, &rc_orig); 212 213 async_serialize_end(); 214 futex_up(&vfs_phone_futex); 215 216 if (rc_orig == EOK) 217 return (int) rc; 218 else 219 return (int) rc_orig; 220 } 221 222 async_wait_for(req, &rc); 223 async_serialize_end(); 224 futex_up(&vfs_phone_futex); 232 225 233 226 if (rc != EOK) … … 239 232 int open(const char *path, int oflag, ...) 240 233 { 241 return _open(path, L_FILE, oflag); 234 size_t abs_size; 235 char *abs = absolutize(path, &abs_size); 236 if (!abs) 237 return ENOMEM; 238 239 int ret = open_internal(abs, abs_size, L_FILE, oflag); 240 free(abs); 241 242 return ret; 242 243 } 243 244 … … 290 291 291 292 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 292 rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte);293 rc = async_data_read_start(vfs_phone, (void *)buf, nbyte); 293 294 if (rc != EOK) { 294 295 ipcarg_t rc_orig; … … 322 323 323 324 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 324 rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte);325 rc = async_data_write_start(vfs_phone, (void *)buf, nbyte); 325 326 if (rc != EOK) { 326 327 ipcarg_t rc_orig; … … 402 403 403 404 req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL); 404 rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));405 rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat)); 405 406 if (rc != EOK) { 406 407 ipcarg_t rc_orig; … … 437 438 438 439 req = async_send_0(vfs_phone, VFS_IN_STAT, NULL); 439 rc = ipc_data_write_start(vfs_phone, pa, pa_size);440 rc = async_data_write_start(vfs_phone, pa, pa_size); 440 441 if (rc != EOK) { 441 442 async_wait_for(req, &rc_orig); … … 448 449 return (int) rc_orig; 449 450 } 450 rc = ipc_data_read_start(vfs_phone, stat, sizeof(struct stat));451 rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat)); 451 452 if (rc != EOK) { 452 453 async_wait_for(req, &rc_orig); … … 471 472 if (!dirp) 472 473 return NULL; 473 dirp->fd = _open(dirname, L_DIRECTORY, 0); 474 if (dirp->fd < 0) { 474 475 size_t abs_size; 476 char *abs = absolutize(dirname, &abs_size); 477 if (!abs) { 478 free(dirp); 479 return ENOMEM; 480 } 481 482 int ret = open_internal(abs, abs_size, L_DIRECTORY, 0); 483 free(abs); 484 485 if (ret < 0) { 475 486 free(dirp); 476 487 return NULL; 477 488 } 489 490 dirp->fd = ret; 478 491 return dirp; 479 492 } … … 514 527 515 528 req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL); 516 rc = ipc_data_write_start(vfs_phone, pa, pa_size);529 rc = async_data_write_start(vfs_phone, pa, pa_size); 517 530 if (rc != EOK) { 518 531 ipcarg_t rc_orig; … … 549 562 550 563 req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL); 551 rc = ipc_data_write_start(vfs_phone, pa, pa_size);564 rc = async_data_write_start(vfs_phone, pa, pa_size); 552 565 if (rc != EOK) { 553 566 ipcarg_t rc_orig; … … 602 615 603 616 req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL); 604 rc = ipc_data_write_start(vfs_phone, olda, olda_size);617 rc = async_data_write_start(vfs_phone, olda, olda_size); 605 618 if (rc != EOK) { 606 619 async_wait_for(req, &rc_orig); … … 614 627 return (int) rc_orig; 615 628 } 616 rc = ipc_data_write_start(vfs_phone, newa, newa_size);629 rc = async_data_write_start(vfs_phone, newa, newa_size); 617 630 if (rc != EOK) { 618 631 async_wait_for(req, &rc_orig); … … 636 649 int chdir(const char *path) 637 650 { 638 size_t pa_size; 639 char *pa = absolutize(path, &pa_size); 640 if (!pa) 641 return ENOMEM; 642 643 DIR *d = opendir(pa); 644 if (!d) { 645 free(pa); 651 size_t abs_size; 652 char *abs = absolutize(path, &abs_size); 653 if (!abs) 654 return ENOMEM; 655 656 int fd = open_internal(abs, abs_size, L_DIRECTORY, O_DESC); 657 658 if (fd < 0) { 659 free(abs); 646 660 return ENOENT; 647 661 } 648 662 649 663 futex_down(&cwd_futex); 650 if (cwd_dir) { 651 closedir(cwd_dir); 652 cwd_dir = NULL; 653 free(cwd_path); 654 cwd_path = NULL; 655 cwd_size = 0; 656 } 657 cwd_dir = d; 658 cwd_path = pa; 659 cwd_size = pa_size; 664 665 if (cwd_fd >= 0) 666 close(cwd_fd); 667 668 669 if (cwd_path) 670 free(cwd_path); 671 672 cwd_fd = fd; 673 cwd_path = abs; 674 cwd_size = abs_size; 675 660 676 futex_up(&cwd_futex); 661 677 return EOK; … … 664 680 char *getcwd(char *buf, size_t size) 665 681 { 666 if ( !size)682 if (size == 0) 667 683 return NULL; 684 668 685 futex_down(&cwd_futex); 669 if (size < cwd_size + 1) { 686 687 if ((cwd_size == 0) || (size < cwd_size + 1)) { 670 688 futex_up(&cwd_futex); 671 689 return NULL; 672 690 } 691 673 692 str_cpy(buf, size, cwd_path); 674 693 futex_up(&cwd_futex); 694 675 695 return buf; 676 696 } … … 705 725 } 706 726 727 int dup2(int oldfd, int newfd) 728 { 729 futex_down(&vfs_phone_futex); 730 async_serialize_start(); 731 vfs_connect(); 732 733 ipcarg_t ret; 734 ipcarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret); 735 736 async_serialize_end(); 737 futex_up(&vfs_phone_futex); 738 739 if (rc == EOK) 740 return (int) ret; 741 742 return (int) rc; 743 } 744 707 745 /** @} 708 746 */ -
uspace/lib/libc/include/async.h
rfcbd1be r1787e527 47 47 extern atomic_t async_futex; 48 48 49 extern atomic_t threads_in_ipc_wait; 50 49 51 extern int __async_init(void); 50 52 extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs); … … 257 259 } 258 260 261 /* 262 * User-friendly wrappers for async_share_in_start(). 263 */ 264 #define async_share_in_start_0_0(phoneid, dst, size) \ 265 async_share_in_start((phoneid), (dst), (size), 0, NULL) 266 #define async_share_in_start_0_1(phoneid, dst, size, flags) \ 267 async_share_in_start((phoneid), (dst), (size), 0, (flags)) 268 #define async_share_in_start_1_0(phoneid, dst, size, arg) \ 269 async_share_in_start((phoneid), (dst), (size), (arg), NULL) 270 #define async_share_in_start_1_1(phoneid, dst, size, arg, flags) \ 271 async_share_in_start((phoneid), (dst), (size), (arg), (flags)) 272 273 extern int async_share_in_start(int, void *, size_t, ipcarg_t, int *); 274 extern int async_share_in_receive(ipc_callid_t *, size_t *); 275 extern int async_share_in_finalize(ipc_callid_t, void *, int ); 276 extern int async_share_out_start(int, void *, int); 277 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *); 278 extern int async_share_out_finalize(ipc_callid_t, void *); 279 extern int async_data_read_start(int, void *, size_t); 280 extern int async_data_read_receive(ipc_callid_t *, size_t *); 281 extern int async_data_read_finalize(ipc_callid_t, const void *, size_t); 282 extern int async_data_write_start(int, const void *, size_t); 283 extern int async_data_write_receive(ipc_callid_t *, size_t *); 284 extern int async_data_write_finalize(ipc_callid_t, void *, size_t); 285 259 286 #endif 260 287 -
uspace/lib/libc/include/async_priv.h
rfcbd1be r1787e527 1 1 /* 2 * Copyright (c) 200 5 Jakub Jermar2 * Copyright (c) 2006 Ondrej Palkovsky 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup libc ia3229 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 /* 36 * Variable argument list manipulation macros 37 * for architectures using stack to pass arguments. 38 */ 39 40 #ifndef LIBC_ia32_STACKARG_H_ 41 #define LIBC_ia32_STACKARG_H_ 35 #ifndef LIBC_ASYNC_PRIV_H_ 36 #define LIBC_ASYNC_PRIV_H_ 42 37 43 #include <sys/types.h> 38 #include <adt/list.h> 39 #include <fibril.h> 40 #include <sys/time.h> 41 #include <bool.h> 44 42 45 /* dont allow to define it second time in stdarg.h */ 46 #define __VARARGS_DEFINED 43 /** Structures of this type are used to track the timeout events. */ 44 typedef struct { 45 /** If true, this struct is in the timeout list. */ 46 bool inlist; 47 48 /** Timeout list link. */ 49 link_t link; 50 51 /** If true, we have timed out. */ 52 bool occurred; 47 53 48 typedef struct va_list { 49 int pos; 50 uint8_t *last; 51 } va_list; 54 /** Expiration time. */ 55 struct timeval expires; 56 } to_event_t; 52 57 53 #define va_start(ap, lst) \ 54 (ap).pos = sizeof(lst); \ 55 (ap).last = (uint8_t *) &(lst) 58 /** Structures of this type are used to track the wakeup events. */ 59 typedef struct { 60 /** If true, this struct is in a synchronization object wait queue. */ 61 bool inlist; 62 63 /** Wait queue linkage. */ 64 link_t link; 65 } wu_event_t; 56 66 57 #define va_arg(ap, type) \58 (*((type *)((ap).last + ((ap).pos += sizeof(type) ) - sizeof(type))))59 67 60 #define va_end(ap) 68 /** Structures of this type represent a waiting fibril. */ 69 typedef struct { 70 /** Identification of and link to the waiting fibril. */ 71 fid_t fid; 72 73 /** If true, this fibril is currently active. */ 74 bool active; 61 75 76 /** Timeout wait data. */ 77 to_event_t to_event; 78 /** Wakeup wait data. */ 79 wu_event_t wu_event; 80 } awaiter_t; 81 82 extern void async_insert_timeout(awaiter_t *wd); 62 83 63 84 #endif -
uspace/lib/libc/include/fcntl.h
rfcbd1be r1787e527 43 43 #define O_RDWR 32 44 44 #define O_WRONLY 64 45 #define O_DESC 128 45 46 46 47 extern int open(const char *, int, ...); -
uspace/lib/libc/include/fibril_sync.h
rfcbd1be r1787e527 40 40 #include <adt/list.h> 41 41 #include <libarch/tls.h> 42 #include <sys/time.h> 42 43 43 44 typedef struct { … … 95 96 96 97 extern void fibril_condvar_initialize(fibril_condvar_t *); 98 extern int fibril_condvar_wait_timeout(fibril_condvar_t *, fibril_mutex_t *, 99 suseconds_t); 97 100 extern void fibril_condvar_wait(fibril_condvar_t *, fibril_mutex_t *); 98 101 extern void fibril_condvar_signal(fibril_condvar_t *); -
uspace/lib/libc/include/io/console.h
rfcbd1be r1787e527 68 68 extern void console_clear(int phone); 69 69 70 extern int console_get_size(int phone, i pcarg_t *rows, ipcarg_t *cols);71 extern void console_goto(int phone, i pcarg_t row, ipcarg_t col);70 extern int console_get_size(int phone, int *cols, int *rows); 71 extern void console_goto(int phone, int col, int row); 72 72 73 73 extern void console_set_style(int phone, int style); -
uspace/lib/libc/include/ipc/bd.h
rfcbd1be r1787e527 39 39 40 40 typedef enum { 41 BD_READ_BLOCK = IPC_FIRST_USER_METHOD, 42 BD_WRITE_BLOCK 41 BD_GET_BLOCK_SIZE = IPC_FIRST_USER_METHOD, 42 BD_READ_BLOCKS, 43 BD_WRITE_BLOCKS 43 44 } bd_request_t; 44 45 -
uspace/lib/libc/include/ipc/ipc.h
rfcbd1be r1787e527 192 192 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int); 193 193 extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t); 194 extern void ipc_poke(void); 194 195 195 196 static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data) … … 282 283 283 284 extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *); 284 extern int ipc_share_in_receive(ipc_callid_t *, size_t *);285 285 extern int ipc_share_in_finalize(ipc_callid_t, void *, int ); 286 286 extern int ipc_share_out_start(int, void *, int); 287 extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *);288 287 extern int ipc_share_out_finalize(ipc_callid_t, void *); 289 288 extern int ipc_data_read_start(int, void *, size_t); 290 extern int ipc_data_read_receive(ipc_callid_t *, size_t *);291 289 extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t); 292 290 extern int ipc_data_write_start(int, const void *, size_t); 293 extern int ipc_data_write_receive(ipc_callid_t *, size_t *);294 291 extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t); 295 292 -
uspace/lib/libc/include/ipc/loader.h
rfcbd1be r1787e527 41 41 LOADER_HELLO = IPC_FIRST_USER_METHOD, 42 42 LOADER_GET_TASKID, 43 LOADER_SET_CWD, 43 44 LOADER_SET_PATHNAME, 44 45 LOADER_SET_ARGS, -
uspace/lib/libc/include/ipc/vfs.h
rfcbd1be r1787e527 73 73 VFS_IN_UNLINK, 74 74 VFS_IN_RENAME, 75 VFS_IN_STAT 75 VFS_IN_STAT, 76 VFS_IN_DUP 76 77 } vfs_in_request_t; 77 78 -
uspace/lib/libc/include/loader/loader.h
rfcbd1be r1787e527 49 49 extern loader_t *loader_connect(void); 50 50 extern int loader_get_task_id(loader_t *, task_id_t *); 51 extern int loader_set_cwd(loader_t *); 51 52 extern int loader_set_pathname(loader_t *, const char *); 52 53 extern int loader_set_args(loader_t *, char *const[]); -
uspace/lib/libc/include/loader/pcb.h
rfcbd1be r1787e527 52 52 /** Program entry point. */ 53 53 entry_point_t entry; 54 55 /** Current working directory. */ 56 char *cwd; 54 57 55 58 /** Number of command-line arguments. */ -
uspace/lib/libc/include/malloc.h
rfcbd1be r1787e527 42 42 43 43 extern void *malloc(const size_t size); 44 extern void *calloc(const size_t nmemb, const size_t size); 44 45 extern void *memalign(const size_t align, const size_t size); 45 46 extern void *realloc(const void *addr, const size_t size); -
uspace/lib/libc/include/stdarg.h
rfcbd1be r1787e527 37 37 38 38 #include <sys/types.h> 39 #include <libarch/stackarg.h>40 41 #ifndef __VARARGS_DEFINED42 # define __VARARGS_DEFINED43 39 44 40 typedef __builtin_va_list va_list; 45 41 46 # define va_start(ap, last) __builtin_va_start(ap, last) 47 # define va_arg(ap, type) __builtin_va_arg(ap, type) 48 # define va_end(ap) __builtin_va_end(ap) 49 50 # endif 42 #define va_start(ap, last) __builtin_va_start(ap, last) 43 #define va_arg(ap, type) __builtin_va_arg(ap, type) 44 #define va_end(ap) __builtin_va_end(ap) 51 45 52 46 #endif -
uspace/lib/libc/include/unistd.h
rfcbd1be r1787e527 51 51 #endif 52 52 53 extern int dup2(int oldfd, int newfd); 54 53 55 extern ssize_t write(int, const void *, size_t); 54 56 extern ssize_t read(int, void *, size_t); -
uspace/lib/libfs/Makefile
rfcbd1be r1787e527 28 28 # 29 29 30 ## Common compiler flags 31 # 30 include Makefile.common 32 31 33 LIBC_PREFIX = ../libc 32 .PHONY: all clean 34 33 35 ## Setup toolchain 36 # 37 38 include $(LIBC_PREFIX)/Makefile.toolchain 39 40 CFLAGS += -Iinclude 41 42 ## Sources 43 # 44 45 SOURCES = \ 46 libfs.c 47 48 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 49 50 .PHONY: all clean depend 51 52 all: libfs.a 53 54 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 55 37 56 38 clean: 57 -rm -f libfs.a Makefile.depend39 rm -f $(DEPEND) $(DEPEND_PREV) $(LIBFS) 58 40 find . -name '*.o' -follow -exec rm \{\} \; 59 60 depend:61 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null62 63 libfs.a: depend $(OBJECTS)64 $(AR) rc libfs.a $(OBJECTS)65 66 %.o: %.c67 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ -
uspace/lib/libfs/libfs.c
rfcbd1be r1787e527 46 46 #include <sys/stat.h> 47 47 48 #define on_error(rc, action) \ 49 do { \ 50 if ((rc) != EOK) \ 51 action; \ 52 } while (0) 53 54 #define combine_rc(rc1, rc2) \ 55 ((rc1) == EOK ? (rc2) : (rc1)) 56 57 #define answer_and_return(rid, rc) \ 58 do { \ 59 ipc_answer_0((rid), (rc)); \ 60 return; \ 61 } while (0) 62 48 63 /** Register file system server. 49 64 * … … 76 91 * Send our VFS info structure to VFS. 77 92 */ 78 int rc = ipc_data_write_start(vfs_phone, info, sizeof(*info));93 int rc = async_data_write_start(vfs_phone, info, sizeof(*info)); 79 94 if (rc != EOK) { 80 95 async_wait_for(req, NULL); … … 99 114 * Request sharing the Path Lookup Buffer with VFS. 100 115 */ 101 rc = ipc_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);116 rc = async_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE); 102 117 if (rc) { 103 118 async_wait_for(req, NULL); … … 154 169 ipc_answer_0(callid, EOK); /* acknowledge the mountee_phone */ 155 170 156 res = ipc_data_write_receive(&callid, NULL);171 res = async_data_write_receive(&callid, NULL); 157 172 if (!res) { 158 173 ipc_hangup(mountee_phone); … … 162 177 } 163 178 164 fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index); 165 if (!fn) { 179 fs_node_t *fn; 180 res = ops->node_get(&fn, mp_dev_handle, mp_fs_index); 181 if (res != EOK || !fn) { 166 182 ipc_hangup(mountee_phone); 167 ipc_answer_0(callid, ENOENT);168 ipc_answer_0(rid, ENOENT);183 ipc_answer_0(callid, combine_rc(res, ENOENT)); 184 ipc_answer_0(rid, combine_rc(res, ENOENT)); 169 185 return; 170 186 } … … 172 188 if (fn->mp_data.mp_active) { 173 189 ipc_hangup(mountee_phone); 174 ops->node_put(fn);190 (void) ops->node_put(fn); 175 191 ipc_answer_0(callid, EBUSY); 176 192 ipc_answer_0(rid, EBUSY); … … 179 195 180 196 rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME); 181 if (rc != 0) {197 if (rc != EOK) { 182 198 ipc_hangup(mountee_phone); 183 ops->node_put(fn);199 (void) ops->node_put(fn); 184 200 ipc_answer_0(callid, rc); 185 201 ipc_answer_0(rid, rc); … … 230 246 char component[NAME_MAX + 1]; 231 247 int len; 248 int rc; 232 249 233 250 if (last < next) … … 235 252 236 253 fs_node_t *par = NULL; 237 fs_node_t *cur = ops->root_get(dev_handle);254 fs_node_t *cur = NULL; 238 255 fs_node_t *tmp = NULL; 256 257 rc = ops->root_get(&cur, dev_handle); 258 on_error(rc, goto out_with_answer); 239 259 240 260 if (cur->mp_data.mp_active) { … … 242 262 next, last, cur->mp_data.dev_handle, lflag, index, 243 263 IPC_FF_ROUTE_FROM_ME); 244 ops->node_put(cur);264 (void) ops->node_put(cur); 245 265 return; 246 266 } … … 249 269 next++; /* eat slash */ 250 270 251 while (next <= last && ops->has_children(cur)) { 271 while (next <= last) { 272 bool has_children; 273 274 rc = ops->has_children(&has_children, cur); 275 on_error(rc, goto out_with_answer); 276 if (!has_children) 277 break; 278 252 279 /* collect the component */ 253 280 len = 0; … … 267 294 268 295 /* match the component */ 269 tmp = ops->match(cur, component); 296 rc = ops->match(&tmp, cur, component); 297 on_error(rc, goto out_with_answer); 298 270 299 if (tmp && tmp->mp_data.mp_active) { 271 300 if (next > last) … … 277 306 VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle, 278 307 lflag, index, IPC_FF_ROUTE_FROM_ME); 279 ops->node_put(cur);280 ops->node_put(tmp);308 (void) ops->node_put(cur); 309 (void) ops->node_put(tmp); 281 310 if (par) 282 ops->node_put(par);311 (void) ops->node_put(par); 283 312 return; 284 313 } … … 300 329 fs_node_t *fn; 301 330 if (lflag & L_CREATE) 302 fn = ops->create(dev_handle, lflag); 331 rc = ops->create(&fn, dev_handle, 332 lflag); 303 333 else 304 fn = ops->node_get(dev_handle,334 rc = ops->node_get(&fn, dev_handle, 305 335 index); 336 on_error(rc, goto out_with_answer); 306 337 if (fn) { 307 int rc;308 309 338 rc = ops->link(cur, fn, component); 310 339 if (rc != EOK) { 311 if (lflag & L_CREATE) { 312 (void)ops->destroy(fn); 313 } 340 if (lflag & L_CREATE) 341 (void) ops->destroy(fn); 314 342 ipc_answer_0(rid, rc); 315 343 } else { … … 319 347 ops->size_get(fn), 320 348 ops->lnkcnt_get(fn)); 321 ops->node_put(fn);349 (void) ops->node_put(fn); 322 350 } 323 351 } else { … … 330 358 } 331 359 332 if (par) 333 ops->node_put(par); 360 if (par) { 361 rc = ops->node_put(par); 362 on_error(rc, goto out_with_answer); 363 } 334 364 335 365 /* descend one level */ … … 340 370 341 371 /* handle miss: excessive components */ 342 if (next <= last && !ops->has_children(cur)) { 372 if (next <= last) { 373 bool has_children; 374 375 rc = ops->has_children(&has_children, cur); 376 on_error(rc, goto out_with_answer); 377 if (has_children) 378 goto skip_miss; 379 343 380 if (lflag & (L_CREATE | L_LINK)) { 344 381 if (!ops->is_directory(cur)) { … … 368 405 fs_node_t *fn; 369 406 if (lflag & L_CREATE) 370 fn = ops->create(dev_handle, lflag);407 rc = ops->create(&fn, dev_handle, lflag); 371 408 else 372 fn = ops->node_get(dev_handle, index); 409 rc = ops->node_get(&fn, dev_handle, index); 410 on_error(rc, goto out_with_answer); 373 411 if (fn) { 374 int rc;375 376 412 rc = ops->link(cur, fn, component); 377 413 if (rc != EOK) { 378 414 if (lflag & L_CREATE) 379 (void) ops->destroy(fn);415 (void) ops->destroy(fn); 380 416 ipc_answer_0(rid, rc); 381 417 } else { … … 385 421 ops->size_get(fn), 386 422 ops->lnkcnt_get(fn)); 387 ops->node_put(fn);423 (void) ops->node_put(fn); 388 424 } 389 425 } else { … … 395 431 goto out; 396 432 } 433 skip_miss: 397 434 398 435 /* handle hit */ 399 436 if (lflag & L_UNLINK) { 400 437 unsigned old_lnkcnt = ops->lnkcnt_get(cur); 401 int res= ops->unlink(par, cur, component);402 ipc_answer_5(rid, (ipcarg_t)r es, fs_handle, dev_handle,438 rc = ops->unlink(par, cur, component); 439 ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle, 403 440 ops->index_get(cur), ops->size_get(cur), old_lnkcnt); 404 441 goto out; … … 418 455 } 419 456 420 ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur), 421 ops->size_get(cur), ops->lnkcnt_get(cur)); 457 out_with_answer: 458 if (rc == EOK) { 459 ipc_answer_5(rid, EOK, fs_handle, dev_handle, 460 ops->index_get(cur), ops->size_get(cur), 461 ops->lnkcnt_get(cur)); 462 } else { 463 ipc_answer_0(rid, rc); 464 } 422 465 423 466 out: 424 467 if (par) 425 ops->node_put(par);468 (void) ops->node_put(par); 426 469 if (cur) 427 ops->node_put(cur);470 (void) ops->node_put(cur); 428 471 if (tmp) 429 ops->node_put(tmp);472 (void) ops->node_put(tmp); 430 473 } 431 474 … … 435 478 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 436 479 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 437 fs_node_t *fn = ops->node_get(dev_handle, index); 480 fs_node_t *fn; 481 int rc; 482 483 rc = ops->node_get(&fn, dev_handle, index); 484 on_error(rc, answer_and_return(rid, rc)); 438 485 439 486 ipc_callid_t callid; 440 487 size_t size; 441 if (! ipc_data_read_receive(&callid, &size) ||488 if (!async_data_read_receive(&callid, &size) || 442 489 size != sizeof(struct stat)) { 443 490 ipc_answer_0(callid, EINVAL); … … 456 503 stat.size = ops->size_get(fn); 457 504 458 ipc_data_read_finalize(callid, &stat, sizeof(struct stat));505 async_data_read_finalize(callid, &stat, sizeof(struct stat)); 459 506 ipc_answer_0(rid, EOK); 460 507 } … … 473 520 dev_handle_t dev_handle = IPC_GET_ARG1(*request); 474 521 fs_index_t index = IPC_GET_ARG2(*request); 475 476 fs_node_t *node = ops->node_get(dev_handle, index); 477 478 if (node == NULL) { 522 fs_node_t *fn; 523 int rc; 524 525 rc = ops->node_get(&fn, dev_handle, index); 526 on_error(rc, answer_and_return(rid, rc)); 527 528 if (fn == NULL) { 479 529 ipc_answer_0(rid, ENOENT); 480 530 return; 481 531 } 482 532 483 ipc_answer_ 5(rid, EOK, fs_handle, dev_handle, index,484 ops->size_get(node), ops->lnkcnt_get(node));485 486 ops->node_put(node);533 ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn), 534 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 535 536 (void) ops->node_put(fn); 487 537 } 488 538 -
uspace/lib/libfs/libfs.h
rfcbd1be r1787e527 56 56 57 57 typedef struct { 58 fs_node_t * (* match)(fs_node_t *, const char *); 59 fs_node_t * (* node_get)(dev_handle_t, fs_index_t); 60 void (* node_put)(fs_node_t *); 61 fs_node_t * (* create)(dev_handle_t, int); 58 /* 59 * The first set of methods are functions that return an integer error 60 * code. If some additional return value is to be returned, the first 61 * argument holds the output argument. 62 */ 63 int (* root_get)(fs_node_t **, dev_handle_t); 64 int (* match)(fs_node_t **, fs_node_t *, const char *); 65 int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t); 66 int (* node_put)(fs_node_t *); 67 int (* create)(fs_node_t **, dev_handle_t, int); 62 68 int (* destroy)(fs_node_t *); 63 69 int (* link)(fs_node_t *, fs_node_t *, const char *); 64 70 int (* unlink)(fs_node_t *, fs_node_t *, const char *); 71 int (* has_children)(bool *, fs_node_t *); 72 /* 73 * The second set of methods are usually mere getters that do not return 74 * an integer error code. 75 */ 65 76 fs_index_t (* index_get)(fs_node_t *); 66 77 size_t (* size_get)(fs_node_t *); 67 78 unsigned (* lnkcnt_get)(fs_node_t *); 68 bool (* has_children)(fs_node_t *);69 fs_node_t *(* root_get)(dev_handle_t);70 79 char (* plb_get_char)(unsigned pos); 71 80 bool (* is_directory)(fs_node_t *); -
uspace/lib/softfloat/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Common compiler flags 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../libc 32 .PHONY: all clean 33 33 34 ## Setup toolchain 35 # 36 37 include $(LIBC_PREFIX)/Makefile.toolchain 38 39 CFLAGS += -Iinclude -Iarch/$(UARCH)/include/ 40 41 ## Sources 42 # 43 44 GENERIC_SOURCES = \ 45 generic/add.c \ 46 generic/common.c \ 47 generic/comparison.c \ 48 generic/conversion.c \ 49 generic/div.c \ 50 generic/mul.c \ 51 generic/other.c \ 52 generic/softfloat.c \ 53 generic/sub.c 54 55 ARCH_SOURCES = 56 57 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 58 59 .PHONY: all clean depend 60 61 all: libsoftfloat.a 62 63 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 64 37 65 38 clean: 66 -rm -f libsoftfloat.a Makefile.depend 67 find generic/ -name '*.o' -follow -exec rm \{\} \; 68 69 depend: 70 -makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null 71 72 libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 73 $(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 74 75 %.o: %.S 76 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 77 78 %.o: %.s 79 $(AS) $(AFLAGS) $< -o $@ 80 81 %.o: %.c 82 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(LIBSOFTFLOAT) 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/lib/softint/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Common compiler flags 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../libc 32 .PHONY: all clean 33 33 34 ## Setup toolchain 35 # 36 37 include $(LIBC_PREFIX)/Makefile.toolchain 38 39 CFLAGS += -Iinclude 40 41 ## Sources 42 # 43 44 ARCH_SOURCES = 45 46 GENERIC_SOURCES = \ 47 generic/division.c 48 49 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 50 51 .PHONY: all clean depend 52 53 all: libsoftint.a 54 55 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBC_PREFIX)/libc.a 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 56 37 57 38 clean: 58 -rm -f libsoftint.a Makefile.depend 59 find generic/ -name '*.o' -follow -exec rm \{\} \; 60 61 depend: 62 -makedepend -f - -- $(DEPEMD_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null 63 64 libsoftint.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 65 $(AR) rc libsoftint.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) 66 67 %.o: %.S 68 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 69 70 %.o: %.s 71 $(AS) $(AFLAGS) $< -o $@ 72 73 %.o: %.c 74 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(LIBSOFTINT) 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/lib/softint/include/multiplication.h
rfcbd1be r1787e527 1 1 /* 2 * Copyright (c) 200 5 Jakub Jermar2 * Copyright (c) 2009 Josef Cejka 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup ia3229 /** @addtogroup softint 30 30 * @{ 31 */ 32 /** @file 31 */ 32 /** 33 * @file 33 34 */ 34 35 35 #ifndef KERN_ia32_ARG_H_36 #define KERN_ia32_ARG_H_36 #ifndef __SOFTINT_MULTIPLICATION_H__ 37 #define __SOFTINT_MULTIPLICATION_H__ 37 38 38 #include <stackarg.h> 39 /* 64 bit multiplication */ 40 long long __muldi3(long long a, long long b); 39 41 40 42 #endif … … 42 44 /** @} 43 45 */ 46 47
Note:
See TracChangeset
for help on using the changeset viewer.
