Changeset 04b73b6 for libcfa/src
- Timestamp:
- Jul 23, 2020, 3:37:05 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- f4ec4a90
- Parents:
- f0c3120 (diff), e262b5e (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:
- libcfa/src
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/io.cfa
rf0c3120 r04b73b6 16 16 #if defined(__CFA_DEBUG__) 17 17 // #define __CFA_DEBUG_PRINT_IO__ 18 #define __CFA_DEBUG_PRINT_IO_CORE__18 // #define __CFA_DEBUG_PRINT_IO_CORE__ 19 19 #endif 20 20 … … 22 22 #include "bitmanip.hfa" 23 23 24 #if !defined( HAVE_LINUX_IO_URING_H)24 #if !defined(CFA_HAVE_LINUX_IO_URING_H) 25 25 void __kernel_io_startup( cluster &, unsigned, bool ) { 26 26 // Nothing to do without io_uring … … 490 490 static uint32_t __release_consumed_submission( struct __io_data & ring ); 491 491 492 static inline void process(struct io_uring_cqe & cqe, struct __processor_id_t * id ) { 493 struct __io_user_data_t * data = (struct __io_user_data_t *)(uintptr_t)cqe.user_data; 494 __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", data, cqe.res, data->thrd ); 495 496 data->result = cqe.res; 497 if(!id) { unpark( data->thrd __cfaabi_dbg_ctx2 ); } 498 else { __unpark( id, data->thrd __cfaabi_dbg_ctx2 ); } 499 } 500 492 501 // Process a single completion message from the io_uring 493 502 // This is NOT thread-safe … … 538 547 /* paranoid */ verify(&cqe); 539 548 540 struct __io_user_data_t * data = (struct __io_user_data_t *)(uintptr_t)cqe.user_data; 541 __cfadbg_print_safe( io, "Kernel I/O : Performed reading io cqe %p, result %d for %p\n", data, cqe.res, data->thrd ); 542 543 data->result = cqe.res; 544 if(!mask) { unpark( data->thrd __cfaabi_dbg_ctx2 ); } 545 else { __unpark( &ring.poller.slow.id, data->thrd __cfaabi_dbg_ctx2 ); } 549 process( cqe, !mask ? (struct __processor_id_t *)0p : &ring.poller.slow.id ); 546 550 } 547 551 -
libcfa/src/concurrency/iocall.cfa
rf0c3120 r04b73b6 20 20 //============================================================================================= 21 21 22 #if defined( HAVE_LINUX_IO_URING_H)22 #if defined(CFA_HAVE_LINUX_IO_URING_H) 23 23 #include <stdint.h> 24 24 #include <linux/io_uring.h> … … 122 122 #if defined(HAVE_PREADV2) 123 123 ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) { 124 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)124 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READV) 125 125 return preadv2(fd, iov, iovcnt, offset, flags); 126 126 #else … … 134 134 135 135 ssize_t cfa_preadv2_fixed(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) { 136 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)136 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READV) 137 137 return preadv2(fd, iov, iovcnt, offset, flags); 138 138 #else … … 149 149 #if defined(HAVE_PWRITEV2) 150 150 ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) { 151 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITEV)151 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_WRITEV) 152 152 return pwritev2(fd, iov, iovcnt, offset, flags); 153 153 #else … … 162 162 163 163 int cfa_fsync(int fd) { 164 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FSYNC)164 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FSYNC) 165 165 return fsync(fd); 166 166 #else … … 174 174 175 175 int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags) { 176 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SYNC_FILE_RANGE)176 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SYNC_FILE_RANGE) 177 177 return sync_file_range(fd, offset, nbytes, flags); 178 178 #else … … 190 190 191 191 ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags) { 192 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SENDMSG)192 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SENDMSG) 193 193 return sendmsg(sockfd, msg, flags); 194 194 #else … … 203 203 204 204 ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags) { 205 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECVMSG)205 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_RECVMSG) 206 206 return recvmsg(sockfd, msg, flags); 207 207 #else … … 216 216 217 217 ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags) { 218 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SEND)218 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SEND) 219 219 return send( sockfd, buf, len, flags ); 220 220 #else … … 231 231 232 232 ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags) { 233 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECV)233 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_RECV) 234 234 return recv( sockfd, buf, len, flags ); 235 235 #else … … 246 246 247 247 int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { 248 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_ACCEPT)248 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_ACCEPT) 249 249 return accept4( sockfd, addr, addrlen, flags ); 250 250 #else … … 261 261 262 262 int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { 263 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CONNECT)263 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_CONNECT) 264 264 return connect( sockfd, addr, addrlen ); 265 265 #else … … 275 275 276 276 int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len) { 277 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FALLOCATE)277 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FALLOCATE) 278 278 return fallocate( fd, mode, offset, len ); 279 279 #else … … 290 290 291 291 int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice) { 292 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FADVISE)292 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FADVISE) 293 293 return posix_fadvise( fd, offset, len, advice ); 294 294 #else … … 305 305 306 306 int cfa_madvise(void *addr, size_t length, int advice) { 307 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_MADVISE)307 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_MADVISE) 308 308 return madvise( addr, length, advice ); 309 309 #else … … 320 320 321 321 int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode) { 322 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_OPENAT)322 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_OPENAT) 323 323 return openat( dirfd, pathname, flags, mode ); 324 324 #else … … 335 335 336 336 int cfa_close(int fd) { 337 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CLOSE)337 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_CLOSE) 338 338 return close( fd ); 339 339 #else … … 349 349 struct statx; 350 350 int cfa_statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf) { 351 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_STATX)351 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_STATX) 352 352 #if defined(__NR_statx) 353 353 return syscall( __NR_statx, dirfd, pathname, flags, mask, statxbuf ); … … 367 367 368 368 ssize_t cfa_read(int fd, void *buf, size_t count) { 369 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READ)369 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READ) 370 370 return read( fd, buf, count ); 371 371 #else … … 379 379 380 380 ssize_t cfa_write(int fd, void *buf, size_t count) { 381 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITE)381 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_WRITE) 382 382 return read( fd, buf, count ); 383 383 #else … … 391 391 392 392 ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags) { 393 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SPLICE)393 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SPLICE) 394 394 return splice( fd_in, off_in, fd_out, off_out, len, flags ); 395 395 #else … … 405 405 } 406 406 407 ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags, int in_flags, int out_flags) { 408 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SPLICE) 409 return splice( fd_in, off_in, fd_out, off_out, len, flags ); 410 #else 411 __submit_prelude 412 413 (*sqe){ IORING_OP_SPLICE, fd_out, 0p, len, off_out }; 414 sqe->splice_fd_in = fd_in; 415 sqe->splice_off_in = off_in; 416 sqe->splice_flags = flags | out_flags; 417 sqe->flags = in_flags; 418 419 __submit_wait 420 #endif 421 } 422 407 423 ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags) { 408 #if !defined( HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_TEE)424 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_TEE) 409 425 return tee( fd_in, fd_out, len, flags ); 410 426 #else … … 429 445 430 446 bool has_user_level_blocking( fptr_t func ) { 431 #if defined( HAVE_LINUX_IO_URING_H)447 #if defined(CFA_HAVE_LINUX_IO_URING_H) 432 448 #if defined(HAVE_PREADV2) 433 449 if( /*func == (fptr_t)preadv2 || */ 434 450 func == (fptr_t)cfa_preadv2 ) 435 #define _CFA_IO_FEATURE_ IORING_OP_READV ,436 return IS_DEFINED( IORING_OP_READV);451 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_READV , 452 return IS_DEFINED(CFA_HAVE_IORING_OP_READV); 437 453 #endif 438 454 … … 440 456 if( /*func == (fptr_t)pwritev2 || */ 441 457 func == (fptr_t)cfa_pwritev2 ) 442 #define _CFA_IO_FEATURE_ IORING_OP_WRITEV ,443 return IS_DEFINED( IORING_OP_WRITEV);458 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_WRITEV , 459 return IS_DEFINED(CFA_HAVE_IORING_OP_WRITEV); 444 460 #endif 445 461 446 462 if( /*func == (fptr_t)fsync || */ 447 463 func == (fptr_t)cfa_fsync ) 448 #define _CFA_IO_FEATURE_ IORING_OP_FSYNC ,449 return IS_DEFINED( IORING_OP_FSYNC);464 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FSYNC , 465 return IS_DEFINED(CFA_HAVE_IORING_OP_FSYNC); 450 466 451 467 if( /*func == (fptr_t)ync_file_range || */ 452 468 func == (fptr_t)cfa_sync_file_range ) 453 #define _CFA_IO_FEATURE_ IORING_OP_SYNC_FILE_RANGE ,454 return IS_DEFINED( IORING_OP_SYNC_FILE_RANGE);469 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SYNC_FILE_RANGE , 470 return IS_DEFINED(CFA_HAVE_IORING_OP_SYNC_FILE_RANGE); 455 471 456 472 if( /*func == (fptr_t)sendmsg || */ 457 473 func == (fptr_t)cfa_sendmsg ) 458 #define _CFA_IO_FEATURE_ IORING_OP_SENDMSG ,459 return IS_DEFINED( IORING_OP_SENDMSG);474 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SENDMSG , 475 return IS_DEFINED(CFA_HAVE_IORING_OP_SENDMSG); 460 476 461 477 if( /*func == (fptr_t)recvmsg || */ 462 478 func == (fptr_t)cfa_recvmsg ) 463 #define _CFA_IO_FEATURE_ IORING_OP_RECVMSG ,464 return IS_DEFINED( IORING_OP_RECVMSG);479 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_RECVMSG , 480 return IS_DEFINED(CFA_HAVE_IORING_OP_RECVMSG); 465 481 466 482 if( /*func == (fptr_t)send || */ 467 483 func == (fptr_t)cfa_send ) 468 #define _CFA_IO_FEATURE_ IORING_OP_SEND ,469 return IS_DEFINED( IORING_OP_SEND);484 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SEND , 485 return IS_DEFINED(CFA_HAVE_IORING_OP_SEND); 470 486 471 487 if( /*func == (fptr_t)recv || */ 472 488 func == (fptr_t)cfa_recv ) 473 #define _CFA_IO_FEATURE_ IORING_OP_RECV ,474 return IS_DEFINED( IORING_OP_RECV);489 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_RECV , 490 return IS_DEFINED(CFA_HAVE_IORING_OP_RECV); 475 491 476 492 if( /*func == (fptr_t)accept4 || */ 477 493 func == (fptr_t)cfa_accept4 ) 478 #define _CFA_IO_FEATURE_ IORING_OP_ACCEPT ,479 return IS_DEFINED( IORING_OP_ACCEPT);494 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_ACCEPT , 495 return IS_DEFINED(CFA_HAVE_IORING_OP_ACCEPT); 480 496 481 497 if( /*func == (fptr_t)connect || */ 482 498 func == (fptr_t)cfa_connect ) 483 #define _CFA_IO_FEATURE_ IORING_OP_CONNECT ,484 return IS_DEFINED( IORING_OP_CONNECT);499 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_CONNECT , 500 return IS_DEFINED(CFA_HAVE_IORING_OP_CONNECT); 485 501 486 502 if( /*func == (fptr_t)fallocate || */ 487 503 func == (fptr_t)cfa_fallocate ) 488 #define _CFA_IO_FEATURE_ IORING_OP_FALLOCATE ,489 return IS_DEFINED( IORING_OP_FALLOCATE);504 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FALLOCATE , 505 return IS_DEFINED(CFA_HAVE_IORING_OP_FALLOCATE); 490 506 491 507 if( /*func == (fptr_t)posix_fadvise || */ 492 508 func == (fptr_t)cfa_fadvise ) 493 #define _CFA_IO_FEATURE_ IORING_OP_FADVISE ,494 return IS_DEFINED( IORING_OP_FADVISE);509 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FADVISE , 510 return IS_DEFINED(CFA_HAVE_IORING_OP_FADVISE); 495 511 496 512 if( /*func == (fptr_t)madvise || */ 497 513 func == (fptr_t)cfa_madvise ) 498 #define _CFA_IO_FEATURE_ IORING_OP_MADVISE ,499 return IS_DEFINED( IORING_OP_MADVISE);514 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_MADVISE , 515 return IS_DEFINED(CFA_HAVE_IORING_OP_MADVISE); 500 516 501 517 if( /*func == (fptr_t)openat || */ 502 518 func == (fptr_t)cfa_openat ) 503 #define _CFA_IO_FEATURE_ IORING_OP_OPENAT ,504 return IS_DEFINED( IORING_OP_OPENAT);519 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_OPENAT , 520 return IS_DEFINED(CFA_HAVE_IORING_OP_OPENAT); 505 521 506 522 if( /*func == (fptr_t)close || */ 507 523 func == (fptr_t)cfa_close ) 508 #define _CFA_IO_FEATURE_ IORING_OP_CLOSE ,509 return IS_DEFINED( IORING_OP_CLOSE);524 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_CLOSE , 525 return IS_DEFINED(CFA_HAVE_IORING_OP_CLOSE); 510 526 511 527 if( /*func == (fptr_t)read || */ 512 528 func == (fptr_t)cfa_read ) 513 #define _CFA_IO_FEATURE_ IORING_OP_READ ,514 return IS_DEFINED( IORING_OP_READ);529 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_READ , 530 return IS_DEFINED(CFA_HAVE_IORING_OP_READ); 515 531 516 532 if( /*func == (fptr_t)write || */ 517 533 func == (fptr_t)cfa_write ) 518 #define _CFA_IO_FEATURE_ IORING_OP_WRITE ,519 return IS_DEFINED( IORING_OP_WRITE);534 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_WRITE , 535 return IS_DEFINED(CFA_HAVE_IORING_OP_WRITE); 520 536 521 537 if( /*func == (fptr_t)splice || */ 522 func == (fptr_t)cfa_splice ) 523 #define _CFA_IO_FEATURE_IORING_OP_SPLICE , 524 return IS_DEFINED(IORING_OP_SPLICE); 538 func == (fptr_t)(ssize_t (*)(int, loff_t *, int, loff_t *, size_t, unsigned int))cfa_splice, 539 func == (fptr_t)(ssize_t (*)(int, loff_t *, int, loff_t *, size_t, unsigned int, int, int))cfa_splice ) 540 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SPLICE , 541 return IS_DEFINED(CFA_HAVE_IORING_OP_SPLICE); 525 542 526 543 if( /*func == (fptr_t)tee || */ 527 544 func == (fptr_t)cfa_tee ) 528 #define _CFA_IO_FEATURE_ IORING_OP_TEE ,529 return IS_DEFINED( IORING_OP_TEE);545 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_TEE , 546 return IS_DEFINED(CFA_HAVE_IORING_OP_TEE); 530 547 #endif 531 548 -
libcfa/src/concurrency/kernel.cfa
rf0c3120 r04b73b6 228 228 static void * __invoke_processor(void * arg); 229 229 230 void ?{}(processor & this, const char name[], cluster & _cltr) with( this ) {230 static init(processor & this, const char name[], cluster & _cltr) with( this ) { 231 231 this.name = name; 232 232 this.cltr = &_cltr; 233 233 id = -1u; 234 terminated{ 0 };235 234 destroyer = 0p; 236 235 do_terminate = false; 237 236 preemption_alarm = 0p; 238 237 pending_preemption = false; 239 runner.proc = &this;240 238 241 239 #if !defined(__CFA_NO_STATISTICS__) … … 244 242 #endif 245 243 246 idle{}; 244 __atomic_fetch_add( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST ); 245 246 id = doregister((__processor_id_t*)&this); 247 248 // Lock the RWlock so no-one pushes/pops while we are changing the queue 249 uint_fast32_t last_size = ready_mutate_lock(); 250 251 // Adjust the ready queue size 252 ready_queue_grow( cltr ); 253 254 // Unlock the RWlock 255 ready_mutate_unlock( last_size ); 256 257 __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this); 258 } 259 260 // Not a ctor, it just preps the destruction but should not destroy members 261 void deinit(processor & this) { 262 // Lock the RWlock so no-one pushes/pops while we are changing the queue 263 uint_fast32_t last_size = ready_mutate_lock(); 264 265 // Adjust the ready queue size 266 ready_queue_shrink( this.cltr ); 267 268 // Make sure we aren't on the idle queue 269 unsafe_remove( this.cltr->idles, &this ); 270 271 // Unlock the RWlock 272 ready_mutate_unlock( last_size ); 273 274 // Finally we don't need the read_lock any more 275 unregister((__processor_id_t*)&this); 276 } 277 278 void ?{}(processor & this, const char name[], cluster & _cltr) { 279 ( this.idle ){}; 280 ( this.terminated ){ 0 }; 281 ( this.runner ){}; 282 init( this, name, _cltr ); 247 283 248 284 __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this); 249 285 250 286 this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this ); 251 __atomic_fetch_add( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST ); 252 253 __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this); 287 254 288 } 255 289 … … 269 303 270 304 free( this.stack ); 305 306 deinit( this ); 271 307 272 308 __atomic_fetch_sub( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST ); … … 318 354 319 355 __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this); 320 321 // register the processor unless it's the main thread which is handled in the boot sequence 322 if(this != mainProcessor) { 323 this->id = doregister((__processor_id_t*)this); 324 #if !defined(__CFA_NO_STATISTICS__) 325 if( this->print_halts ) { 326 __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->id, this->name, (void*)this); 327 } 328 #endif 329 330 // Lock the RWlock so no-one pushes/pops while we are changing the queue 331 uint_fast32_t last_size = ready_mutate_lock(); 332 333 // Adjust the ready queue size 334 ready_queue_grow( this->cltr ); 335 336 // Unlock the RWlock 337 ready_mutate_unlock( last_size ); 338 } 356 #if !defined(__CFA_NO_STATISTICS__) 357 if( this->print_halts ) { 358 __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->id, this->name, (void*)this); 359 } 360 #endif 339 361 340 362 { … … 375 397 V( this->terminated ); 376 398 377 // unregister the processor unless it's the main thread which is handled in the boot sequence 378 if(this != mainProcessor) { 379 // Lock the RWlock so no-one pushes/pops while we are changing the queue 380 uint_fast32_t last_size = ready_mutate_lock(); 381 382 // Adjust the ready queue size 383 ready_queue_shrink( this->cltr ); 384 385 // Make sure we aren't on the idle queue 386 #if !defined(__CFA_NO_STATISTICS__) 387 bool removed = 388 #endif 389 unsafe_remove( this->cltr->idles, this ); 390 391 #if !defined(__CFA_NO_STATISTICS__) 392 if(removed) __tls_stats()->ready.sleep.exits++; 393 #endif 394 395 // Unlock the RWlock 396 ready_mutate_unlock( last_size ); 397 398 // Finally we don't need the read_lock any more 399 unregister((__processor_id_t*)this); 400 } 401 else { 399 if(this == mainProcessor) { 402 400 // HACK : the coroutine context switch expects this_thread to be set 403 401 // and it make sense for it to be set in all other cases except here … … 859 857 860 858 void ?{}(processor & this) with( this ) { 861 name = "Main Processor"; 862 cltr = mainCluster; 863 terminated{ 0 }; 864 do_terminate = false; 865 preemption_alarm = 0p; 866 pending_preemption = false; 859 ( this.idle ){}; 860 ( this.terminated ){ 0 }; 861 ( this.runner ){}; 862 init( this, "Main Processor", *mainCluster ); 867 863 kernel_thread = pthread_self(); 868 id = -1u;869 870 #if !defined(__CFA_NO_STATISTICS__)871 print_stats = false;872 print_halts = false;873 #endif874 864 875 865 runner{ &this }; 876 866 __cfadbg_print_safe(runtime_core, "Kernel : constructed main processor context %p\n", &runner); 877 878 __atomic_fetch_add( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );879 867 } 880 868 … … 883 871 mainProcessor = (processor *)&storage_mainProcessor; 884 872 (*mainProcessor){}; 885 886 mainProcessor->id = doregister( (__processor_id_t*)mainProcessor);887 873 888 874 //initialize the global state variables … … 944 930 kernel_stop_preemption(); 945 931 946 unregister((__processor_id_t*)mainProcessor);947 948 932 // Destroy the main processor and its context in reverse order of construction 949 933 // These were manually constructed so we need manually destroy them 950 934 void ^?{}(processor & this) with( this ){ 935 deinit( this ); 936 951 937 /* paranoid */ verify( this.do_terminate == true ); 952 938 __atomic_fetch_sub( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST ); -
libcfa/src/concurrency/ready_queue.cfa
rf0c3120 r04b73b6 186 186 //======================================================================= 187 187 void ?{}(__ready_queue_t & this) with (this) { 188 189 lanes.data = alloc(4); 190 for( i; 4 ) { 191 (lanes.data[i]){}; 192 } 193 lanes.count = 4; 194 snzi{ log2( lanes.count / 8 ) }; 188 lanes.data = 0p; 189 lanes.count = 0; 195 190 } 196 191 197 192 void ^?{}(__ready_queue_t & this) with (this) { 198 verify( 4== lanes.count );193 verify( 0 == lanes.count ); 199 194 verify( !query( snzi ) ); 200 201 ^(snzi){};202 203 for( i; 4 ) {204 ^(lanes.data[i]){};205 }206 195 free(lanes.data); 207 196 } … … 495 484 } 496 485 486 #warning remove when alloc is fixed 487 forall( dtype T | sized(T) ) 488 static inline T * correct_alloc( T ptr[], size_t dim ) { 489 if( dim == 0 ) { 490 free(ptr); 491 return 0p; 492 } 493 T * temp = alloc( dim ); 494 if(ptr) { 495 memcpy( temp, ptr, dim * sizeof(T)); 496 free(ptr); 497 } 498 return temp; 499 } 500 497 501 // Grow the ready queue 498 502 void ready_queue_grow (struct cluster * cltr) { … … 513 517 514 518 // Allocate new array (uses realloc and memcpies the data) 515 lanes.data = alloc(lanes.data, ncount);519 lanes.data = correct_alloc(lanes.data, ncount); 516 520 517 521 // Fix the moved data … … 558 562 size_t ocount = lanes.count; 559 563 // Check that we have some space left 560 if(ocount < 8) abort("Program attempted to destroy more Ready Queues than were created");564 if(ocount < 4) abort("Program attempted to destroy more Ready Queues than were created"); 561 565 562 566 // reduce the actual count so push doesn't use the old queues … … 600 604 601 605 // Allocate new array (uses realloc and memcpies the data) 602 lanes.data = alloc(lanes.data, lanes.count);606 lanes.data = correct_alloc(lanes.data, lanes.count); 603 607 604 608 // Fix the moved data -
libcfa/src/concurrency/snzi.hfa
rf0c3120 r04b73b6 120 120 //-------------------------------------------------- 121 121 // SNZI object 122 void ?{}( __snzi_t & this ) { 123 this.mask = 0; 124 this.root = 0; 125 this.nodes = 0p; 126 } 127 122 128 void ?{}( __snzi_t & this, unsigned depth ) with( this ) { 123 129 mask = (1 << depth) - 1; -
libcfa/src/concurrency/stats.cfa
rf0c3120 r04b73b6 24 24 stats->ready.sleep.exits = 0; 25 25 26 #if defined( HAVE_LINUX_IO_URING_H)26 #if defined(CFA_HAVE_LINUX_IO_URING_H) 27 27 stats->io.submit_q.submit_avg.rdy = 0; 28 28 stats->io.submit_q.submit_avg.csm = 0; … … 59 59 __atomic_fetch_add( &cltr->ready.sleep.exits , proc->ready.sleep.exits , __ATOMIC_SEQ_CST ); 60 60 61 #if defined( HAVE_LINUX_IO_URING_H)61 #if defined(CFA_HAVE_LINUX_IO_URING_H) 62 62 __atomic_fetch_add( &cltr->io.submit_q.submit_avg.rdy , proc->io.submit_q.submit_avg.rdy , __ATOMIC_SEQ_CST ); 63 63 __atomic_fetch_add( &cltr->io.submit_q.submit_avg.csm , proc->io.submit_q.submit_avg.csm , __ATOMIC_SEQ_CST ); … … 121 121 } 122 122 123 #if defined( HAVE_LINUX_IO_URING_H)123 #if defined(CFA_HAVE_LINUX_IO_URING_H) 124 124 if( flags & CFA_STATS_IO ) { 125 125 double avgrdy = ((double)io.submit_q.submit_avg.rdy) / io.submit_q.submit_avg.cnt; -
libcfa/src/concurrency/stats.hfa
rf0c3120 r04b73b6 11 11 enum { 12 12 CFA_STATS_READY_Q = 0x01, 13 #if defined( HAVE_LINUX_IO_URING_H)13 #if defined(CFA_HAVE_LINUX_IO_URING_H) 14 14 CFA_STATS_IO = 0x02, 15 15 #endif … … 64 64 }; 65 65 66 #if defined( HAVE_LINUX_IO_URING_H)66 #if defined(CFA_HAVE_LINUX_IO_URING_H) 67 67 struct __attribute__((aligned(64))) __stats_io_t{ 68 68 struct { … … 99 99 struct __attribute__((aligned(128))) __stats_t { 100 100 __stats_readQ_t ready; 101 #if defined( HAVE_LINUX_IO_URING_H)101 #if defined(CFA_HAVE_LINUX_IO_URING_H) 102 102 __stats_io_t io; 103 103 #endif -
libcfa/src/heap.cfa
rf0c3120 r04b73b6 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jun 13 22:42:15202013 // Update Count : 80 512 // Last Modified On : Mon Jul 20 23:00:32 2020 13 // Update Count : 808 14 14 // 15 15 … … 901 901 if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 902 902 header->kind.real.blockSize &= -2; // no alignment and turn off 0 fill 903 if ( size != odsize ) header->kind.real.size = size; // reset allocation size 903 904 return oaddr; 904 905 } // if … … 929 930 930 931 size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket 931 if ( size <= odsize && odsize <= size * 2 ) { // allow up to 50% wasted storage in smaller size 932 // Do not know size of original allocation => cannot do 0 fill for any additional space because do not know 933 // where to start filling, i.e., do not overwrite existing values in space. 932 if ( size <= odsize && odsize <= size * 2 ) { // allow up to 50% wasted storage in smaller size 933 if ( size != odsize ) header->kind.real.size = size; // reset allocation size 934 934 return oaddr; 935 935 } // if … … 1098 1098 // Returns original total allocation size (not bucket size) => array size is dimension * sizeif(T). 1099 1099 size_t malloc_size( void * addr ) { 1100 if ( unlikely( addr == 0p ) ) return false; // null allocation is not zero fill1100 if ( unlikely( addr == 0p ) ) return 0; // null allocation has zero size 1101 1101 HeapManager.Storage.Header * header = headerAddr( addr ); 1102 1102 if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ? … … 1108 1108 // Set allocation size and return previous size. 1109 1109 size_t $malloc_size_set( void * addr, size_t size ) { 1110 if ( unlikely( addr == 0p ) ) return false; // null allocation is not zero fill1110 if ( unlikely( addr == 0p ) ) return 0; // null allocation has 0 size 1111 1111 HeapManager.Storage.Header * header = headerAddr( addr ); 1112 1112 if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ? … … 1227 1227 if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size 1228 1228 header->kind.real.blockSize &= -2; // turn off 0 fill 1229 if ( size != odsize ) header->kind.real.size = size; // reset allocation size 1229 1230 return oaddr; 1230 1231 } // if -
libcfa/src/heap.hfa
rf0c3120 r04b73b6 10 10 // Created On : Tue May 26 11:23:55 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Ju n 1 21:19:00202013 // Update Count : 1 012 // Last Modified On : Mon Jul 20 18:52:31 2020 13 // Update Count : 11 14 14 // 15 15 … … 35 35 void * resize( void * oaddr, size_t size ); 36 36 void * amemalign( size_t align, size_t dim, size_t elemSize ); 37 void * cmemalign( size_t align, size_t noOfElems, size_t elemSize );37 void * cmemalign( size_t align, size_t dim, size_t elemSize ); 38 38 size_t malloc_alignment( void * addr ); 39 39 bool malloc_zero_fill( void * addr ); -
libcfa/src/iostream.cfa
rf0c3120 r04b73b6 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 16 07:43:31202013 // Update Count : 11 0212 // Last Modified On : Mon Jul 20 15:00:37 2020 13 // Update Count : 1124 14 14 // 15 15 … … 167 167 #define P10_UINT64 10_000_000_000_000_000_000_ULL // 19 zeroes 168 168 169 static void base10_128( ostype & os, unsigned int128 val ) { 169 static inline void base10_128( ostype & os, unsigned int128 val ) { 170 #if defined(__GNUC__) && __GNUC_PREREQ(7,0) // gcc version >= 7 170 171 if ( val > P10_UINT64 ) { 172 #else 173 if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug 174 #endif // __GNUC_PREREQ(7,0) 171 175 base10_128( os, val / P10_UINT64 ); // recursive 172 176 fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) ); … … 176 180 } // base10_128 177 181 178 static void base10_128( ostype & os, int128 val ) {182 static inline void base10_128( ostype & os, int128 val ) { 179 183 if ( val < 0 ) { 180 184 fmt( os, "-" ); // leading negative sign -
libcfa/src/stdlib.cfa
rf0c3120 r04b73b6 9 9 // Author : Peter A. Buhr 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Jun 2 16:46:00202013 // Update Count : 50 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 19 15:05:28 2020 13 // Update Count : 501 14 14 // 15 15 … … 25 25 26 26 //--------------------------------------- 27 28 forall( dtype T | sized(T) ) {29 T * alloc_set( T ptr[], size_t dim, char fill ) { // realloc array with fill30 size_t olen = malloc_usable_size( ptr ); // current allocation31 void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc32 size_t nlen = malloc_usable_size( nptr ); // new allocation33 if ( nlen > olen ) { // larger ?34 memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage35 } // if36 return (T *)nptr;37 } // alloc_set38 39 T * alloc_set( T ptr[], size_t dim, T fill ) { // realloc array with fill40 size_t olen = malloc_usable_size( ptr ); // current allocation41 void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc42 size_t nlen = malloc_usable_size( nptr ); // new allocation43 if ( nlen > olen ) { // larger ?44 for ( i; malloc_size( ptr ) / sizeof(T) ~ dim ) {45 memcpy( &ptr[i], &fill, sizeof(T) ); // initialize with fill value46 } // for47 } // if48 return (T *)nptr;49 } // alloc_align_set50 51 T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill52 size_t olen = malloc_usable_size( ptr ); // current allocation53 void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc54 // char * nptr = alloc_align( ptr, align );55 size_t nlen = malloc_usable_size( nptr ); // new allocation56 if ( nlen > olen ) { // larger ?57 memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage58 } // if59 return (T *)nptr;60 } // alloc_align_set61 62 T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ) { // aligned realloc with fill63 size_t olen = malloc_usable_size( ptr ); // current allocation64 void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc65 // char * nptr = alloc_align( ptr, align );66 size_t nlen = malloc_usable_size( nptr ); // new allocation67 if ( nlen > olen ) { // larger ?68 for ( i; dim ) { memcpy( &ptr[i], &fill, sizeof(T) ); } // initialize with fill value69 } // if70 return (T *)nptr;71 } // alloc_align_set72 } // distribution73 27 74 28 // allocation/deallocation and constructor/destructor, non-array types -
libcfa/src/stdlib.hfa
rf0c3120 r04b73b6 9 9 // Author : Peter A. Buhr 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Ju n 2 16:47:00202013 // Update Count : 4 5111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 21 07:58:05 2020 13 // Update Count : 475 14 14 // 15 15 … … 39 39 //--------------------------------------- 40 40 41 // Macro because of returns 42 #define $VAR_ALLOC( allocation, alignment ) \ 43 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( (size_t)sizeof(T) ); /* C allocation */ \ 44 else return (T *)alignment( _Alignof(T), sizeof(T) ) 45 46 #define $ARRAY_ALLOC( allocation, alignment, dim ) \ 47 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( dim, (size_t)sizeof(T) ); /* C allocation */ \ 48 else return (T *)alignment( _Alignof(T), dim, sizeof(T) ) 49 50 #define $RE_SPECIALS( ptr, size, allocation, alignment ) \ 51 if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { \ 52 if ( unlikely( size == 0 ) ) free( ptr ); \ 53 $VAR_ALLOC( malloc, memalign ); \ 54 } /* if */ 55 41 56 static inline forall( dtype T | sized(T) ) { 42 57 // Cforall safe equivalents, i.e., implicit size specification 43 58 44 59 T * malloc( void ) { 45 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc 46 else return (T *)memalign( _Alignof(T), sizeof(T) ); 60 $VAR_ALLOC( malloc, memalign ); 47 61 } // malloc 48 62 49 63 T * aalloc( size_t dim ) { 50 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)aalloc( dim, (size_t)sizeof(T) ); // CFA aalloc 51 else return (T *)amemalign( _Alignof(T), dim, sizeof(T) ); 64 $ARRAY_ALLOC( aalloc, amemalign, dim ); 52 65 } // aalloc 53 66 54 67 T * calloc( size_t dim ) { 55 if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc 56 else return (T *)cmemalign( _Alignof(T), dim, sizeof(T) ); 68 $ARRAY_ALLOC( calloc, cmemalign, dim ); 57 69 } // calloc 58 70 59 T * resize( T * ptr, size_t size ) { // CFA realloc, eliminate return-type cast 60 return (T *)(void *)resize( (void *)ptr, size ); // C realloc 71 T * resize( T * ptr, size_t size ) { // CFA resize, eliminate return-type cast 72 $RE_SPECIALS( ptr, size, malloc, memalign ); 73 return (T *)(void *)resize( (void *)ptr, size ); // CFA resize 61 74 } // resize 62 75 63 76 T * realloc( T * ptr, size_t size ) { // CFA realloc, eliminate return-type cast 77 $RE_SPECIALS( ptr, size, malloc, memalign ); 64 78 return (T *)(void *)realloc( (void *)ptr, size ); // C realloc 65 79 } // realloc … … 118 132 119 133 T * alloc( T ptr[], size_t dim, bool copy = true ) { 120 if ( copy ) { // realloc121 return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // Crealloc134 if ( copy ) { 135 return realloc( ptr, dim * sizeof(T) ); // CFA realloc 122 136 } else { 123 return resize( ptr, dim * sizeof(T) ); // resize137 return resize( ptr, dim * sizeof(T) ); // CFA resize 124 138 } // if 125 139 } // alloc … … 146 160 return (T *)memcpy( (T *)alloc( dim ), fill, dim * sizeof(T) ); // initialize with fill value 147 161 } // alloc 148 } // distribution 149 150 forall( dtype T | sized(T) ) { 151 T * alloc_set( T ptr[], size_t dim, char fill ); // realloc array with fill 152 T * alloc_set( T ptr[], size_t dim, T fill ); // realloc array with fill 162 163 T * alloc_set( T ptr[], size_t dim, char fill ) { // realloc array with fill 164 size_t osize = malloc_size( ptr ); // current allocation 165 size_t nsize = dim * sizeof(T); // new allocation 166 T * nptr = realloc( ptr, nsize ); // CFA realloc 167 if ( nsize > osize ) { // larger ? 168 memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage 169 } // if 170 return (T *)nptr; 171 } // alloc_set 172 173 T * alloc_set( T ptr[], size_t dim, T & fill ) { // realloc array with fill 174 size_t odim = malloc_size( ptr ) / sizeof(T); // current dimension 175 size_t nsize = dim * sizeof(T); // new allocation 176 size_t ndim = nsize / sizeof(T); // new dimension 177 T * nptr = realloc( ptr, nsize ); // CFA realloc 178 if ( ndim > odim ) { // larger ? 179 for ( i; odim ~ ndim ) { 180 memcpy( &nptr[i], &fill, sizeof(T) ); // initialize with fill value 181 } // for 182 } // if 183 return (T *)nptr; 184 } // alloc_align_set 153 185 } // distribution 154 186 … … 196 228 return (T *)memcpy( (T *)alloc_align( align, dim ), fill, dim * sizeof(T) ); 197 229 } // alloc_align 198 } // distribution 199 200 forall( dtype T | sized(T) ) { 201 T * alloc_align_set( T ptr[], size_t align, char fill ); // aligned realloc with fill 202 T * alloc_align_set( T ptr[], size_t align, T fill ); // aligned realloc with fill 203 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); // aligned realloc array with fill 204 T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ); // aligned realloc array with fill 230 231 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ) { 232 size_t osize = malloc_size( ptr ); // current allocation 233 size_t nsize = dim * sizeof(T); // new allocation 234 T * nptr = realloc( ptr, align, nsize ); // CFA realloc 235 if ( nsize > osize ) { // larger ? 236 memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage 237 } // if 238 return (T *)nptr; 239 } // alloc_align_set 240 241 T * alloc_align_set( T ptr[], size_t align, size_t dim, T & fill ) { 242 size_t odim = malloc_size( ptr ) / sizeof(T); // current dimension 243 size_t nsize = dim * sizeof(T); // new allocation 244 size_t ndim = nsize / sizeof(T); // new dimension 245 T * nptr = realloc( ptr, align, nsize ); // CFA realloc 246 if ( ndim > odim ) { // larger ? 247 for ( i; odim ~ ndim ) { 248 memcpy( &nptr[i], &fill, sizeof(T) ); // initialize with fill value 249 } // for 250 } // if 251 return (T *)nptr; 252 } // alloc_align_set 205 253 } // distribution 206 254
Note:
See TracChangeset
for help on using the changeset viewer.