Changeset 04b73b6 for libcfa/src


Ignore:
Timestamp:
Jul 23, 2020, 3:37:05 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/io.cfa

    rf0c3120 r04b73b6  
    1616#if defined(__CFA_DEBUG__)
    1717        // #define __CFA_DEBUG_PRINT_IO__
    18         #define __CFA_DEBUG_PRINT_IO_CORE__
     18        // #define __CFA_DEBUG_PRINT_IO_CORE__
    1919#endif
    2020
     
    2222#include "bitmanip.hfa"
    2323
    24 #if !defined(HAVE_LINUX_IO_URING_H)
     24#if !defined(CFA_HAVE_LINUX_IO_URING_H)
    2525        void __kernel_io_startup( cluster &, unsigned, bool ) {
    2626                // Nothing to do without io_uring
     
    490490        static uint32_t __release_consumed_submission( struct __io_data & ring );
    491491
     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
    492501        // Process a single completion message from the io_uring
    493502        // This is NOT thread-safe
     
    538547                        /* paranoid */ verify(&cqe);
    539548
    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 );
    546550                }
    547551
  • libcfa/src/concurrency/iocall.cfa

    rf0c3120 r04b73b6  
    2020//=============================================================================================
    2121
    22 #if defined(HAVE_LINUX_IO_URING_H)
     22#if defined(CFA_HAVE_LINUX_IO_URING_H)
    2323        #include <stdint.h>
    2424        #include <linux/io_uring.h>
     
    122122#if defined(HAVE_PREADV2)
    123123        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)
    125125                        return preadv2(fd, iov, iovcnt, offset, flags);
    126126                #else
     
    134134
    135135        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)
    137137                        return preadv2(fd, iov, iovcnt, offset, flags);
    138138                #else
     
    149149#if defined(HAVE_PWRITEV2)
    150150        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)
    152152                        return pwritev2(fd, iov, iovcnt, offset, flags);
    153153                #else
     
    162162
    163163int 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)
    165165                return fsync(fd);
    166166        #else
     
    174174
    175175int 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)
    177177                return sync_file_range(fd, offset, nbytes, flags);
    178178        #else
     
    190190
    191191ssize_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)
    193193                return sendmsg(sockfd, msg, flags);
    194194        #else
     
    203203
    204204ssize_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)
    206206                return recvmsg(sockfd, msg, flags);
    207207        #else
     
    216216
    217217ssize_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)
    219219                return send( sockfd, buf, len, flags );
    220220        #else
     
    231231
    232232ssize_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)
    234234                return recv( sockfd, buf, len, flags );
    235235        #else
     
    246246
    247247int 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)
    249249                return accept4( sockfd, addr, addrlen, flags );
    250250        #else
     
    261261
    262262int 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)
    264264                return connect( sockfd, addr, addrlen );
    265265        #else
     
    275275
    276276int 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)
    278278                return fallocate( fd, mode, offset, len );
    279279        #else
     
    290290
    291291int 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)
    293293                return posix_fadvise( fd, offset, len, advice );
    294294        #else
     
    305305
    306306int 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)
    308308                return madvise( addr, length, advice );
    309309        #else
     
    320320
    321321int 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)
    323323                return openat( dirfd, pathname, flags, mode );
    324324        #else
     
    335335
    336336int 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)
    338338                return close( fd );
    339339        #else
     
    349349struct statx;
    350350int 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)
    352352                #if defined(__NR_statx)
    353353                        return syscall( __NR_statx, dirfd, pathname, flags, mask, statxbuf );
     
    367367
    368368ssize_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)
    370370                return read( fd, buf, count );
    371371        #else
     
    379379
    380380ssize_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)
    382382                return read( fd, buf, count );
    383383        #else
     
    391391
    392392ssize_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)
    394394                return splice( fd_in, off_in, fd_out, off_out, len, flags );
    395395        #else
     
    405405}
    406406
     407ssize_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
    407423ssize_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)
    409425                return tee( fd_in, fd_out, len, flags );
    410426        #else
     
    429445
    430446bool has_user_level_blocking( fptr_t func ) {
    431         #if defined(HAVE_LINUX_IO_URING_H)
     447        #if defined(CFA_HAVE_LINUX_IO_URING_H)
    432448                #if defined(HAVE_PREADV2)
    433449                        if( /*func == (fptr_t)preadv2 || */
    434450                                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);
    437453                #endif
    438454
     
    440456                        if( /*func == (fptr_t)pwritev2 || */
    441457                                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);
    444460                #endif
    445461
    446462                if( /*func == (fptr_t)fsync || */
    447463                        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);
    450466
    451467                if( /*func == (fptr_t)ync_file_range || */
    452468                        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);
    455471
    456472                if( /*func == (fptr_t)sendmsg || */
    457473                        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);
    460476
    461477                if( /*func == (fptr_t)recvmsg || */
    462478                        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);
    465481
    466482                if( /*func == (fptr_t)send || */
    467483                        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);
    470486
    471487                if( /*func == (fptr_t)recv || */
    472488                        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);
    475491
    476492                if( /*func == (fptr_t)accept4 || */
    477493                        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);
    480496
    481497                if( /*func == (fptr_t)connect || */
    482498                        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);
    485501
    486502                if( /*func == (fptr_t)fallocate || */
    487503                        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);
    490506
    491507                if( /*func == (fptr_t)posix_fadvise || */
    492508                        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);
    495511
    496512                if( /*func == (fptr_t)madvise || */
    497513                        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);
    500516
    501517                if( /*func == (fptr_t)openat || */
    502518                        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);
    505521
    506522                if( /*func == (fptr_t)close || */
    507523                        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);
    510526
    511527                if( /*func == (fptr_t)read || */
    512528                        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);
    515531
    516532                if( /*func == (fptr_t)write || */
    517533                        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);
    520536
    521537                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);
    525542
    526543                if( /*func == (fptr_t)tee || */
    527544                        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);
    530547        #endif
    531548
  • libcfa/src/concurrency/kernel.cfa

    rf0c3120 r04b73b6  
    228228static void * __invoke_processor(void * arg);
    229229
    230 void ?{}(processor & this, const char name[], cluster & _cltr) with( this ) {
     230static init(processor & this, const char name[], cluster & _cltr) with( this ) {
    231231        this.name = name;
    232232        this.cltr = &_cltr;
    233233        id = -1u;
    234         terminated{ 0 };
    235234        destroyer = 0p;
    236235        do_terminate = false;
    237236        preemption_alarm = 0p;
    238237        pending_preemption = false;
    239         runner.proc = &this;
    240238
    241239        #if !defined(__CFA_NO_STATISTICS__)
     
    244242        #endif
    245243
    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
     261void 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
     278void ?{}(processor & this, const char name[], cluster & _cltr) {
     279        ( this.idle ){};
     280        ( this.terminated ){ 0 };
     281        ( this.runner ){};
     282        init( this, name, _cltr );
    247283
    248284        __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
    249285
    250286        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
    254288}
    255289
     
    269303
    270304        free( this.stack );
     305
     306        deinit( this );
    271307
    272308        __atomic_fetch_sub( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
     
    318354
    319355        __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
    339361
    340362        {
     
    375397        V( this->terminated );
    376398
    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) {
    402400                // HACK : the coroutine context switch expects this_thread to be set
    403401                // and it make sense for it to be set in all other cases except here
     
    859857
    860858        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 );
    867863                kernel_thread = pthread_self();
    868                 id = -1u;
    869 
    870                 #if !defined(__CFA_NO_STATISTICS__)
    871                         print_stats = false;
    872                         print_halts = false;
    873                 #endif
    874864
    875865                runner{ &this };
    876866                __cfadbg_print_safe(runtime_core, "Kernel : constructed main processor context %p\n", &runner);
    877 
    878                 __atomic_fetch_add( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
    879867        }
    880868
     
    883871        mainProcessor = (processor *)&storage_mainProcessor;
    884872        (*mainProcessor){};
    885 
    886         mainProcessor->id = doregister( (__processor_id_t*)mainProcessor);
    887873
    888874        //initialize the global state variables
     
    944930        kernel_stop_preemption();
    945931
    946         unregister((__processor_id_t*)mainProcessor);
    947 
    948932        // Destroy the main processor and its context in reverse order of construction
    949933        // These were manually constructed so we need manually destroy them
    950934        void ^?{}(processor & this) with( this ){
     935                deinit( this );
     936
    951937                /* paranoid */ verify( this.do_terminate == true );
    952938                __atomic_fetch_sub( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
  • libcfa/src/concurrency/ready_queue.cfa

    rf0c3120 r04b73b6  
    186186//=======================================================================
    187187void ?{}(__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;
    195190}
    196191
    197192void ^?{}(__ready_queue_t & this) with (this) {
    198         verify( 4  == lanes.count );
     193        verify( 0  == lanes.count );
    199194        verify( !query( snzi ) );
    200 
    201         ^(snzi){};
    202 
    203         for( i; 4 ) {
    204                 ^(lanes.data[i]){};
    205         }
    206195        free(lanes.data);
    207196}
     
    495484}
    496485
     486#warning remove when alloc is fixed
     487forall( dtype T | sized(T) )
     488static 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
    497501// Grow the ready queue
    498502void ready_queue_grow  (struct cluster * cltr) {
     
    513517
    514518                // Allocate new array (uses realloc and memcpies the data)
    515                 lanes.data = alloc(lanes.data, ncount);
     519                lanes.data = correct_alloc(lanes.data, ncount);
    516520
    517521                // Fix the moved data
     
    558562                size_t ocount = lanes.count;
    559563                // 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");
    561565
    562566                // reduce the actual count so push doesn't use the old queues
     
    600604
    601605                // 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);
    603607
    604608                // Fix the moved data
  • libcfa/src/concurrency/snzi.hfa

    rf0c3120 r04b73b6  
    120120//--------------------------------------------------
    121121// SNZI object
     122void  ?{}( __snzi_t & this ) {
     123        this.mask = 0;
     124        this.root = 0;
     125        this.nodes = 0p;
     126}
     127
    122128void  ?{}( __snzi_t & this, unsigned depth ) with( this ) {
    123129        mask = (1 << depth) - 1;
  • libcfa/src/concurrency/stats.cfa

    rf0c3120 r04b73b6  
    2424                stats->ready.sleep.exits   = 0;
    2525
    26                 #if defined(HAVE_LINUX_IO_URING_H)
     26                #if defined(CFA_HAVE_LINUX_IO_URING_H)
    2727                        stats->io.submit_q.submit_avg.rdy = 0;
    2828                        stats->io.submit_q.submit_avg.csm = 0;
     
    5959                __atomic_fetch_add( &cltr->ready.sleep.exits  , proc->ready.sleep.exits  , __ATOMIC_SEQ_CST );
    6060
    61                 #if defined(HAVE_LINUX_IO_URING_H)
     61                #if defined(CFA_HAVE_LINUX_IO_URING_H)
    6262                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.rdy          , proc->io.submit_q.submit_avg.rdy          , __ATOMIC_SEQ_CST );
    6363                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.csm          , proc->io.submit_q.submit_avg.csm          , __ATOMIC_SEQ_CST );
     
    121121                }
    122122
    123                 #if defined(HAVE_LINUX_IO_URING_H)
     123                #if defined(CFA_HAVE_LINUX_IO_URING_H)
    124124                        if( flags & CFA_STATS_IO ) {
    125125                                double avgrdy = ((double)io.submit_q.submit_avg.rdy) / io.submit_q.submit_avg.cnt;
  • libcfa/src/concurrency/stats.hfa

    rf0c3120 r04b73b6  
    1111        enum {
    1212                CFA_STATS_READY_Q  = 0x01,
    13                 #if defined(HAVE_LINUX_IO_URING_H)
     13                #if defined(CFA_HAVE_LINUX_IO_URING_H)
    1414                        CFA_STATS_IO = 0x02,
    1515                #endif
     
    6464        };
    6565
    66         #if defined(HAVE_LINUX_IO_URING_H)
     66        #if defined(CFA_HAVE_LINUX_IO_URING_H)
    6767                struct __attribute__((aligned(64))) __stats_io_t{
    6868                        struct {
     
    9999        struct __attribute__((aligned(128))) __stats_t {
    100100                __stats_readQ_t ready;
    101                 #if defined(HAVE_LINUX_IO_URING_H)
     101                #if defined(CFA_HAVE_LINUX_IO_URING_H)
    102102                        __stats_io_t    io;
    103103                #endif
  • libcfa/src/heap.cfa

    rf0c3120 r04b73b6  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 13 22:42:15 2020
    13 // Update Count     : 805
     12// Last Modified On : Mon Jul 20 23:00:32 2020
     13// Update Count     : 808
    1414//
    1515
     
    901901          if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    902902                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
     903                        if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    903904                        return oaddr;
    904905                } // if
     
    929930
    930931                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
    934934                        return oaddr;
    935935                } // if
     
    10981098        // Returns original total allocation size (not bucket size) => array size is dimension * sizeif(T).
    10991099        size_t malloc_size( void * addr ) {
    1100           if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     1100          if ( unlikely( addr == 0p ) ) return 0;                       // null allocation has zero size
    11011101                HeapManager.Storage.Header * header = headerAddr( addr );
    11021102                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     
    11081108        // Set allocation size and return previous size.
    11091109        size_t $malloc_size_set( void * addr, size_t size ) {
    1110           if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     1110          if ( unlikely( addr == 0p ) ) return 0;                       // null allocation has 0 size
    11111111                HeapManager.Storage.Header * header = headerAddr( addr );
    11121112                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     
    12271227                if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    12281228                        header->kind.real.blockSize &= -2;                      // turn off 0 fill
     1229                        if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    12291230                        return oaddr;
    12301231                } // if
  • libcfa/src/heap.hfa

    rf0c3120 r04b73b6  
    1010// Created On       : Tue May 26 11:23:55 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  1 21:19:00 2020
    13 // Update Count     : 10
     12// Last Modified On : Mon Jul 20 18:52:31 2020
     13// Update Count     : 11
    1414//
    1515
     
    3535        void * resize( void * oaddr, size_t size );
    3636        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 );
    3838        size_t malloc_alignment( void * addr );
    3939        bool malloc_zero_fill( void * addr );
  • libcfa/src/iostream.cfa

    rf0c3120 r04b73b6  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 16 07:43:31 2020
    13 // Update Count     : 1102
     12// Last Modified On : Mon Jul 20 15:00:37 2020
     13// Update Count     : 1124
    1414//
    1515
     
    167167        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    168168
    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
    170171                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)
    171175                        base10_128( os, val / P10_UINT64 );                     // recursive
    172176                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     
    176180        } // base10_128
    177181
    178         static void base10_128( ostype & os, int128 val ) {
     182        static inline void base10_128( ostype & os, int128 val ) {
    179183                if ( val < 0 ) {
    180184                        fmt( os, "-" );                                                         // leading negative sign
  • libcfa/src/stdlib.cfa

    rf0c3120 r04b73b6  
    99// Author           : Peter A. Buhr
    1010// Created On       : Thu Jan 28 17:10:29 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jun  2 16:46:00 2020
    13 // Update Count     : 500
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Jul 19 15:05:28 2020
     13// Update Count     : 501
    1414//
    1515
     
    2525
    2626//---------------------------------------
    27 
    28 forall( dtype T | sized(T) ) {
    29         T * alloc_set( T ptr[], size_t dim, char fill ) {       // realloc array with fill
    30                 size_t olen = malloc_usable_size( ptr );                // current allocation
    31                 void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
    32                 size_t nlen = malloc_usable_size( nptr );               // new allocation
    33                 if ( nlen > olen ) {                                                    // larger ?
    34                         memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
    35                 } // if
    36                 return (T *)nptr;
    37         } // alloc_set
    38 
    39         T * alloc_set( T ptr[], size_t dim, T fill ) {          // realloc array with fill
    40                 size_t olen = malloc_usable_size( ptr );                // current allocation
    41                 void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
    42                 size_t nlen = malloc_usable_size( nptr );               // new allocation
    43                 if ( nlen > olen ) {                                                    // larger ?
    44                         for ( i; malloc_size( ptr ) / sizeof(T) ~ dim ) {
    45                                 memcpy( &ptr[i], &fill, sizeof(T) );    // initialize with fill value
    46                         } // for
    47                 } // if
    48                 return (T *)nptr;
    49         } // alloc_align_set
    50 
    51         T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill
    52                 size_t olen = malloc_usable_size( ptr );                // current allocation
    53                 void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
    54                 // char * nptr = alloc_align( ptr, align );
    55                 size_t nlen = malloc_usable_size( nptr );               // new allocation
    56                 if ( nlen > olen ) {                                                    // larger ?
    57                         memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
    58                 } // if
    59                 return (T *)nptr;
    60         } // alloc_align_set
    61 
    62         T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ) { // aligned realloc with fill
    63                 size_t olen = malloc_usable_size( ptr );                // current allocation
    64                 void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
    65                 // char * nptr = alloc_align( ptr, align );
    66                 size_t nlen = malloc_usable_size( nptr );               // new allocation
    67                 if ( nlen > olen ) {                                                    // larger ?
    68                         for ( i; dim ) { memcpy( &ptr[i], &fill, sizeof(T) ); } // initialize with fill value
    69                 } // if
    70                 return (T *)nptr;
    71         } // alloc_align_set
    72 } // distribution
    7327
    7428// allocation/deallocation and constructor/destructor, non-array types
  • libcfa/src/stdlib.hfa

    rf0c3120 r04b73b6  
    99// Author           : Peter A. Buhr
    1010// Created On       : Thu Jan 28 17:12:35 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jun  2 16:47:00 2020
    13 // Update Count     : 451
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Jul 21 07:58:05 2020
     13// Update Count     : 475
    1414//
    1515
     
    3939//---------------------------------------
    4040
     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
    4156static inline forall( dtype T | sized(T) ) {
    4257        // Cforall safe equivalents, i.e., implicit size specification
    4358
    4459        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 );
    4761        } // malloc
    4862
    4963        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 );
    5265        } // aalloc
    5366
    5467        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 );
    5769        } // calloc
    5870
    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
    6174        } // resize
    6275
    6376        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
     77                $RE_SPECIALS( ptr, size, malloc, memalign );
    6478                return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    6579        } // realloc
     
    118132
    119133        T * alloc( T ptr[], size_t dim, bool copy = true ) {
    120                 if ( copy ) {                                                                   // realloc
    121                         return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     134                if ( copy ) {
     135                        return realloc( ptr, dim * sizeof(T) );         // CFA realloc
    122136                } else {
    123                         return resize( ptr, dim * sizeof(T) );          // resize
     137                        return resize( ptr, dim * sizeof(T) );          // CFA resize
    124138                } // if
    125139        } // alloc
     
    146160                return (T *)memcpy( (T *)alloc( dim ), fill, dim * sizeof(T) ); // initialize with fill value
    147161        } // 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
    153185} // distribution
    154186
     
    196228                return (T *)memcpy( (T *)alloc_align( align, dim ), fill, dim * sizeof(T) );
    197229        } // 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
    205253} // distribution
    206254
Note: See TracChangeset for help on using the changeset viewer.