Ignore:
Timestamp:
Aug 12, 2014, 6:39:26 PM (10 years ago)
Author:
alain
Message:

Cosmetic

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_common/utils.c

    r378 r399  
    2222extern static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
    2323
    24 ///////////////////////////////////////////////////////////////////////////////////
    25 // This function implements a pseudo-random delay.
    26 // The val argument define approximately an exponentially increasing mean delay,
    27 // and should not be larger than 32.
    28 ///////////////////////////////////////////////////////////////////////////////////
    29 void _random_wait( unsigned int val )
    30 {
    31     unsigned int mask  = (1<<(val&0x1F))-1;
    32     unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
    33     asm volatile( "move  $3,   %0                 \n"
    34                   "loop_nic_completed:            \n"
    35                   "addi  $3,   $3, -1             \n"
    36                   "bnez  $3,   loop_nic_completed \n"
    37                   "nop                            \n"
    38                   :
    39                   : "r" (delay)
    40                   : "$3" );
    41 }
    42 ///////////////////////////////////////////////////////////////////////////////////
    43 // Copy a source memory buffer content to a dest memory buffer (size bytes)
    44 // Code taken from MutekH.
    45 ///////////////////////////////////////////////////////////////////////////////////
    46 void* memcpy( void*        dest,     // dest buffer vbase
    47                      const void*  source,   // source buffer vbase
    48                      unsigned int size )    // bytes
    49 {
    50     unsigned int* idst = (unsigned int*)dest;
    51     unsigned int* isrc = (unsigned int*)source;
    52 
    53     // word-by-word copy
    54     if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3))
    55     {
    56         while (size > 3)
    57         {
    58             *idst++ = *isrc++;
    59             size -= 4;
    60         }
    61     }
    62 
    63     unsigned char* cdst = (unsigned char*)dest;
    64     unsigned char* csrc = (unsigned char*)source;
    65 
    66     /* byte-by-byte copy */
    67     while (size--)
    68     {
    69         *cdst++ = *csrc++;
    70     }
    71     return dest;
    72 }
    73 //////////////////////////////////////////////////////////////////////////////////
    74 // Fill a byte string with a byte value.
    75 //////////////////////////////////////////////////////////////////////////////////
    76 void * memset( void*        dest,
    77                       int          value,
    78                       unsigned int count )
    79 {
    80     // word-by-word copy
    81     unsigned int* idst = dest;
    82     unsigned int  data = (((unsigned char)value)      ) |
    83                          (((unsigned char)value) <<  8) |
    84                          (((unsigned char)value) << 16) |
    85                          (((unsigned char)value) << 24) ;
    86 
    87     if ( ! ((unsigned int)idst & 3) )
    88     {
    89         while ( count > 3 )
    90         {
    91             *idst++ = data;
    92             count -= 4;
    93         }
    94     }
    95    
    96     // byte-by-byte copy
    97     unsigned char* cdst = dest;
    98     while (count--)
    99     {
    100         *cdst++ = (unsigned char)value;
    101     }
    102     return dest;
    103 }
    104 
    105 //////////////////////////////////////////////////////////////////////////////////
    106 // This function implements an interactive break for debug.
    107 // Execution continue when typing any character on TTY0.
    108 // The "str" argument is supposed to indicate the break location.
    109 //////////////////////////////////////////////////////////////////////////////////
    110 void _break( char* string )
    111 {
    112     char byte;
    113 
    114     _printf("\n[GIET DEBUG] break from %s / continue ?\n", string );
    115     _getc( &byte );
    116 }
    117 
    118 //////////////////////////////////////////////////////////////////////////////////
    119 // Processor suicide: infinite loop 
    120 //////////////////////////////////////////////////////////////////////////////////
    121 __attribute__((noreturn))
    122 void _exit()
    123 {
    124     unsigned int procid     = _get_procid();
    125     unsigned int lpid       = procid % NB_PROCS_MAX;
    126     unsigned int cluster_xy = procid / NB_PROCS_MAX;
    127     unsigned int x          = cluster_xy >> Y_WIDTH;
    128     unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
    129 
    130 
    131     _printf("\n[GIET PANIC] processor[%d,%d,%d] suicide...\n", x, y, lpid );
    132 
    133     while (1) { asm volatile ("nop"); }
    134 }
    135 ///////////////////////////////////////////////////////////////////////////////////
    136 //         CP0 and CP2 registers access functions
     24
     25///////////////////////////////////////////////////////////////////////////////////
     26//         CP0 registers access functions
    13727///////////////////////////////////////////////////////////////////////////////////
    13828
     
    14939}
    15040///////////////////////////////////////////////////////////////////////////////////
    151 // Returns PTPR register content.
    152 ///////////////////////////////////////////////////////////////////////////////////
    153 unsigned int _get_mmu_ptpr()
    154 {
    155     unsigned int ret;
    156     asm volatile( "mfc2      %0,     $0      \n"
    157                   : "=r"(ret) );
    158     return ret;
    159 }
    160 ///////////////////////////////////////////////////////////////////////////////////
    161 // Returns MODE register content.
    162 ///////////////////////////////////////////////////////////////////////////////////
    163 unsigned int _get_mmu_mode()
    164 {
    165     unsigned int ret;
    166     asm volatile( "mfc2      %0,     $1      \n"
    167                   : "=r"(ret) );
    168     return ret;
    169 }
    170 ///////////////////////////////////////////////////////////////////////////////////
    17141// Returns EPC register content.
    17242///////////////////////////////////////////////////////////////////////////////////
     
    238108    return ret;
    239109}
    240 //////////////////////////////////////////////////////////////////////////////
    241 // Returns index of the currently running task from the processor scheduler.
    242 //////////////////////////////////////////////////////////////////////////////
    243 unsigned int _get_current_task_id()
    244 {
    245     static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
    246     return (unsigned int) (psched->current);
    247 }
    248 
    249110//////////////////////////////////////////////////////////////////////////////
    250111// Save SR value into save_sr_ptr variable and disable IRQs.
     
    262123    *save_sr_ptr = sr;
    263124}
    264 //////////////////////////////////////////////////////////////////////////////
    265 // Enables IRQs
    266 //////////////////////////////////////////////////////////////////////////////
    267 void _it_enable()
    268 {
    269     asm volatile( "li      $3,        0x00000001    \n"
    270                   "mfc0    $4,        $12           \n"
    271                   "or      $3,        $3, $4        \n"
    272                   "mtc0    $3,        $12           \n" 
    273                   ::: "$3", "$4", "memory" );
    274 }
    275125
    276126//////////////////////////////////////////////////////////////////////////////
     
    287137
    288138//////////////////////////////////////////////////////////////////////////////
     139// This function set a new value in CP0 SCHED register.
     140// (virtual base address of the processor scheduler).
     141//////////////////////////////////////////////////////////////////////////////
     142void _set_sched(unsigned int val)
     143{
     144    asm volatile ( "mtc0     %0,     $4, 2          \n"
     145                   :
     146                   :"r" (val) );
     147}
     148
     149///////////////////////////////////////////////////////////////////////////////////
     150//         CP2 registers access functions
     151///////////////////////////////////////////////////////////////////////////////////
     152
     153///////////////////////////////////////////////////////////////////////////////////
     154// Returns PTPR register content.
     155///////////////////////////////////////////////////////////////////////////////////
     156unsigned int _get_mmu_ptpr()
     157{
     158    unsigned int ret;
     159    asm volatile( "mfc2      %0,     $0      \n"
     160                  : "=r"(ret) );
     161    return ret;
     162}
     163///////////////////////////////////////////////////////////////////////////////////
     164// Returns MODE register content.
     165///////////////////////////////////////////////////////////////////////////////////
     166unsigned int _get_mmu_mode()
     167{
     168    unsigned int ret;
     169    asm volatile( "mfc2      %0,     $1      \n"
     170                  : "=r"(ret) );
     171    return ret;
     172}
     173//////////////////////////////////////////////////////////////////////////////
    289174// This function set a new value for the MMU PTPR register.
    290175//////////////////////////////////////////////////////////////////////////////
     
    305190                   :"r" (val)
    306191                   :"memory" );
    307 }
    308 //////////////////////////////////////////////////////////////////////////////
    309 // This function set a new value in CP0 SCHED register.
    310 // (virtual base address of the processor scheduler).
    311 //////////////////////////////////////////////////////////////////////////////
    312 void _set_sched(unsigned int val)
    313 {
    314     asm volatile ( "mtc0     %0,     $4, 2          \n"
    315                    :
    316                    :"r" (val) );
    317192}
    318193
     
    355230////////////////////////////////////////////////////////////////////////////
    356231void _physical_write( unsigned long long paddr,
    357                              unsigned int       value )
     232                               unsigned int       value )
    358233{
    359234    unsigned int lsb = (unsigned int)paddr;
     
    419294////////////////////////////////////////////////////////////////////////////
    420295void _physical_write_ull( unsigned long long paddr,
    421                                  unsigned long long value )
     296                          unsigned long long value )
    422297{
    423298    unsigned int addr_lsb = (unsigned int)paddr;
     
    450325// This function makes a memcpy from a source buffer to a destination buffer
    451326// using physical addresses, after a temporary DTLB de-activation.
    452 // source and destination buffers must be aligned, and size must be
     327// source and destination buffers must be word aligned, and size must be
    453328// multiple of 4 bytes.
    454329///////////////////////////////////////////////////////////////////////////////////
    455330void _physical_memcpy( unsigned long long dst_paddr,  // dest buffer paddr
    456                               unsigned long long src_paddr,  // source buffer paddr
    457                               unsigned int size )            // bytes
     331                       unsigned long long src_paddr,  // source buffer paddr
     332                       unsigned int size )            // bytes
    458333{
    459334    // check alignment constraints
     
    509384///////////////////////////////////////////////////////////////////////////////////
    510385void _io_extended_write( unsigned int*  vaddr,
    511                                 unsigned int   value )
     386                         unsigned int   value )
    512387{
    513388    unsigned long long paddr;
     
    892767}
    893768
    894 ///////////////////////////////////////////////////////////////////////////////////
    895 // Compare two strings s1 & s2 (no more than n characters)
    896 ///////////////////////////////////////////////////////////////////////////////////
    897 unsigned int _strncmp( const char * s1,
    898                        const char * s2,
    899                        unsigned int n )
    900 {
    901     unsigned int i;
    902     for (i = 0; i < n; i++)
    903     {
    904         if (s1[i] != s2[i])  return 1;
    905         if (s1[i] == 0)      break;
    906     }
    907     return 0;
    908 }
    909 
    910 ///////////////////////////////////////////////////////////////////////////////////
    911 // Copy source string to dest string
    912 ///////////////////////////////////////////////////////////////////////////////////
    913 char* _strcpy( char* dest, char* source )
    914 {
    915     if (!dest || !source) return dest;
    916 
    917     while (*source)
    918         *(dest++) = *(source++);
    919 
    920     return dest;
    921 }
    922 
    923 ///////////////////////////////////////////////////////////////////////////////////
    924 // Invalidate all data cache lines corresponding to a memory
    925 // buffer (identified by an address and a size).
    926 // TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
    927 // register, to be more processor independant.
    928 ///////////////////////////////////////////////////////////////////////////////////
    929 void _dcache_buf_invalidate( void * buffer,
    930                              unsigned int size)
    931 {
    932     unsigned int i;
    933     unsigned int tmp;
    934     unsigned int line_size;
    935 
    936     // compute data cache line size based on config register (bits 12:10)
    937     asm volatile(
    938                  "mfc0 %0, $16, 1"
    939                  : "=r" (tmp) );
    940     tmp = ((tmp >> 10) & 0x7);
    941     line_size = 2 << tmp;
    942 
    943     // iterate on cache lines
    944     for (i = 0; i < size; i += line_size)
    945     {
    946         asm volatile(
    947                 " cache %0, %1"
    948                 : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
    949     }
    950 }
    951 
     769
     770//////////////////////////////////////////////////////////////////////////////
     771//           Scheduler and tasks context access functions
     772//////////////////////////////////////////////////////////////////////////////
     773
     774//////////////////////////////////////////////////////////////////////////////
     775// Returns index of the currently running task from the processor scheduler.
     776//////////////////////////////////////////////////////////////////////////////
     777unsigned int _get_current_task_id()
     778{
     779    static_scheduler_t * psched = (static_scheduler_t *) _get_sched();
     780    return (unsigned int) (psched->current);
     781}
    952782////////////////////////////////////////////////////////////////////////////////////
    953783// This function returns the content of a context slot
    954 // for any task identified by the ltid argument (local task index),
     784// for a task identified by the ltid argument (local task index),
    955785// and the gpid argument (global processor index)
    956786////////////////////////////////////////////////////////////////////////////////////
     
    962792    return psched->context[ltid][slot];
    963793}
    964 
    965794////////////////////////////////////////////////////////////////////////////////////
    966795// This function updates the content of a context slot
     
    976805    psched->context[ltid][slot] = value;
    977806}
    978 
    979807////////////////////////////////////////////////////////////////////////////////////
    980808// This function returns the content of a context slot
     
    987815    return psched->context[task_id][slot];
    988816}
    989 
    990817////////////////////////////////////////////////////////////////////////////////////
    991818// This function updates the content of a context slot for the running task.
     
    998825    psched->context[task_id][slot] = value;
    999826}
    1000 
    1001 ///////////////////////////////////////////////////////////////////////////////////
    1002 // This function returns the information associated to a heap : vaddr and length.
    1003 // - If (x < X_SIZE) and (y < Y_SIZE), it return the heap associated to any task
    1004 // running in cluster(x,y).
    1005 // - Else, it return the heap associated to the calling task.
    1006 // It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
    1007 // vspace index (CTX_VSID_ID), that are defined in the calling task context
    1008 // to find the vobj_id containing the heap.
    1009 // Return 0 if success. Return non zero if not found.
    1010 ///////////////////////////////////////////////////////////////////////////////////
    1011 unsigned int _heap_info( unsigned int* vaddr,
    1012                          unsigned int* length,
    1013                          unsigned int  x,
    1014                          unsigned int  y )
    1015 {
    1016     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
    1017     mapping_task_t *   tasks   = _get_task_base(header);
    1018     mapping_vobj_t *   vobjs   = _get_vobj_base(header);
    1019     mapping_vspace_t * vspaces = _get_vspace_base(header);
    1020 
    1021     unsigned int task_id;
    1022     unsigned int vspace_id;
    1023     unsigned int vobj_id = 0xFFFFFFFF;
    1024 
    1025     // searching the heap vobj_id
    1026     if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
    1027     {
    1028         // get vspace global index
    1029         vspace_id = _get_context_slot(CTX_VSID_ID);
    1030 
    1031         // scan all tasks in vspace
    1032         unsigned int min = vspaces[vspace_id].task_offset ;
    1033         unsigned int max = min + vspaces[vspace_id].tasks ;
    1034         for ( task_id = min ; task_id < max ; task_id++ )
    1035         {
    1036             if ( tasks[task_id].clusterid == (x * Y_SIZE + y) )
    1037             {
    1038                 vobj_id = tasks[task_id].heap_vobj_id;
    1039                 if ( vobj_id != 0xFFFFFFFF ) break;
    1040             }
    1041         }
    1042     }
    1043     else                                // searching in the calling task
    1044     {
    1045         task_id = _get_context_slot(CTX_GTID_ID);
    1046         vobj_id = tasks[task_id].heap_vobj_id;
    1047     }
    1048 
    1049     // analysing the vobj_id
    1050     if ( vobj_id != 0xFFFFFFFF )
    1051     {
    1052         *vaddr  = vobjs[vobj_id].vaddr;
    1053         *length = vobjs[vobj_id].length;
    1054         return 0;
    1055     }
    1056     else
    1057     {
    1058         *vaddr = 0;
    1059         *length = 0;
    1060         return 1;
    1061     }
    1062 }  // end _heap_info()
    1063827
    1064828/////////////////////////////////////////////////////////////////////////////
     
    1186950}
    1187951
     952///////////////////////////////////////////////////////////////////////////////////
     953// Miscelaneous functions
     954///////////////////////////////////////////////////////////////////////////////////
     955
     956///////////////////////////////////////////////////////////////////////////////////
     957// This function implements a pseudo-random delay.
     958// The val argument define approximately an exponentially increasing mean delay,
     959// and should not be larger than 32.
     960///////////////////////////////////////////////////////////////////////////////////
     961void _random_wait( unsigned int val )
     962{
     963    unsigned int mask  = (1<<(val&0x1F))-1;
     964    unsigned int delay = (_get_proctime() ^ (_get_procid()<<4)) & mask;
     965    asm volatile( "move  $3,   %0                 \n"
     966                  "loop_nic_completed:            \n"
     967                  "addi  $3,   $3, -1             \n"
     968                  "bnez  $3,   loop_nic_completed \n"
     969                  "nop                            \n"
     970                  :
     971                  : "r" (delay)
     972                  : "$3" );
     973}
     974//////////////////////////////////////////////////////////////////////////////////
     975// This function implements an interactive break for debug.
     976// Execution continue when typing any character on TTY0.
     977// The "str" argument is supposed to indicate the break location.
     978//////////////////////////////////////////////////////////////////////////////////
     979void _break( char* string )
     980{
     981    char byte;
     982
     983    _printf("\n[GIET DEBUG] break from %s / continue ?\n", string );
     984    _getc( &byte );
     985}
     986
     987//////////////////////////////////////////////////////////////////////////////////
     988// Processor suicide: infinite loop 
     989//////////////////////////////////////////////////////////////////////////////////
     990__attribute__((noreturn))
     991void _exit()
     992{
     993    unsigned int procid     = _get_procid();
     994    unsigned int lpid       = procid % NB_PROCS_MAX;
     995    unsigned int cluster_xy = procid / NB_PROCS_MAX;
     996    unsigned int x          = cluster_xy >> Y_WIDTH;
     997    unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1);
     998
     999
     1000    _printf("\n[GIET PANIC] processor[%d,%d,%d] suicide...\n", x, y, lpid );
     1001
     1002    while (1) { asm volatile ("nop"); }
     1003}
     1004///////////////////////////////////////////////////////////////////////////////////
     1005// Compare two strings s1 & s2 (no more than n characters)
     1006///////////////////////////////////////////////////////////////////////////////////
     1007unsigned int _strncmp( const char * s1,
     1008                       const char * s2,
     1009                       unsigned int n )
     1010{
     1011    unsigned int i;
     1012    for (i = 0; i < n; i++)
     1013    {
     1014        if (s1[i] != s2[i])  return 1;
     1015        if (s1[i] == 0)      break;
     1016    }
     1017    return 0;
     1018}
     1019
     1020///////////////////////////////////////////////////////////////////////////////////
     1021// Copy source string to dest string
     1022///////////////////////////////////////////////////////////////////////////////////
     1023char* _strcpy( char* dest, char* source )
     1024{
     1025    if (!dest || !source) return dest;
     1026
     1027    while (*source)
     1028        *(dest++) = *(source++);
     1029
     1030    return dest;
     1031}
     1032
     1033///////////////////////////////////////////////////////////////////////////////////
     1034// Invalidate all data cache lines corresponding to a memory
     1035// buffer (identified by an address and a size).
     1036// TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
     1037// register, to be more processor independant.
     1038///////////////////////////////////////////////////////////////////////////////////
     1039void _dcache_buf_invalidate( void * buffer,
     1040                             unsigned int size)
     1041{
     1042    unsigned int i;
     1043    unsigned int tmp;
     1044    unsigned int line_size;
     1045
     1046    // compute data cache line size based on config register (bits 12:10)
     1047    asm volatile(
     1048                 "mfc0 %0, $16, 1"
     1049                 : "=r" (tmp) );
     1050    tmp = ((tmp >> 10) & 0x7);
     1051    line_size = 2 << tmp;
     1052
     1053    // iterate on cache lines
     1054    for (i = 0; i < size; i += line_size)
     1055    {
     1056        asm volatile(
     1057                " cache %0, %1"
     1058                : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
     1059    }
     1060}
     1061///////////////////////////////////////////////////////////////////////////////////
     1062// This function returns the information associated to a heap : vaddr and length.
     1063// - If (x < X_SIZE) and (y < Y_SIZE), it return the heap associated to any task
     1064// running in cluster(x,y).
     1065// - Else, it return the heap associated to the calling task.
     1066// It uses the global task index (CTX_GTID_ID, unique for each giet task) and the
     1067// vspace index (CTX_VSID_ID), that are defined in the calling task context
     1068// to find the vobj_id containing the heap.
     1069// Return 0 if success. Return non zero if not found.
     1070///////////////////////////////////////////////////////////////////////////////////
     1071unsigned int _heap_info( unsigned int* vaddr,
     1072                         unsigned int* length,
     1073                         unsigned int  x,
     1074                         unsigned int  y )
     1075{
     1076    mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE;
     1077    mapping_task_t *   tasks   = _get_task_base(header);
     1078    mapping_vobj_t *   vobjs   = _get_vobj_base(header);
     1079    mapping_vspace_t * vspaces = _get_vspace_base(header);
     1080
     1081    unsigned int task_id;
     1082    unsigned int vspace_id;
     1083    unsigned int vobj_id = 0xFFFFFFFF;
     1084
     1085    // searching the heap vobj_id
     1086    if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y)
     1087    {
     1088        // get vspace global index
     1089        vspace_id = _get_context_slot(CTX_VSID_ID);
     1090
     1091        // scan all tasks in vspace
     1092        unsigned int min = vspaces[vspace_id].task_offset ;
     1093        unsigned int max = min + vspaces[vspace_id].tasks ;
     1094        for ( task_id = min ; task_id < max ; task_id++ )
     1095        {
     1096            if ( tasks[task_id].clusterid == (x * Y_SIZE + y) )
     1097            {
     1098                vobj_id = tasks[task_id].heap_vobj_id;
     1099                if ( vobj_id != 0xFFFFFFFF ) break;
     1100            }
     1101        }
     1102    }
     1103    else                                // searching in the calling task
     1104    {
     1105        task_id = _get_context_slot(CTX_GTID_ID);
     1106        vobj_id = tasks[task_id].heap_vobj_id;
     1107    }
     1108
     1109    // analysing the vobj_id
     1110    if ( vobj_id != 0xFFFFFFFF )
     1111    {
     1112        *vaddr  = vobjs[vobj_id].vaddr;
     1113        *length = vobjs[vobj_id].length;
     1114        return 0;
     1115    }
     1116    else
     1117    {
     1118        *vaddr = 0;
     1119        *length = 0;
     1120        return 1;
     1121    }
     1122}  // end _heap_info()
     1123
     1124
     1125///////////////////////////////////////////////////////////////////////////////////
     1126//   Required by GCC
     1127///////////////////////////////////////////////////////////////////////////////////
     1128
     1129///////////////////////////////////////////////////////////////////////////////////
     1130// Copy a source memory buffer content to a dest memory buffer (size bytes)
     1131// Code taken from MutekH.
     1132///////////////////////////////////////////////////////////////////////////////////
     1133void* memcpy( void*        dest,     // dest buffer vbase
     1134              const void*  source,   // source buffer vbase
     1135              unsigned int size )    // bytes
     1136{
     1137    unsigned int* idst = (unsigned int*)dest;
     1138    unsigned int* isrc = (unsigned int*)source;
     1139
     1140    // word-by-word copy
     1141    if (!((unsigned int) idst & 3) && !((unsigned int) isrc & 3))
     1142    {
     1143        while (size > 3)
     1144        {
     1145            *idst++ = *isrc++;
     1146            size -= 4;
     1147        }
     1148    }
     1149
     1150    unsigned char* cdst = (unsigned char*)dest;
     1151    unsigned char* csrc = (unsigned char*)source;
     1152
     1153    /* byte-by-byte copy */
     1154    while (size--)
     1155    {
     1156        *cdst++ = *csrc++;
     1157    }
     1158    return dest;
     1159}
     1160//////////////////////////////////////////////////////////////////////////////////
     1161// Fill a byte string with a byte value.
     1162//////////////////////////////////////////////////////////////////////////////////
     1163void * memset( void*        dest,
     1164                      int          value,
     1165                      unsigned int count )
     1166{
     1167    // word-by-word copy
     1168    unsigned int* idst = dest;
     1169    unsigned int  data = (((unsigned char)value)      ) |
     1170                         (((unsigned char)value) <<  8) |
     1171                         (((unsigned char)value) << 16) |
     1172                         (((unsigned char)value) << 24) ;
     1173
     1174    if ( ! ((unsigned int)idst & 3) )
     1175    {
     1176        while ( count > 3 )
     1177        {
     1178            *idst++ = data;
     1179            count -= 4;
     1180        }
     1181    }
     1182   
     1183    // byte-by-byte copy
     1184    unsigned char* cdst = dest;
     1185    while (count--)
     1186    {
     1187        *cdst++ = (unsigned char)value;
     1188    }
     1189    return dest;
     1190}
     1191
     1192
    11881193// Local Variables:
    11891194// tab-width: 4
Note: See TracChangeset for help on using the changeset viewer.