arch/x86/include/asm/unistd.h vs. include/asm-generic/unistd.h - linux

What's the difference between these two files? I can't really get it. I should mention that the first file should be arch/x86/include/asm/unistd_32.h (or and _64.h). Here is a quick preview of what they contain:
arch/x86/include/asm/unistd.h:
#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H
/*
* This file contains the system call numbers.
*/
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
#define __NR_unlink 10
#define __NR_execve 11
#define __NR_chdir 12
#define __NR_time 13
#define __NR_mknod 14
#define __NR_chmod 15
#define __NR_lchown 16
#define __NR_break 17
#define __NR_oldstat 18
#define __NR_lseek 19
#define __NR_getpid 20
#define __NR_mount 21
#define __NR_umount 22
include/asm-generic/unistd.h
#if !defined(_ASM_GENERIC_UNISTD_H) || defined(__SYSCALL)
#define _ASM_GENERIC_UNISTD_H
#include <asm/bitsperlong.h>
/*
* This file contains the system call numbers, based on the
* layout of the x86-64 architecture, which embeds the
* pointer to the syscall in the table.
*
* As a basic principle, no duplication of functionality
* should be added, e.g. we don't use lseek when llseek
* is present. New architectures should use this file
* and implement the less feature-full calls in user space.
*/
#ifndef __SYSCALL
#define __SYSCALL(x, y)
#endif
#if __BITS_PER_LONG == 32
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
#else
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
#endif
#define __NR_io_setup 0
__SYSCALL(__NR_io_setup, sys_io_setup)
#define __NR_io_destroy 1
__SYSCALL(__NR_io_destroy, sys_io_destroy)
#define __NR_io_submit 2
__SYSCALL(__NR_io_submit, sys_io_submit)
#define __NR_io_cancel 3
__SYSCALL(__NR_io_cancel, sys_io_cancel)
#define __NR_io_getevents 4
__SYSCALL(__NR_io_getevents, sys_io_getevents)
/* fs/xattr.c */
#define __NR_setxattr 5
__SYSCALL(__NR_setxattr, sys_setxattr)
#define __NR_lsetxattr 6
__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
#define __NR_fsetxattr 7
__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
#define __NR_getxattr 8
__SYSCALL(__NR_getxattr, sys_getxattr)
#define __NR_lgetxattr 9
__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
#define __NR_fgetxattr 10
__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
#define __NR_listxattr 11
__SYSCALL(__NR_listxattr, sys_listxattr)
#define __NR_llistxattr 12

I don't have a definite answer, but it's not uncommon for redundant files to exist when devs try to shift from old mechanisms to newer ones. Your case here looks quite similar.
If you checkout the 3.4 kernel, you will find that both arch/x86/include/asm/unistd_32.h and arch/x86/include/asm/unistd_64.h are gone. Instead, they are generated using arch/x86/syscalls.
Checkout the latest kernel (3.4.2 stable works for me), and do a "git log --stat arch/x86/include/asm", search for unistd_64.h or unistd_32.h or unistd.h.
I found the following commit might be interesting to you.
commit 303395ac3bf3e2cb488435537d416bc840438fcb
I've never touched syscalls before, so I'd rather not say too much. git log is usually how I sort out confusing files. You can also get into makefiles if you are good at it. (I am not, so I rely on git log. )

Related

User can define the virtual address ignoring API?

It was strange to me when I saw this:
#define HI3518_IOCH1_PHYS 0x10000000 /* 0x1000_0000 ~ 0x1020_0000 */
#define HI3518_IOCH2_PHYS 0x20000000 /* 0x2000_0000 ~ 0x2020_0000 */
#define HI3518_IOCH1_SIZE 0x200000
#define HI3518_IOCH2_SIZE 0x700000
#define HI3518_IOCH1_VIRT 0xFE000000
#define HI3518_IOCH2_VIRT (HI3518_IOCH1_VIRT + HI3518_IOCH1_SIZE)
This is located at arch/arm/mach-hi3518/include/mach/io.h
The last 2 line puzzle me, is that mean user can determine the virtual address themselves, don't need to use APIs?
Thanks in advance!

How to understand the macro of "page_align" in kernel?

the codes is:
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
I know this marco aligns
any address on the page boundary. How to understand this implement
?
It rounds up an addr to the next multiple of 4096 (i.e. 212), by adding 4095 (i.e. 212-1) to it and clearing the lowest 12 bits

Can't compile MAGMA 1.3 on Ubuntu 10.04, CUDA 5.0

I'm trying to compile MAGMA libraries on Ubuntu 10.04, and I'm stuck.
From the README file:
To INSTALL MAGMA, modify the make.inc file to indicate where CUDA, CPU BLAS, and LAPACK are installed on your system. Examples
are given in make.inc.mkl, make.inc.acml, make.inc.goto, and
make.inc.atlas, showing how to link correspondingly to MKL, ACML,
GOTO BLAS or ATLAS BLAS. After proper modification of the make.inc
file, typing 'make', will create 1) the libmagma.a and
libmagmablas.a libraries in directory 'lib' 2) testing drivers in
directory 'testing'.
So, I install the required packages:
apt-get install libatlas-base-dev liblapack-dev libf2c2-dev gfortran
Copy make.inc.atlas to make.inc modifying the CUDA path, the nvcc path and the liblapack.a path, and I remove two unnecessary linking directories.
For full reference, here is the original make.inc.atlas:
#//////////////////////////////////////////////////////////////////////////////
# -- MAGMA (version 1.3.0) --
# Univ. of Tennessee, Knoxville
# Univ. of California, Berkeley
# Univ. of Colorado, Denver
# November 2012
#//////////////////////////////////////////////////////////////////////////////
#
# GPU_TARGET specifies for which GPU you want to compile MAGMA:
# "Tesla" (NVIDIA compute capability 1.x cards)
# "Fermi" (NVIDIA compute capability 2.x cards)
# See http://developer.nvidia.com/cuda-gpus
GPU_TARGET = Fermi
CC = gcc
NVCC = nvcc
FORT = gfortran
ARCH = ar
ARCHFLAGS = cr
RANLIB = ranlib
OPTS = -O3 -DADD_
F77OPTS = -O3 -DADD_
FOPTS = -O3 -DADD_ -x f95-cpp-input
NVOPTS = -O3 -DADD_ --compiler-options -fno-strict-aliasing -DUNIX
LDOPTS = -fPIC -Xlinker -zmuldefs
LIB = /home/tomov/LIB/lapack-lite-3.1.1/lapack_LINUX64.a \
-lf77blas -latlas -lcblas -lf2c -lcublas -lm
CUDADIR = /usr/local/cuda-3.0
LIBDIR = -L/home/tomov/LIB/ATLAS/lib/Linux_UNKNOWNSSE2 \
-L/home/tomov/LIB/CLAPACK-3.1.1/F2CLIBS/ \
-L$(CUDADIR)/lib64
INC = -I$(CUDADIR)/include
And here, my modified file saved into make.inc:
#//////////////////////////////////////////////////////////////////////////////
# -- MAGMA (version 1.3.0) --
# Univ. of Tennessee, Knoxville
# Univ. of California, Berkeley
# Univ. of Colorado, Denver
# November 2012
#//////////////////////////////////////////////////////////////////////////////
#
# GPU_TARGET specifies for which GPU you want to compile MAGMA:
# "Tesla" (NVIDIA compute capability 1.x cards)
# "Fermi" (NVIDIA compute capability 2.x cards)
# See http://developer.nvidia.com/cuda-gpus
GPU_TARGET = Fermi
CC = gcc
NVCC = /usr/local/cuda-5.0/bin/nvcc
FORT = gfortran
ARCH = ar
ARCHFLAGS = cr
RANLIB = ranlib
OPTS = -O3 -DADD_
F77OPTS = -O3 -DADD_
FOPTS = -O3 -DADD_ -x f95-cpp-input
NVOPTS = -O3 -DADD_ --compiler-options -fno-strict-aliasing -DUNIX
LDOPTS = -fPIC -Xlinker -zmuldefs
LIB = /usr/lib/liblapack.a \
-lf77blas -latlas -lcblas -lf2c -lcublas -lm
CUDADIR = /usr/local/cuda-5.0
LIBDIR = -L$(CUDADIR)/lib64
INC = -I$(CUDADIR)/include
So, I run make and I get this error. I apply the solution proposed there, and compiling continues so far, up to this point:
make[1]: Entering directory `/usr/src/magma-1.3.0/testing'
gcc -O3 -DADD_ -DHAVE_CUBLAS -DGPUSHMEM=200 -I/usr/local/cuda-5.0/include -I../include -I../control -c /usr/local/cuda-5.0/src/fortran.c -o fortran.o
In file included from /usr/local/cuda-5.0/src/fortran.c:67:
/usr/local/cuda-5.0/src/fortran_common.h:405:2: error: #error unsupported Fortran compiler
make[1]: *** [fortran.o] Error 1
make[1]: Leaving directory `/usr/src/magma-1.3.0/testing'
make: *** [test] Error 2
What can I do?
Easy solution: set FORT as follows:
FORT = gfortran -DCUBLAS_GFORTRAN
This seems like a CUDA problem. Open the fortran_common.h and locate this condition:
#if defined(CUBLAS_GFORTRAN) || defined (CUBLAS_G95)
This condition should be met, AFAIK. But it doesn't, so just delete that line, and also delete all the other elsif and endif lines and complete paths. The file fortran_common.h should be like this one:
/*
* Copyright 1993-2012 NVIDIA Corporation. All rights reserved.
*
* NOTICE TO LICENSEE:
*
* This source code and/or documentation ("Licensed Deliverables") are
* subject to NVIDIA intellectual property rights under U.S. and
* international Copyright laws.
*
* These Licensed Deliverables contained herein is PROPRIETARY and
* CONFIDENTIAL to NVIDIA and is being provided under the terms and
* conditions of a form of NVIDIA software license agreement by and
* between NVIDIA and Licensee ("License Agreement") or electronically
* accepted by Licensee. Notwithstanding any terms or conditions to
* the contrary in the License Agreement, reproduction or disclosure
* of the Licensed Deliverables to any third party without the express
* written consent of NVIDIA is prohibited.
*
* NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
* LICENSE AGREEMENT, NVIDIA MAKES NO REPRESENTATION ABOUT THE
* SUITABILITY OF THESE LICENSED DELIVERABLES FOR ANY PURPOSE. IT IS
* PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.
* NVIDIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THESE LICENSED
* DELIVERABLES, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY,
* NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
* NOTWITHSTANDING ANY TERMS OR CONDITIONS TO THE CONTRARY IN THE
* LICENSE AGREEMENT, IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY
* SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THESE LICENSED DELIVERABLES.
*
* U.S. Government End Users. These Licensed Deliverables are a
* "commercial item" as that term is defined at 48 C.F.R. 2.101 (OCT
* 1995), consisting of "commercial computer software" and "commercial
* computer software documentation" as such terms are used in 48
* C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Government
* only as a commercial end item. Consistent with 48 C.F.R.12.212 and
* 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), all
* U.S. Government End Users acquire the Licensed Deliverables with
* only those rights set forth herein.
*
* Any use of the Licensed Deliverables in individual and commercial
* software must include, in the user documentation and internal
* comments to the code, the above Disclaimer and U.S. Government End
* Users Notice.
*/
/* Define CUBLAS_FORTRAN_COMPILER for Windows needed because
tbe compilation is done from the perl script fortran_nightly.pl which
does not include fortran_tools.mk
On Linux and Apple, CFLAGS is setup with fortran_tools.mk
*/
#if defined(_WIN32)
#ifndef CUBLAS_INTEL_FORTRAN
#define CUBLAS_INTEL_FORTRAN
#endif
#endif
#if defined(CUBLAS_GFORTRAN)
/* using option -ff2c make the ABI compatible with F77
No need to define RETURN_COMPLEX, which cause problem
on Gfortran 4.x on 32 bit
*/
/* #define RETURN_COMPLEX 1 */
#endif
/* NOTE: Must use -fno-second-underscore when building Fortran source with g77
* g77 invocation may not use -fno-f2c, which forces different return
* type conventions than the one used below
*/
#define CUBLAS_INIT cublas_init_
#define CUBLAS_SHUTDOWN cublas_shutdown_
#define CUBLAS_ALLOC cublas_alloc_
#define CUBLAS_FREE cublas_free_
#define CUBLAS_SET_VECTOR cublas_set_vector_
#define CUBLAS_GET_VECTOR cublas_get_vector_
#define CUBLAS_SET_MATRIX cublas_set_matrix_
#define CUBLAS_GET_MATRIX cublas_get_matrix_
#define CUBLAS_GET_ERROR cublas_get_error_
#define CUBLAS_XERBLA cublas_xerbla_
#define CUBLAS_ISAMAX cublas_isamax_
#define CUBLAS_ISAMIN cublas_isamin_
#define CUBLAS_SASUM cublas_sasum_
#define CUBLAS_SAXPY cublas_saxpy_
#define CUBLAS_SCOPY cublas_scopy_
#define CUBLAS_SDOT cublas_sdot_
#define CUBLAS_SNRM2 cublas_snrm2_
#define CUBLAS_SROT cublas_srot_
#define CUBLAS_SROTG cublas_srotg_
#define CUBLAS_SROTM cublas_srotm_
#define CUBLAS_SROTMG cublas_srotmg_
#define CUBLAS_SSCAL cublas_sscal_
#define CUBLAS_SSWAP cublas_sswap_
#define CUBLAS_CAXPY cublas_caxpy_
#define CUBLAS_CCOPY cublas_ccopy_
#define CUBLAS_CROT cublas_crot_
#define CUBLAS_CROTG cublas_crotg_
#define CUBLAS_CSCAL cublas_cscal_
#define CUBLAS_CSROT cublas_csrot_
#define CUBLAS_CSSCAL cublas_csscal_
#define CUBLAS_CSWAP cublas_cswap_
#define CUBLAS_CTRMV cublas_ctrmv_
#define CUBLAS_CDOTU cublas_cdotu_
#define CUBLAS_CDOTC cublas_cdotc_
#define CUBLAS_ICAMAX cublas_icamax_
#define CUBLAS_SCASUM cublas_scasum_
#define CUBLAS_SCNRM2 cublas_scnrm2_
#define CUBLAS_SGBMV cublas_sgbmv_
#define CUBLAS_SGEMV cublas_sgemv_
#define CUBLAS_SGER cublas_sger_
#define CUBLAS_SSBMV cublas_ssbmv_
#define CUBLAS_SSPMV cublas_sspmv_
#define CUBLAS_SSPR cublas_sspr_
#define CUBLAS_SSPR2 cublas_sspr2_
#define CUBLAS_SSYMV cublas_ssymv_
#define CUBLAS_SSYR cublas_ssyr_
#define CUBLAS_SSYR2 cublas_ssyr2_
#define CUBLAS_STBMV cublas_stbmv_
#define CUBLAS_STBSV cublas_stbsv_
#define CUBLAS_STPMV cublas_stpmv_
#define CUBLAS_STPSV cublas_stpsv_
#define CUBLAS_STRMV cublas_strmv_
#define CUBLAS_STRSV cublas_strsv_
#define CUBLAS_SGEMM cublas_sgemm_
#define CUBLAS_SSYMM cublas_ssymm_
#define CUBLAS_SSYR2K cublas_ssyr2k_
#define CUBLAS_SSYRK cublas_ssyrk_
#define CUBLAS_STRMM cublas_strmm_
#define CUBLAS_STRSM cublas_strsm_
#define CUBLAS_CGEMM cublas_cgemm_
#define CUBLAS_CHEMM cublas_chemm_
#define CUBLAS_CSYMM cublas_csymm_
#define CUBLAS_CTRMM cublas_ctrmm_
#define CUBLAS_CTRSM cublas_ctrsm_
#define CUBLAS_CHERK cublas_cherk_
#define CUBLAS_CSYRK cublas_csyrk_
#define CUBLAS_CHER2K cublas_cher2k_
#define CUBLAS_CSYR2K cublas_csyr2k_
#define CUBLAS_IDAMAX cublas_idamax_
#define CUBLAS_IDAMIN cublas_idamin_
#define CUBLAS_DASUM cublas_dasum_
#define CUBLAS_DAXPY cublas_daxpy_
#define CUBLAS_DCOPY cublas_dcopy_
#define CUBLAS_DDOT cublas_ddot_
#define CUBLAS_DNRM2 cublas_dnrm2_
#define CUBLAS_DROT cublas_drot_
#define CUBLAS_DROTG cublas_drotg_
#define CUBLAS_DROTM cublas_drotm_
#define CUBLAS_DROTMG cublas_drotmg_
#define CUBLAS_DSCAL cublas_dscal_
#define CUBLAS_DSWAP cublas_dswap_
#define CUBLAS_ZAXPY cublas_zaxpy_
#define CUBLAS_ZCOPY cublas_zcopy_
#define CUBLAS_ZROT cublas_zrot_
#define CUBLAS_ZROTG cublas_zrotg_
#define CUBLAS_ZSCAL cublas_zscal_
#define CUBLAS_ZDROT cublas_zdrot_
#define CUBLAS_ZDSCAL cublas_zdscal_
#define CUBLAS_ZSWAP cublas_zswap_
#define CUBLAS_ZDOTU cublas_zdotu_
#define CUBLAS_ZDOTC cublas_zdotc_
#define CUBLAS_IZAMAX cublas_izamax_
#define CUBLAS_DZASUM cublas_dzasum_
#define CUBLAS_DZNRM2 cublas_dznrm2_
#define CUBLAS_DGBMV cublas_dgbmv_
#define CUBLAS_DGEMV cublas_dgemv_
#define CUBLAS_ZGEMV cublas_zgemv_
#define CUBLAS_DGER cublas_dger_
#define CUBLAS_DSBMV cublas_dsbmv_
#define CUBLAS_DSPMV cublas_dspmv_
#define CUBLAS_DSPR cublas_dspr_
#define CUBLAS_DSPR2 cublas_dspr2_
#define CUBLAS_DSYMV cublas_dsymv_
#define CUBLAS_DSYR cublas_dsyr_
#define CUBLAS_DSYR2 cublas_dsyr2_
#define CUBLAS_DTBMV cublas_dtbmv_
#define CUBLAS_DTBSV cublas_dtbsv_
#define CUBLAS_DTPMV cublas_dtpmv_
#define CUBLAS_DTPSV cublas_dtpsv_
#define CUBLAS_DTRMV cublas_dtrmv_
#define CUBLAS_DTRSV cublas_dtrsv_
#define CUBLAS_DGEMM cublas_dgemm_
#define CUBLAS_DSYMM cublas_dsymm_
#define CUBLAS_DSYR2K cublas_dsyr2k_
#define CUBLAS_DSYRK cublas_dsyrk_
#define CUBLAS_ZSYRK cublas_zsyrk_
#define CUBLAS_DTRMM cublas_dtrmm_
#define CUBLAS_DTRSM cublas_dtrsm_
#define CUBLAS_ZGEMM cublas_zgemm_
#define CUBLAS_ZHEMM cublas_zhemm_
#define CUBLAS_ZSYMM cublas_zsymm_
#define CUBLAS_ZTRMM cublas_ztrmm_
#define CUBLAS_ZTRSM cublas_ztrsm_
#define CUBLAS_ZHERK cublas_zherk_
#define CUBLAS_ZSYRK cublas_zsyrk_
#define CUBLAS_ZHER2K cublas_zher2k_
#define CUBLAS_ZSYR2K cublas_zsyr2k_
#define CUBLAS_CGEMV cublas_cgemv_
#define CUBLAS_CGBMV cublas_cgbmv_
#define CUBLAS_CHEMV cublas_chemv_
#define CUBLAS_CHBMV cublas_chbmv_
#define CUBLAS_CHPMV cublas_chpmv_
#define CUBLAS_CTBMV cublas_ctbmv_
#define CUBLAS_CTPMV cublas_ctpmv_
#define CUBLAS_CTRSV cublas_ctrsv_
#define CUBLAS_CTBSV cublas_ctbsv_
#define CUBLAS_CTPSV cublas_ctpsv_
#define CUBLAS_CGERC cublas_cgerc_
#define CUBLAS_CGERU cublas_cgeru_
#define CUBLAS_CHPR cublas_chpr_
#define CUBLAS_CHPR2 cublas_chpr2_
#define CUBLAS_CHER cublas_cher_
#define CUBLAS_CHER2 cublas_cher2_
// stubs for zblat2
#define CUBLAS_ZGBMV cublas_zgbmv_
#define CUBLAS_ZHEMV cublas_zhemv_
#define CUBLAS_ZHBMV cublas_zhbmv_
#define CUBLAS_ZHPMV cublas_zhpmv_
#define CUBLAS_ZTRMV cublas_ztrmv_
#define CUBLAS_ZTBMV cublas_ztbmv_
#define CUBLAS_ZTPMV cublas_ztpmv_
#define CUBLAS_ZTRSV cublas_ztrsv_
#define CUBLAS_ZTBSV cublas_ztbsv_
#define CUBLAS_ZTPSV cublas_ztpsv_
#define CUBLAS_ZGERC cublas_zgerc_
#define CUBLAS_ZGERU cublas_zgeru_
#define CUBLAS_ZHER cublas_zher_
#define CUBLAS_ZHPR cublas_zhpr_
#define CUBLAS_ZHER2 cublas_zher2_
#define CUBLAS_ZHPR2 cublas_zhpr2_
After that change, MAGMA compiles OK.

Latest ATL version

I couldn't find the exact number of current Active Template Library (ATL) which distribute along with Visual Studio 2012. Does anyone have an idea about the exact version number ?
From atldef.h:
/////////////////////////////////////////////////////////////////////////////
// Master version numbers
#define _ATL 1 // Active Template Library
#define _ATL_VER 0x0A00 // Active Template Library version 10.00
#ifndef _ATL_FILENAME_VER
#define _ATL_FILENAME_VER "100"
#endif
#ifndef _ATL_FILENAME_VER_NUM
#define _ATL_FILENAME_VER_NUM 100
#endif
#ifndef _ATL_VER_RBLD
#define _ATL_VER_RBLD "10.00"
#endif

Linux kernel 0.0.1 vs 2.6.36, "ctype.h", whats the difference?

How efficient is linux kernel 2.6.36 from 0.0.1
0.0.1:
I understand, in this version, Linus has assigned the value of
c(input variable to a function) to a temp variable and operate on
that temp variable inside the function and return the temp variable.
This happens in tolower/toupper functions.
2.6.36:
Here in tolower/toupper he changed it.
ctype is const.
New function ismask is written.
What I want to know?:
Why these changes has been made?, what good it brought home?
I have listed out the ctype.h files in the kernel versions of 0.0.1 and 2.6.36, respectively.
**** ctype.h, linux-0.01 *****
#ifndef _CTYPE_H
#define _CTYPE_H
#define _U 0x01 /* upper */
#define _L 0x02 /* lower */
#define _D 0x04 /* digit */
#define _C 0x08 /* cntrl */
#define _P 0x10 /* punct */
#define _S 0x20 /* white space (space/lf/tab) */
#define _X 0x40 /* hex digit */
#define _SP 0x80 /* hard space (0x20) */
extern unsigned char _ctype[];
extern char _ctmp;
#define isalnum(c) ((_ctype+1)[c]&(_U|_L|_D))
#define isalpha(c) ((_ctype+1)[c]&(_U|_L))
#define iscntrl(c) ((_ctype+1)[c]&(_C))
#define isdigit(c) ((_ctype+1)[c]&(_D))
#define isgraph(c) ((_ctype+1)[c]&(_P|_U|_L|_D))
#define islower(c) ((_ctype+1)[c]&(_L))
#define isprint(c) ((_ctype+1)[c]&(_P|_U|_L|_D|_SP))
#define ispunct(c) ((_ctype+1)[c]&(_P))
#define isspace(c) ((_ctype+1)[c]&(_S))
#define isupper(c) ((_ctype+1)[c]&(_U))
#define isxdigit(c) ((_ctype+1)[c]&(_D|_X))
#define isascii(c) (((unsigned) c)<=0x7f)
#define toascii(c) (((unsigned) c)&0x7f)
#define tolower(c) (_ctmp=c,isupper(_ctmp)?_ctmp+('a'+'A'):_ctmp)
#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp+('A'-'a'):_ctmp)
#endif
#
****** ctype.h, linux-2.6.36 *******
#ifndef _LINUX_CTYPE_H
#define _LINUX_CTYPE_H
/*
* NOTE! This ctype does not handle EOF like the standard C
* library is required to.
*/
#define _U 0x01 /* upper */
#define _L 0x02 /* lower */
#define _D 0x04 /* digit */
#define _C 0x08 /* cntrl */
#define _P 0x10 /* punct */
#define _S 0x20 /* white space (space/lf/tab) */
#define _X 0x40 /* hex digit */
#define _SP 0x80 /* hard space (0x20) */
extern const unsigned char _ctype[];
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
#define isdigit(c) ((__ismask(c)&(_D)) != 0)
#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
#define islower(c) ((__ismask(c)&(_L)) != 0)
#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
#define ispunct(c) ((__ismask(c)&(_P)) != 0)
/* Note: isspace() must return false for %NUL-terminator */
#define isspace(c) ((__ismask(c)&(_S)) != 0)
#define isupper(c) ((__ismask(c)&(_U)) != 0)
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
#define isascii(c) (((unsigned char)(c))<=0x7f)
#define toascii(c) (((unsigned char)(c))&0x7f)
static inline unsigned char __tolower(unsigned char c)
{
if (isupper(c))
c -= 'A'-'a';
return c;
}
static inline unsigned char __toupper(unsigned char c)
{
if (islower(c))
c -= 'a'-'A';
return c;
}
#define tolower(c) __tolower(c)
#define toupper(c) __toupper(c)
#endif
Why these changes has been made?, what good it brought home?
For one, you don't have to define a ctemp variable in code calling isupper any longer, thereby reducing lines of code. It also obviously avoids leaking implementation details.

Resources