Changeset 6b4a1bf


Ignore:
Timestamp:
Mar 6, 2020, 2:22:49 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
c4fd4ef, c88f0cf
Parents:
9c6f459 (diff), ca7949b (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

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r9c6f459 r6b4a1bf  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Thu Mar  5 12:09:42 2020
    14 %% Update Count     : 3885
     13%% Last Modified On : Fri Mar  6 13:34:52 2020
     14%% Update Count     : 3924
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    66216621An array may be filled, resized, or aligned.
    66226622\end{description}
    6623 \VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities:
     6623\VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities.
    66246624\begin{table}
    66256625\centering
     6626\begin{minipage}{0.75\textwidth}
    66266627\begin{tabular}{@{}r|l|l|l|l|l@{}}
    66276628\multicolumn{1}{c}{}&           & \multicolumn{1}{c|}{fill}     & resize        & alignment     & array \\
     
    66316632                & ©realloc©                     & copy                  & yes           & no            & no    \\
    66326633                & ©memalign©            & no                    & no            & yes           & no    \\
    6633                 & ©aligned_alloc©       & no                    & no            & yes           & no    \\
     6634                & ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment, which is universally ignored.}
     6635                                                        & no                    & no            & yes           & no    \\
    66346636                & ©posix_memalign©      & no                    & no            & yes           & no    \\
     6637                & ©valloc©                      & no                    & no            & yes (page size)& no   \\
     6638                & ©pvalloc©\footnote{Same as ©valloc© but rounds size to multiple of page size.}
     6639                                                        & no                    & no            & yes (page size)& no   \\
    66356640\hline
    66366641\CFA    & ©cmemalign©           & yes (0 only)  & no            & yes           & yes   \\
    66376642                & ©realloc©                     & copy                  & yes           & yes           & no    \\
    6638                 & ©alloc©                       & no                    & no            & no            & no    \\
    6639                 & ©alloc©                       & copy                  & no/yes        & no            & yes   \\
    6640                 & ©alloc©                       & no/copy/yes   & no/yes        & no            & yes   \\
    6641                 & ©alloc_set©           & no/yes                & no            & yes           & yes   \\
    6642                 & ©alloc_align©         & no/yes                & no            & yes           & yes   \\
    6643                 & ©alloc_align_set©     & no/yes                & no            & yes           & yes   \\
     6643                & ©alloc©                       & no                    & yes           & no            & yes   \\
     6644                & ©alloc_set©           & yes                   & yes           & no            & yes   \\
     6645                & ©alloc_align©         & no                    & yes           & yes           & yes   \\
     6646                & ©alloc_align_set©     & yes                   & yes           & yes           & yes   \\
    66446647\end{tabular}
     6648\end{minipage}
    66456649\caption{Allocation Routines versus Storage-Management Capabilities}
    66466650\label{t:AllocationVersusCapabilities}
    66476651\end{table}
     6652
     6653\CFA memory management extends the type safety of all allocations by using the type of the left-hand-side type to determine the allocation size and return a matching type for the new storage.
     6654Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in
     6655\begin{cfa}
     6656int * ip = (int *)malloc( sizeof(int) );                §\C{// C}§
     6657int * ip = malloc();                                                    §\C{// \CFA type-safe version of C malloc}§
     6658int * ip = alloc();                                                             §\C{// \CFA type-safe uniform alloc}§
     6659\end{cfa}
     6660the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©.
     6661
     6662\CFA memory management extends allocation safety by implicitly honouring all alignment requirements, \eg in
     6663\begin{cfa}
     6664struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment
     6665S * sp = malloc();                                                              §\C{// honour type alignment}§
     6666\end{cfa}
     6667the storage allocation is implicitly aligned to 128 rather than the default 16.
     6668The alignment check is performed at compile time so there is no runtime cost.
    66486669
    66496670\CFA memory management extends the resize capability with the notion of \newterm{sticky properties}.
     
    66526673Without sticky properties it is dangerous to use ©realloc©, resulting in an idiom of manually performing the reallocation to maintain correctness.
    66536674
     6675\CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in
     6676\begin{cfa}
     6677struct S { int i; };                                                    §\C{// cache-line aglinment}§
     6678void ?{}( S & s, int i ) { s.i = i; }
     6679// assume ?|? operator for printing an S
     6680
     6681S & sp = *®new®( 3 );                                                   §\C{// call constructor after allocation}§
     6682sout | sp.i;
     6683®delete®( &sp );
     6684
     6685S * spa = ®anew®( 10, 5 );                                              §\C{// allocate array and initialize each array element}§
     6686for ( i; 10 ) sout | spa[i] | nonl;
     6687sout | nl;
     6688®adelete®( 10, spa );
     6689\end{cfa}
     6690Allocation routines ©new©/©anew© allocate a variable/array and initialize storage using the allocated type's constructor.
     6691Note, the matching deallocation routines ©delete©/©adelete©.
    66546692
    66556693\leavevmode
  • libcfa/src/heap.cfa

    r9c6f459 r6b4a1bf  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 10:04:51 2020
    13 // Update Count     : 648
     12// Last Modified On : Fri Mar  6 10:14:52 2020
     13// Update Count     : 650
    1414//
    1515
     
    819819
    820820extern "C" {
    821         // The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not
    822         // initialized. If size is 0, then malloc() returns either 0p, or a unique pointer value that can later be
    823         // successfully passed to free().
     821        // Allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0,
     822        // then malloc() returns either 0p, or a unique pointer value that can later be successfully passed to free().
    824823        void * malloc( size_t size ) {
    825824                #ifdef __STATISTICS__
     
    831830        } // malloc
    832831
    833         // The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to
    834         // the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either 0p, or a
    835         // unique pointer value that can later be successfully passed to free().
     832        // Allocate memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated
     833        // memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either 0p, or a unique pointer
     834        // value that can later be successfully passed to free().
    836835        void * calloc( size_t noOfElems, size_t elemSize ) {
    837836                #ifdef __STATISTICS__
     
    843842        } // calloc
    844843
    845         // The realloc() function changes the size of the memory block pointed to by ptr to size bytes. The contents will be
    846         // unchanged in the range from the start of the region up to the minimum of the old and new sizes. If the new size
    847         // is larger than the old size, the added memory will not be initialized.  If ptr is 0p, then the call is
    848         // equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not 0p, then the call
    849         // is equivalent to free(ptr). Unless ptr is 0p, it must have been returned by an earlier call to malloc(),
    850         // calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.
     844        // Change the size of the memory block pointed to by ptr to size bytes. The contents shall be unchanged in the range
     845        // from the start of the region up to the minimum of the old and new sizes. If the new size is larger than the old
     846        // size, the added memory shall not be initialized.  If ptr is 0p, then the call is equivalent to malloc(size), for
     847        // all values of size; if size is equal to zero, and ptr is not 0p, then the call is equivalent to free(ptr). Unless
     848        // ptr is 0p, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed
     849        // to was moved, a free(ptr) is done.
    851850        void * realloc( void * oaddr, size_t size ) {
    852851                #ifdef __STATISTICS__
     
    903902        } // realloc
    904903
    905         // The obsolete function memalign() allocates size bytes and returns a pointer to the allocated memory. The memory
    906         // address will be a multiple of alignment, which must be a power of two.
     904        // Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of
     905        // alignment, which must be a power of two. (obsolete)
    907906        void * memalign( size_t alignment, size_t size ) {
    908907                #ifdef __STATISTICS__
     
    915914
    916915
    917         // The cmemalign() function is the same as calloc() with memory alignment.
     916        // Same as calloc() with memory alignment.
    918917        void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
    919918                #ifdef __STATISTICS__
     
    925924        } // cmemalign
    926925
    927         // The function aligned_alloc() is the same as memalign(), except for the added restriction that size should be a
    928         // multiple of alignment.
     926        // Same as memalign(), but ISO/IEC 2011 C11 Section 7.22.2 states: the value of size shall be an integral multiple
     927    // of alignment. This requirement is universally ignored.
    929928        void * aligned_alloc( size_t alignment, size_t size ) {
    930929                return memalign( alignment, size );
     
    932931
    933932
    934         // The function posix_memalign() allocates size bytes and places the address of the allocated memory in *memptr. The
    935         // address of the allocated memory will be a multiple of alignment, which must be a power of two and a multiple of
    936         // sizeof(void *). If size is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later
    937         // be successfully passed to free(3).
     933        // Allocates size bytes and places the address of the allocated memory in *memptr. The address of the allocated
     934        // memory shall be a multiple of alignment, which must be a power of two and a multiple of sizeof(void *). If size
     935        // is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later be successfully passed to
     936        // free(3).
    938937        int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
    939938          if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) return EINVAL; // check alignment
     
    943942        } // posix_memalign
    944943
    945         // The obsolete function valloc() allocates size bytes and returns a pointer to the allocated memory. The memory
    946         // address will be a multiple of the page size.  It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
     944        // Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of the
     945        // page size.  It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
    947946        void * valloc( size_t size ) {
    948947                return memalign( pageSize, size );
     
    950949
    951950
    952         // The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to
    953         // malloc(), calloc() or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behavior
    954         // occurs. If ptr is 0p, no operation is performed.
     951        // Same as valloc but rounds size to multiple of page size.
     952        void * pvalloc( size_t size ) {
     953                return memalign( pageSize, libCeiling( size, pageSize ) );
     954        } // pvalloc
     955
     956
     957        // Frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc()
     958        // or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is
     959        // 0p, no operation is performed.
    955960        void free( void * addr ) {
    956961                #ifdef __STATISTICS__
     
    973978
    974979
    975         // The malloc_alignment() function returns the alignment of the allocation.
     980        // Returns the alignment of the allocation.
    976981        size_t malloc_alignment( void * addr ) {
    977982          if ( unlikely( addr == 0p ) ) return libAlign();      // minimum alignment
     
    985990
    986991
    987         // The malloc_zero_fill() function returns true if the allocation is zero filled, i.e., initially allocated by calloc().
     992        // Returns true if the allocation is zero filled, i.e., initially allocated by calloc().
    988993        bool malloc_zero_fill( void * addr ) {
    989994          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
     
    9961001
    9971002
    998         // The malloc_usable_size() function returns the number of usable bytes in the block pointed to by ptr, a pointer to
    999         // a block of memory allocated by malloc(3) or a related function.
     1003        // Returns the number of usable bytes in the block pointed to by ptr, a pointer to a block of memory allocated by
     1004        // malloc or a related function.
    10001005        size_t malloc_usable_size( void * addr ) {
    10011006          if ( unlikely( addr == 0p ) ) return 0;                       // null allocation has 0 size
     
    10091014
    10101015
    1011         // The malloc_stats() function prints (on default standard error) statistics about memory allocated by malloc(3) and
    1012         // related functions.
     1016        // Prints (on default standard error) statistics about memory allocated by malloc and related functions.
    10131017        void malloc_stats( void ) {
    10141018                #ifdef __STATISTICS__
     
    10181022        } // malloc_stats
    10191023
    1020         // The malloc_stats_fd() function changes the file descripter where malloc_stats() writes the statistics.
     1024        // Changes the file descripter where malloc_stats() writes statistics.
    10211025        int malloc_stats_fd( int fd __attribute__(( unused )) ) {
    10221026                #ifdef __STATISTICS__
     
    10301034
    10311035
    1032         // The mallopt() function adjusts parameters that control the behavior of the memory-allocation functions (see
    1033         // malloc(3)). The param argument specifies the parameter to be modified, and value specifies the new value for that
    1034         // parameter.
     1036        // Adjusts parameters that control the behavior of the memory-allocation functions (see malloc). The param argument
     1037        // specifies the parameter to be modified, and value specifies the new value for that parameter.
    10351038        int mallopt( int option, int value ) {
    10361039                choose( option ) {
     
    10431046        } // mallopt
    10441047
    1045         // The malloc_trim() function attempts to release free memory at the top of the heap (by calling sbrk(2) with a
    1046         // suitable argument).
     1048        // Attempt to release free memory at the top of the heap (by calling sbrk with a suitable argument).
    10471049        int malloc_trim( size_t ) {
    10481050                return 0;                                                                               // => impossible to release memory
     
    10501052
    10511053
    1052         // The malloc_info() function exports an XML string that describes the current state of the memory-allocation
    1053         // implementation in the caller.  The string is printed on the file stream stream.  The exported string includes
    1054         // information about all arenas (see malloc(3)).
     1054        // Exports an XML string that describes the current state of the memory-allocation implementation in the caller.
     1055        // The string is printed on the file stream stream.  The exported string includes information about all arenas (see
     1056        // malloc).
    10551057        int malloc_info( int options, FILE * stream ) {
    10561058                if ( options != 0 ) { errno = EINVAL; return -1; }
     
    10591061
    10601062
    1061         // The malloc_get_state() function records the current state of all malloc(3) internal bookkeeping variables (but
    1062         // not the actual contents of the heap or the state of malloc_hook(3) functions pointers).  The state is recorded in
    1063         // a system-dependent opaque data structure dynamically allocated via malloc(3), and a pointer to that data
    1064         // structure is returned as the function result.  (It is the caller's responsibility to free(3) this memory.)
     1063        // Records the current state of all malloc internal bookkeeping variables (but not the actual contents of the heap
     1064        // or the state of malloc_hook functions pointers).  The state is recorded in a system-dependent opaque data
     1065        // structure dynamically allocated via malloc, and a pointer to that data structure is returned as the function
     1066        // result.  (The caller must free this memory.)
    10651067        void * malloc_get_state( void ) {
    10661068                return 0p;                                                                              // unsupported
     
    10681070
    10691071
    1070         // The malloc_set_state() function restores the state of all malloc(3) internal bookkeeping variables to the values
    1071         // recorded in the opaque data structure pointed to by state.
     1072        // Restores the state of all malloc internal bookkeeping variables to the values recorded in the opaque data
     1073        // structure pointed to by state.
    10721074        int malloc_set_state( void * ptr ) {
    10731075                return 0;                                                                               // unsupported
  • libcfa/src/stdlib.hfa

    r9c6f459 r6b4a1bf  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  4 08:27:01 2020
    13 // Update Count     : 401
     12// Last Modified On : Thu Mar  5 11:29:06 2020
     13// Update Count     : 407
    1414//
    1515
     
    2121#include <stdlib.h>                                                                             // *alloc, strto*, ato*
    2222
     23// Reduce includes by explicitly defining these routines.
    2324extern "C" {
    2425        void * memalign( size_t align, size_t size );           // malloc.h
     26    void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    2527        void * memset( void * dest, int fill, size_t size ); // string.h
    2628        void * memcpy( void * dest, const void * src, size_t size ); // string.h
    27     void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
    2829} // extern "C"
    2930
     
    4041
    4142static inline forall( dtype T | sized(T) ) {
    42         // C dynamic allocation
     43        // Cforall safe equivalents, i.e., implicit size specification
    4344
    4445        T * malloc( void ) {
     
    7273        } // posix_memalign
    7374
    74         // Cforall dynamic allocation
     75        // Cforall safe general allocation, fill, resize, array
    7576
    7677        T * alloc( void ) {
     
    159160
    160161static inline forall( dtype T | sized(T) ) {
    161         // data, non-array types
     162        // Cforall safe initialization/copy, i.e., implicit size specification, non-array types
    162163        T * memset( T * dest, char fill ) {
    163164                return (T *)memset( dest, fill, sizeof(T) );
     
    170171
    171172static inline forall( dtype T | sized(T) ) {
    172         // data, array types
     173        // Cforall safe initialization/copy, i.e., implicit size specification, array types
    173174        T * amemset( T dest[], char fill, size_t dim ) {
    174175                return (T *)(void *)memset( dest, fill, dim * sizeof(T) ); // C memset
     
    180181} // distribution
    181182
    182 // allocation/deallocation and constructor/destructor, non-array types
     183// Cforall allocation/deallocation and constructor/destructor, non-array types
    183184forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
    184185forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );
    185186forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
    186187
    187 // allocation/deallocation and constructor/destructor, array types
     188// Cforall allocation/deallocation and constructor/destructor, array types
    188189forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );
    189190forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );
Note: See TracChangeset for help on using the changeset viewer.