8、特定区域的字符串比较和转换strcoll,strxfrm,wcscoll,wcsxfrm:strcoll使用当前的区域设置来比较字符串,strxfrm使用当前的区域设置来转换字符串。当前区域设置由LL_COLLATE宏指定。它们均调用带有区域设置参数的内部版本strcoll_l和strxfrm_l来完成实际的工作。
9、错误消息报告strerror:获取错误码errnum的字符串描述,在下一次调用strerror之前这个字符串存储空间不能修改,对这个空间进行写操作会导致未定义的行为。若获取没有成功,则使用errno全局变量(或全局宏)中的错误码来获取错误消息。
10、内存块复制memcpy,memmove,wmemcpy,wmemmove:memcpy从SRC中复制N个字节的内容到DEST中,memmove从SRC中复制N个字节的内容到DEST中,保证对重叠字符串(即SRC与DEST共用存储空间)有正确的行为。这两个函数的实现使用了memcopy.h和pagecopy.h中定义的内部接口,有按字节方式复制BYTE_COPY_FWD,按字方式复制WORD_COPY_FWD(一个字为unsigned long型)、按页方式复制PAGE_COPY_FWD_MAYBE,这些接口都是以宏的形式提供的。
解释:
(1)memcopy.h中,宏op_t为字的类型,定义为unsigned long,OPSIZ为字的大小(32位平台中为4字节)。byte为字节的类型,定义为unsigned char。MERGE函数用于合并两个字,根据不同的机器字节序,一个字在高端,一个字在低端。字节复制和字复制都有两种方式,一种是向前复制,一种是向后复制。字复制时需要指针对齐到字的边界(即指针变量中的值为OPSIZ的倍数),复制操作使用了编译器内置的_wordcopy_fwd_aligned等函数。字节复制的接口中的代码是很直接的,用一个while循环一个字节一个字节地进行拷贝即可。宏OP_T_THRES定义了能进行字复制的最低门槛值。
(2)pagecopy.h中,要复制的字节数必须达到一定的门槛值PAGE_COPY_THRESHOLD(这个值在内核中定义),才会执行按页复制。PAGE_SIZE为页的大小,在内核中定义,PAGE_OFFSET(n)用于计算页的偏移。复制时先用WORD_COPY_FWD复制前面几个字节,这样就能让源地址和目标地址按页对齐,然后就可执行页复制。
(3)有了这些宏,memcpy和memmove函数的实现就比较简单了,直接用这些接口来进行复制操作,只不过要注意进行字复制或页复制时要复制开头的几个字节,以对齐到字或页的边界。最后尾部可能还剩下几个字节,用字节复制复制它们即可。
11、内存块中的字符搜索memchr,wmemchr:在内存块S的前N个字节中搜索C的第一次出现。算法实现与strlen及strchr类似。
12、内存块比较memcmp,wmemcmp:对两个内存块的前N个字节进行比较。比较也是使用字(unsigned long型)的比较方式,以加快搜索速度。采用的策略是先比较开头的几个字节,以使块指针对齐到字的边界,再用memcmp_common_alignment(两个内存块都对齐的情况)或memcmp_not_common_alignment(一个内存块对齐,而另一个没有对齐)按字进行快速的比较,最后对剩下的几个字节进行比较。代码就不再解剖了,涉及到大量的字操作,以及用MERGE进行字合并(这需要考虑到机器的字节序)。
13、内存块设置memset,wmemset:将内存块的前LEN个字节设置为字符C。也是采用字的方式来进行快速地写入。先设置了一个字cccc,其每个字节都是字符C。为了加快写入速度,每循环一次就写入8个cccc,最后对剩下的几个字节写入C。