├── Android.mk ├── BUGS ├── CHANGELOG ├── COPYING ├── Makefile ├── README ├── README.tests ├── conf-cc ├── conf-ld ├── extra-libs.sh ├── find-systype.sh ├── make-compile.sh ├── make-load.sh ├── make-makelib.sh ├── memtester.8 ├── memtester.c ├── memtester.h ├── sizes.h ├── tests.c ├── tests.h ├── trycpp.c ├── types.h └── warn-auto.sh /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | LOCAL_SRC_FILES:= \ 4 | memtester.c tests.c 5 | LOCAL_MODULE:= memtester 6 | LOCAL_MODULE_FILENAME:=memtester 7 | LOCAL_C_INCLUDES:=$(LOCAL_PATH) 8 | #LOCAL_C_INCLUDES := 9 | #LOCAL_STATIC_LIBRARIES := 10 | #LOCAL_SHARED_LIBRARIES := 11 | include $(BUILD_EXECUTABLE) 12 | 13 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | * On some platforms, a few of the initial output messages don't format 2 | correctly, due to %llu or %tx not being a supported printf format. This 3 | is harmless. 4 | 5 | If you spot any other bugs in the software or documentation, please ensure 6 | you're using the latest version from http://pyropus.ca/software/memtester/ , 7 | then email me at so that I can correct it. 8 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | Version 4.3.0 2 | 9 June 2012 3 | -add ability to mmap a device other than /dev/mem, enabling easier testing 4 | of memory for hardware engineers et al if their system's kernel exports the 5 | memory they're interested in via /dev/mydevice or similar. Thanks: 6 | Jean-Noël Avila. 7 | -add ability to run only specified tests by setting the environment 8 | variable MEMTESTER_TEST_MASK to a bitmask of the indexes of the tests to be 9 | run. Thanks: Ian Alexander. 10 | 11 | Version 4.2.2 12 | 22 July 2011 13 | -add progress message for one more errno value (EAGAIN) in response to failed 14 | mlock; BSDs use this to indicate the lock failed due to being over a system 15 | or process limit, much like ENOMEM. 16 | 17 | Version 4.2.1 18 | 3 October 2010 19 | -fix offsets/addresses were not being reported correctly in test failure 20 | messages. Thanks: Anton Sergeev. 21 | 22 | Version 4.2.0 23 | 30 July 2010 24 | -define _FILE_OFFSET_BITS to 64 by default in conf-cc, which causes some 25 | 32-bit systems with larger-than-32-bit address spaces to have a 64-bit off_t, 26 | allowing testing of larger chunks of memory. Thanks to Steven A. Falco for 27 | the suggestion. Let me know if this definition causes problems for anyone. 28 | -add tests of 8-bit-wide and 16-bit-wide random writes, to enable verifying 29 | the correct operation of hardware. Thanks: Dick Hollenbeck. If these tests 30 | trigger unaligned access problems on your platform, you can eliminate these 31 | tests by removing the -DTEST_NARROW_WRITES definition from the conf-cc file. 32 | 33 | Version 4.1.3 34 | 28 February 2010 35 | -fix 64-bit data patterns with some versions of gcc. Thanks: Tony Battersby. 36 | -clarify `make install` in readme. Thanks: Marc Lobelle. 37 | 38 | Version 4.1.2 39 | 28 July 2009 40 | -fix portability issue with MAP_LOCKED flag. Thanks: Scott Haneda. 41 | -remove debugging output accidentally left in v.4.1.0. 42 | -cleanups 43 | 44 | Version 4.1.1 45 | 24 July 2009 46 | 47 | -memtester.h was missing from the 4.1.0 tarball; release update to fix that. 48 | Thanks: Owen Leonard. 49 | 50 | Version 4.1.0 51 | 23 July 2009 52 | 53 | -added the ability to test a specific physical region of memory (by mmap'ing 54 | /dev/mem) with the new -p option, which takes a hex starting address as a 55 | value. This is mostly of use to developers trying to verify memory or I/O 56 | mapped devices (on an embedded system, for instance). Thanks: Allon Stern. 57 | -re-add the ability to set a suffix on the memory to allocate: "3G", "128K", etc, 58 | mostly for use with the above new feature, where the "memory" to be tested is 59 | less than a megabyte, but also useful for users wanting to test many gigabytes; 60 | you no longer have to do the conversion-to-megs in your head. 61 | -documentation updates and clarifications. 62 | 63 | Version 4.0.8 64 | 21 November 2007 65 | 66 | -add a startup check for amount of memory being greater than the possible 67 | address space; prevents user confusion on 32-bit systems that use addressing 68 | tricks to have >4GB total system memory. Thanks: Michael Kelly. 69 | -documentation updates 70 | 71 | Version 4.0.7 72 | 13 May 2007 73 | 74 | -fix a bug in the align-to-page logic which may have prevented memtester 75 | from mlock()ing the memory it was trying to test on some systems. 76 | Thanks: Baif Chen. 77 | 78 | Version 4.0.6 79 | 15 November 2006 80 | 81 | -test algorithm improvement: the walking 0 bits test was only walking 82 | the 0 bit in one direction, instead of walking it up and back down 83 | the line the way it was intended to. Thanks: Tim Rule. 84 | -formatting cleanups. 85 | 86 | Version 4.0.5 87 | 10 March 2005 88 | 89 | -change to the method of allocating and locking memory; if we get EPERM 90 | when trying to mlock(), reset the amount of memory desired to the original 91 | amount and try again without mlock(). The reason for this is that on many 92 | systems, mlock() won't return EPERM until after having returned ENOMEM for 93 | a larger amount. The new behaviour allows processes without mlock privileges 94 | to still test the fully-specified amount or as much memory as can be 95 | allocated. Thanks for the suggestion and testing to Dan Bradley. 96 | 97 | Version 4.0.4 98 | 26 August 2004 99 | 100 | -make memtester's exit code meaningful. See the manpage for its meaning. 101 | Thanks to Wurzel Parsons-Keir, who sent a patch for the code, so I only had 102 | to document it. 103 | 104 | Version 4.0.3 105 | 10 August 2004 106 | 107 | -small changes to enable building with dietlibc and a few other environments 108 | that don't even attempt to provide the various Posix definitions. 109 | -cosmetic fixes to output. 110 | -restore the reduce-and-retry loop of memory locking from version 2. 111 | 112 | Version 4.0.2 113 | 9 August 2004 114 | 115 | -add manpage 116 | 117 | Version 4.0.1 118 | 8 August 2004 119 | 120 | -fix cosmetic bugs in output 121 | 122 | Version 4.0.0 123 | 7 August 2004 124 | 125 | -rewrite to clean up the code (previously an ugly hack), for 64-bit 126 | cleanliness 127 | -change build system to build on (hopefully) any platform. Previous 128 | versions required hackery on some systems. 129 | 130 | Version 3 not publicly released. 131 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 19yy 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) 19yy name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for memtester by Charles Cazabon. 3 | # 4 | # Copyright (C) 1999 Simon Kirby. 5 | # Copyright (C) 1999-2009 Charles Cazabon. 6 | # Licensed under the GNU General Public License version 2. See the file 7 | # COPYING for details. 8 | # 9 | 10 | # You don't need to edit these; change the contents of the conf-cc and conf-ld 11 | # files if you need to change the compile/link commands. See the README for 12 | # more information. 13 | CC = $(shell head -n 1 conf-cc) 14 | LD = $(shell head -n 1 conf-ld) 15 | 16 | SOURCES = memtester.c tests.c 17 | OBJECTS = $(SOURCES:.c=.o) 18 | HEADERS = memtester.h 19 | TARGETS = *.o compile load auto-ccld.sh find-systype make-compile make-load systype extra-libs 20 | INSTALLPATH = /usr/local 21 | 22 | # 23 | # Targets 24 | # 25 | all: memtester 26 | 27 | install: all 28 | mkdir -m 755 -p $(INSTALLPATH)/{bin,man/man8} 29 | install -m 755 memtester $(INSTALLPATH)/bin/ 30 | gzip -c memtester.8 >memtester.8.gz ; install -m 644 memtester.8.gz $(INSTALLPATH)/man/man8/ 31 | 32 | auto-ccld.sh: \ 33 | conf-cc conf-ld warn-auto.sh 34 | ( cat warn-auto.sh; \ 35 | echo CC=\'`head -1 conf-cc`\'; \ 36 | echo LD=\'`head -1 conf-ld`\' \ 37 | ) > auto-ccld.sh 38 | 39 | compile: \ 40 | make-compile warn-auto.sh systype 41 | ( cat warn-auto.sh; ./make-compile "`cat systype`" ) > \ 42 | compile 43 | chmod 755 compile 44 | 45 | find-systype: \ 46 | find-systype.sh auto-ccld.sh 47 | cat auto-ccld.sh find-systype.sh > find-systype 48 | chmod 755 find-systype 49 | 50 | make-compile: \ 51 | make-compile.sh auto-ccld.sh 52 | cat auto-ccld.sh make-compile.sh > make-compile 53 | chmod 755 make-compile 54 | 55 | make-load: \ 56 | make-load.sh auto-ccld.sh 57 | cat auto-ccld.sh make-load.sh > make-load 58 | chmod 755 make-load 59 | 60 | systype: \ 61 | find-systype trycpp.c 62 | ./find-systype > systype 63 | 64 | extra-libs: \ 65 | extra-libs.sh systype 66 | ./extra-libs.sh "`cat systype`" >extra-libs 67 | 68 | load: \ 69 | make-load warn-auto.sh systype 70 | ( cat warn-auto.sh; ./make-load "`cat systype`" ) > load 71 | chmod 755 load 72 | 73 | clean: 74 | rm -f memtester $(TARGETS) $(OBJECTS) core 75 | 76 | memtester: \ 77 | $(OBJECTS) memtester.c tests.h tests.c tests.h conf-cc Makefile load extra-libs 78 | ./load memtester tests.o `cat extra-libs` 79 | 80 | memtester.o: memtester.c tests.h conf-cc Makefile compile 81 | ./compile memtester.c 82 | 83 | tests.o: tests.c tests.h conf-cc Makefile compile 84 | ./compile tests.c 85 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ===================================== 2 | usage: 3 | cd android/ 4 | source ./build/envsetup.sh 5 | lunch xx 6 | cd android/external/ 7 | git clone https://github.com/royzhao/memtester4Android.git 8 | cd memtester4Android 9 | mm 10 | ===================================== 11 | 12 | memtester 13 | 14 | Utility to test for faulty memory subsystem. 15 | 16 | by Charles Cazabon 17 | 18 | Copyright 1999 Simon Kirby. 19 | Version 2 Copyright 1999 Charles Cazabon. 20 | Version 3 not publicly released. 21 | Version 4 rewrite: 22 | Copyright 2004-2012 Charles Cazabon. 23 | Licensed under the terms of the GNU General Public License version 2 (only). 24 | See the file COPYING for details. 25 | 26 | 27 | About memtester 28 | 29 | memtester is a utility for testing the memory subsystem in a computer to 30 | determine if it is faulty. The original source was by Simon Kirby 31 | . I have by this time completely rewritten the 32 | original source, and added many additional tests to help catch 33 | borderline memory. I also rewrote the original tests (which catch 34 | mainly memory bits which are stuck permanently high or low) so that 35 | they run approximately an order of magnitude faster. 36 | 37 | The version 4 rewrite was mainly to accomplish three things: 38 | 39 | (1) the previous code was basically a hack, and was ugly. 40 | (2) to make the code more portable. The previous version required some 41 | hackery to compile on some systems. 42 | (3) to make the code fully 64-bit aware. The previous version worked 43 | on 64-bit systems, but did not fully stress the memory subsystems 44 | on them -- this version should be better at stress-testing 64-bit 45 | systems. 46 | 47 | Building memtester 48 | 49 | memtester is currently only distributed in source-code form. Building 50 | it, however, is simple -- just type `make`. There's no `configure` script 51 | or anything like that. 52 | 53 | If you have a really strange system/toolchain, you might need to edit the 54 | conf-cc or conf-ld files, but try to build it without changes first. 55 | For example, if you want to cross-compile with `armgcc`, you would edit 56 | conf-cc and conf-ld to use `armgcc` instead of `cc`. You can also change 57 | the contents of these files for other reasons; for example, if your 58 | compiler isn't in your PATH, you could change it to use `/path/to/cc` or 59 | similar. 60 | 61 | You can run the resulting binary from anywhere, but if you want to install 62 | it and the manpage to /usr/local/, `make install` will do that. Edit 63 | INSTALLPATH in the makefile if you prefer a different location. 64 | 65 | I've successfully built and run memtester 4 on the following systems: 66 | 67 | HP Tru64 Unix 4.0g (Alpha) 68 | HP Tru64 Unix 5.1b (Alpha) 69 | HP-UX 11i 11.11 (PA-RISC) 70 | HP-UX 11i 11.23 (64-bit Itanium) 71 | Debian GNU/Linux 3.0 (various) 72 | other 32-bit Linux (RedHat, SuSE, Ubuntu, etc) (various) 73 | RedHat Enterprise Linux/CentOS (64-bit AMD Opteron) 74 | FreeBSD 4.9 (32-bit Intel) 75 | FreeBSD 5.1 (64-bit Alpha) 76 | NetBSD 1.6 (32-bit Intel) 77 | Darwin (OS X) 7.5.0 (32-bit PowerPC) 78 | OS X Leopard/Panther/whatever -- 32- or 64-bit, PPC or x86 79 | 80 | It should, however, work on other Unix-like systems -- I simply don't 81 | have access to systems running Solaris, AIX, etc. at the moment. 82 | If you have trouble building memtester on your system, please report it 83 | to me so I can fix this. 84 | 85 | Using memtester 86 | 87 | Usage is simple for the basic case. As root, run the resulting memtester 88 | binary with the following commandline: 89 | 90 | memtester [runs] 91 | 92 | where is the amount of memory to test, in megabytes by default. 93 | You can optionally include a suffix of B, K, M, or G (for bytes, 94 | kilobytes, megabytes, and gigabytes respectively). 95 | [runs] is an optional limit to the number of runs through all tests. 96 | 97 | An optional "-p physaddr" argument available to cause memtester to test 98 | memory starting at a specific physical memory address (by mmap(2)ing 99 | a device file representing physical memory (/dev/mem by default, but can 100 | be specified with the "-d device" option) starting at an offset of 101 | `physaddr`, which is given in hex). 102 | 103 | Note: the memory specified will be overwritten during testing; you 104 | therefore *cannot* specify a region belonging to the kernel or other 105 | applications without causing the other process or entire system to 106 | crash). If you use this option, it is up to you to ensure the specified 107 | memory is safe to overwrite. That makes this option mostly of use for 108 | testing memory-mapped I/O devices and similar. Thanks to Allon Stern 109 | for the idea behind this feature. For example, if you want to test a 110 | bank of RAM or device which is 64kbytes in size and starts at physical 111 | address 0x0C0000 through the normal /dev/mem, you would run memtester as 112 | follows: 113 | 114 | memtester -p 0x0c0000 64k [runs] 115 | 116 | If instead that device presented its memory as /dev/foodev at offset 117 | 0, you would run memtester instead as follows: 118 | 119 | memtester -p 0 -d /dev/foodev 64k [runs] 120 | 121 | Note that the "-d" option can only be specified in combination with "-p". 122 | 123 | memtester must run as user root so that it can lock its pages into 124 | memory. If memtester fails to lock its pages, it will issue a warning and 125 | continue regardless. Testing without the memory being locked is generally 126 | very slow and not particularly accurate, as you'll end up testing the same 127 | memory over and over as the system swaps the larger region. 128 | 129 | Current Version 130 | 131 | The current version of memtester should be available at 132 | http://pyropus.ca/software/memtester/ 133 | 134 | Questions, comments, and feature requests should be 135 | directed to me at . Read BUGS to report 136 | bugs found in memtester. 137 | 138 | -------------------------------------------------------------------------------- /README.tests: -------------------------------------------------------------------------------- 1 | About the Tests 2 | --------------- 3 | 4 | The following tests are from the original version, updated simply for speed 5 | and rewritten to fit the new framework of the program. These tests will 6 | mainly catch memory errors due to bad bits which are permanently stuck high 7 | or low: 8 | Random value 9 | XOR comparison 10 | SUB comparison 11 | MUL comparison 12 | DIV comparison 13 | OR comparison 14 | AND comparison 15 | 16 | The following tests were implemented by me, and will do a slightly better job 17 | of catching flaky bits, which may or may not hold a true value: 18 | Sequential Increment 19 | Block Sequential 20 | Solid Bits 21 | 22 | The remaining tests were also implemented by me, and are designed to catch 23 | bad bits which are dependent on the current values of surrounding bits in either 24 | the same word32, or in the preceding and succeeding word32s. 25 | Bit Flip 26 | Checkerboard 27 | Walking Ones 28 | Walking Zeroes 29 | Bit Spread 30 | 31 | There is also a test (Stuck Address) which is run first. It determines if the 32 | memory locations the program attempts to access are addressed properly or not. 33 | If this test reports errors, there is almost certainly a problem somewhere in 34 | the memory subsystem. Results from the rest of the tests cannot be considered 35 | accurate if this test fails: 36 | Stuck Address 37 | 38 | Usage information is summarized in the file README, and in the man page. 39 | -------------------------------------------------------------------------------- /conf-cc: -------------------------------------------------------------------------------- 1 | cc -O2 -DPOSIX -D_POSIX_C_SOURCE=200809L -D_FILE_OFFSET_BITS=64 -DTEST_NARROW_WRITES -c 2 | 3 | This will be used to compile .c files. 4 | -------------------------------------------------------------------------------- /conf-ld: -------------------------------------------------------------------------------- 1 | cc -s 2 | 3 | This will be used to link .o files into an executable. 4 | -------------------------------------------------------------------------------- /extra-libs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case "$1" in 4 | osf1-*) 5 | # OSF/1 (Tru64) needs /usr/lib/librt.a for mlock() 6 | echo /usr/lib/librt.a 7 | ;; 8 | unix_sv*) ;; 9 | irix64-*) ;; 10 | irix-*) ;; 11 | dgux-*) ;; 12 | hp-ux-*) ;; 13 | sco*) ;; 14 | *) 15 | ;; 16 | esac 17 | -------------------------------------------------------------------------------- /find-systype.sh: -------------------------------------------------------------------------------- 1 | # oper-:arch-:syst-:chip-:kern- 2 | # oper = operating system type; e.g., sunos-4.1.4 3 | # arch = machine language; e.g., sparc 4 | # syst = which binaries can run; e.g., sun4 5 | # chip = chip model; e.g., micro-2-80 6 | # kern = kernel version; e.g., sun4m 7 | # dependence: arch --- chip 8 | # \ \ 9 | # oper --- syst --- kern 10 | # so, for example, syst is interpreted in light of oper, but chip is not. 11 | # anyway, no slashes, no extra colons, no uppercase letters. 12 | # the point of the extra -'s is to ease parsing: can add hierarchies later. 13 | # e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium, 14 | # and i386-486 (486s do have more instructions, you know) as well as i386. 15 | # the idea here is to include ALL useful available information. 16 | 17 | exec 2>/dev/null 18 | sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`" 19 | if [ x"$sys" != x ] 20 | then 21 | unamer="`uname -r | tr /: ..`" 22 | unamem="`uname -m | tr /: ..`" 23 | unamev="`uname -v | tr /: ..`" 24 | 25 | case "$sys" in 26 | bsd.os) 27 | # in bsd 4.4, uname -v does not have useful info. 28 | # in bsd 4.4, uname -m is arch, not chip. 29 | oper="$sys-$unamer" 30 | arch="$unamem" 31 | syst="" 32 | chip="`sysctl -n hw.model`" 33 | kern="" 34 | ;; 35 | freebsd) 36 | # see above about bsd 4.4 37 | oper="$sys-$unamer" 38 | arch="$unamem" 39 | syst="" 40 | chip="`sysctl -n hw.model`" # hopefully 41 | kern="" 42 | ;; 43 | netbsd) 44 | # see above about bsd 4.4 45 | oper="$sys-$unamer" 46 | arch="$unamem" 47 | syst="" 48 | chip="`sysctl -n hw.model`" # hopefully 49 | kern="" 50 | ;; 51 | linux) 52 | # as in bsd 4.4, uname -v does not have useful info. 53 | oper="$sys-$unamer" 54 | syst="" 55 | chip="$unamem" 56 | kern="" 57 | case "$chip" in 58 | i386|i486|i586|i686) 59 | arch="i386" 60 | ;; 61 | alpha) 62 | arch="alpha" 63 | ;; 64 | esac 65 | ;; 66 | aix) 67 | # naturally IBM has to get uname -r and uname -v backwards. dorks. 68 | oper="$sys-$unamev-$unamer" 69 | arch="`arch | tr /: ..`" 70 | syst="" 71 | chip="$unamem" 72 | kern="" 73 | ;; 74 | sunos) 75 | oper="$sys-$unamer-$unamev" 76 | arch="`(uname -p || mach) | tr /: ..`" 77 | syst="`arch | tr /: ..`" 78 | chip="$unamem" # this is wrong; is there any way to get the real info? 79 | kern="`arch -k | tr /: ..`" 80 | ;; 81 | unix_sv) 82 | oper="$sys-$unamer-$unamev" 83 | arch="`uname -m`" 84 | syst="" 85 | chip="$unamem" 86 | kern="" 87 | ;; 88 | *) 89 | oper="$sys-$unamer-$unamev" 90 | arch="`arch | tr /: ..`" 91 | syst="" 92 | chip="$unamem" 93 | kern="" 94 | ;; 95 | esac 96 | else 97 | $CC -c trycpp.c 98 | $LD -o trycpp trycpp.o 99 | case `./trycpp` in 100 | nextstep) 101 | oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`" 102 | arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`" 103 | syst="" 104 | chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`" 105 | kern="" 106 | ;; 107 | *) 108 | oper="unknown" 109 | arch="" 110 | syst="" 111 | chip="" 112 | kern="" 113 | ;; 114 | esac 115 | rm -f trycpp.o trycpp 116 | fi 117 | 118 | case "$chip" in 119 | 80486) 120 | # let's try to be consistent here. (BSD/OS) 121 | chip=i486 122 | ;; 123 | i486DX) 124 | # respect the hyphen hierarchy. (FreeBSD) 125 | chip=i486-dx 126 | ;; 127 | i486.DX2) 128 | # respect the hyphen hierarchy. (FreeBSD) 129 | chip=i486-dx2 130 | ;; 131 | Intel.586) 132 | # no, you nitwits, there is no such chip. (NeXTStep) 133 | chip=pentium 134 | ;; 135 | i586) 136 | # no, you nitwits, there is no such chip. (Linux) 137 | chip=pentium 138 | ;; 139 | i686) 140 | # STOP SAYING THAT! (Linux) 141 | chip=ppro 142 | esac 143 | 144 | echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]' 145 | -------------------------------------------------------------------------------- /make-compile.sh: -------------------------------------------------------------------------------- 1 | echo exec "$CC" -c '${1+"$@"}' 2 | -------------------------------------------------------------------------------- /make-load.sh: -------------------------------------------------------------------------------- 1 | echo 'main="$1"; shift' 2 | echo exec "$LD" '-o "$main" "$main".o ${1+"$@"}' 3 | -------------------------------------------------------------------------------- /make-makelib.sh: -------------------------------------------------------------------------------- 1 | echo 'main="$1"; shift' 2 | echo 'rm -f "$main"' 3 | echo 'ar cr "$main" ${1+"$@"}' 4 | 5 | case "$1" in 6 | sunos-5.*) ;; 7 | unix_sv*) ;; 8 | irix64-*) ;; 9 | irix-*) ;; 10 | dgux-*) ;; 11 | hp-ux-*) ;; 12 | sco*) ;; 13 | *) 14 | echo 'ranlib "$main"' 15 | ;; 16 | esac 17 | -------------------------------------------------------------------------------- /memtester.8: -------------------------------------------------------------------------------- 1 | .TH memtester "8" "June 2012" "memtester 4" "Maintenance Commands" 2 | .SH NAME 3 | memtester \- stress test to find memory subsystem faults. 4 | .SH SYNOPSIS 5 | .B memtester 6 | [\f -p PHYSADDR\fR [\f -d DEVICE\fR]] 7 | <\fIMEMORY\fR> 8 | [\fIITERATIONS\fR] 9 | .SH DESCRIPTION 10 | .\" Add any additional description here 11 | .PP 12 | memtester is an effective userspace tester for stress-testing the memory 13 | subsystem. It is very effective at finding intermittent and non-deterministic 14 | faults. Note that problems in other hardware areas (overheating CPU, 15 | out-of-specification power supply, etc.) can cause intermittent memory faults, 16 | so it is still up to you to determine where the fault lies through normal 17 | hardware diagnostic procedures; memtester just helps you determine whether 18 | a problem exists. 19 | .PP 20 | memtester will malloc(3) the amount of memory specified, if possible. If 21 | this fails, it will decrease the amount of memory requested until it succeeds. 22 | It will then attempt to mlock(3) this memory; if it cannot do so, testing 23 | will be slower and much less effective. Run memtester as root so that it 24 | can mlock the memory it tests. 25 | .PP 26 | Note that the maximum amount of memory that memtester can test will be less 27 | than the total amount of memory installed in the system; the operating system, 28 | libraries, and other system limits take some of the available memory. 29 | memtester is also limited to the amount of memory available to a single 30 | process; for example, on 32-bit machines with more than 4GB of memory, 31 | memtester is still limited to less than 4GB. 32 | .PP 33 | Note that it is up to you to know how much memory you can safely allocate 34 | for testing. If you attempt to allocate more memory than is available, 35 | memtester should figure that out, reduce the amount slightly, and try again. 36 | However, this can lead to memtester successfully allocating and mlocking 37 | essentially all free memory on the system -- if other programs are running, 38 | this can lead to excessive swapping and slowing the system down to the point 39 | that it is difficult to use. If the system allows allocation of more memory 40 | than is actually available (overcommit), it may lead to a deadlock, where 41 | the system halts. If the system has an out-of-memory process killer (like 42 | Linux), memtester or another process may be killed by the OOM killer. 43 | .PP 44 | So choose wisely. 45 | .PP 46 | .SH OPTIONS 47 | .TP 48 | \f -p PHYSADDR\fR 49 | tells memtester to test a specific region of memory starting at physical 50 | address PHYSADDR (given in hex), by mmap(2)ing a device specified by the 51 | -d option (below, or /dev/mem by default). This is mostly of use to hardware 52 | developers, for testing memory-mapped I/O devices and similar. 53 | Note that the memory region will be overwritten during testing, so it is not 54 | safe to specify memory which is allocated for the system or for other 55 | applications; doing so will cause them to crash. If you absolutely must test 56 | a particular region of actual physical memory, arrange to have that memory 57 | allocated by your test software, and hold it in this allocated state, then 58 | run memtester on it with this option. 59 | .TP 60 | \fIMEMORY\fR 61 | the amount of memory to allocate and test, in megabytes by default. You can 62 | include a suffix of B, K, M, or G to indicate bytes, kilobytes, megabytes, or 63 | gigabytes respectively. 64 | .TP 65 | \fIITERATIONS\fR 66 | (optional) number of loops to iterate through. Default is infinite. 67 | .SH ENVIRONMENT 68 | .PP 69 | If the environment variable MEMTESTER_TEST_MASK is set, memtester treats the 70 | value as a bitmask of which tests (other than the stuck address test) to run. 71 | The value can be specified in decimal, in octal (with a leading 0), or in 72 | hexadecimal (with a leading 0x). The specific bit values corresponding to 73 | particular tests may change from release to release; consult the list of tests 74 | in the source for the appropriate index values for the version of memtester you 75 | are running. Note that skipping some tests will reduce the time it takes for 76 | memtester to run, but also reduce memtester's effectiveness. 77 | .SH NOTE 78 | .PP 79 | memtester must be run with root privileges to mlock(3) its pages. Testing 80 | memory without locking the pages in place is mostly pointless and slow. 81 | .SH EXIT CODE 82 | .PP 83 | memtester's exit code is 0 when everything works properly. Otherwise, 84 | it is the logical OR of the following values: 85 | .TP 86 | \f0x01 87 | error allocating or locking memory, or invocation error 88 | .TP 89 | \f0x02 90 | error during stuck address test 91 | .TP 92 | \f0x04 93 | error during one of the other tests 94 | .SH AUTHOR 95 | Written by Charles Cazabon. 96 | .SH "REPORTING BUGS" 97 | Report bugs to . 98 | .PP 99 | .SH COPYRIGHT 100 | Copyright \(co 2001-2012 Charles Cazabon 101 | .br 102 | This is free software; see the file COPYING for copying conditions. There is NO 103 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 104 | -------------------------------------------------------------------------------- /memtester.c: -------------------------------------------------------------------------------- 1 | /* 2 | * memtester version 4 3 | * 4 | * Very simple but very effective user-space memory tester. 5 | * Originally by Simon Kirby 6 | * Version 2 by Charles Cazabon 7 | * Version 3 not publicly released. 8 | * Version 4 rewrite: 9 | * Copyright (C) 2004-2012 Charles Cazabon 10 | * Licensed under the terms of the GNU General Public License version 2 (only). 11 | * See the file COPYING for details. 12 | * 13 | */ 14 | 15 | #define __version__ "4.3.0" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "types.h" 29 | #include "sizes.h" 30 | #include "tests.h" 31 | 32 | #define EXIT_FAIL_NONSTARTER 0x01 33 | #define EXIT_FAIL_ADDRESSLINES 0x02 34 | #define EXIT_FAIL_OTHERTEST 0x04 35 | 36 | struct test tests[] = { 37 | { "Random Value", test_random_value }, 38 | { "Compare XOR", test_xor_comparison }, 39 | { "Compare SUB", test_sub_comparison }, 40 | { "Compare MUL", test_mul_comparison }, 41 | { "Compare DIV",test_div_comparison }, 42 | { "Compare OR", test_or_comparison }, 43 | { "Compare AND", test_and_comparison }, 44 | { "Sequential Increment", test_seqinc_comparison }, 45 | { "Solid Bits", test_solidbits_comparison }, 46 | { "Block Sequential", test_blockseq_comparison }, 47 | { "Checkerboard", test_checkerboard_comparison }, 48 | { "Bit Spread", test_bitspread_comparison }, 49 | { "Bit Flip", test_bitflip_comparison }, 50 | { "Walking Ones", test_walkbits1_comparison }, 51 | { "Walking Zeroes", test_walkbits0_comparison }, 52 | #ifdef TEST_NARROW_WRITES 53 | { "8-bit Writes", test_8bit_wide_random }, 54 | { "16-bit Writes", test_16bit_wide_random }, 55 | #endif 56 | { NULL, NULL } 57 | }; 58 | 59 | /* Sanity checks and portability helper macros. */ 60 | #ifdef _SC_VERSION 61 | void check_posix_system(void) { 62 | if (sysconf(_SC_VERSION) < 198808L) { 63 | fprintf(stderr, "A POSIX system is required. Don't be surprised if " 64 | "this craps out.\n"); 65 | fprintf(stderr, "_SC_VERSION is %lu\n", sysconf(_SC_VERSION)); 66 | } 67 | } 68 | #else 69 | #define check_posix_system() 70 | #endif 71 | 72 | #ifdef _SC_PAGE_SIZE 73 | int memtester_pagesize(void) { 74 | int pagesize = sysconf(_SC_PAGE_SIZE); 75 | if (pagesize == -1) { 76 | perror("get page size failed"); 77 | exit(EXIT_FAIL_NONSTARTER); 78 | } 79 | printf("pagesize is %ld\n", (long) pagesize); 80 | return pagesize; 81 | } 82 | #else 83 | int memtester_pagesize(void) { 84 | printf("sysconf(_SC_PAGE_SIZE) not supported; using pagesize of 8192\n"); 85 | return 8192; 86 | } 87 | #endif 88 | 89 | /* Some systems don't define MAP_LOCKED. Define it to 0 here 90 | so it's just a no-op when ORed with other constants. */ 91 | #ifndef MAP_LOCKED 92 | #define MAP_LOCKED 0 93 | #endif 94 | 95 | /* Function declarations */ 96 | void usage(char *me); 97 | 98 | /* Global vars - so tests have access to this information */ 99 | int use_phys = 0; 100 | off_t physaddrbase = 0; 101 | 102 | /* Function definitions */ 103 | void usage(char *me) { 104 | fprintf(stderr, "\n" 105 | "Usage: %s [-p physaddrbase [-d device]] [B|K|M|G] [loops]\n", 106 | me); 107 | exit(EXIT_FAIL_NONSTARTER); 108 | } 109 | 110 | int main(int argc, char **argv) { 111 | ul loops, loop, i; 112 | size_t pagesize, wantraw, wantmb, wantbytes, wantbytes_orig, bufsize, 113 | halflen, count; 114 | char *memsuffix, *addrsuffix, *loopsuffix; 115 | ptrdiff_t pagesizemask; 116 | void volatile *buf, *aligned; 117 | ulv *bufa, *bufb; 118 | int do_mlock = 1, done_mem = 0; 119 | int exit_code = 0; 120 | int memfd, opt, memshift; 121 | size_t maxbytes = -1; /* addressable memory, in bytes */ 122 | size_t maxmb = (maxbytes >> 20) + 1; /* addressable memory, in MB */ 123 | /* Device to mmap memory from with -p, default is normal core */ 124 | char *device_name = "/dev/mem"; 125 | struct stat statbuf; 126 | int device_specified = 0; 127 | char *env_testmask = 0; 128 | ul testmask = 0; 129 | 130 | printf("memtester version " __version__ " (%d-bit)\n", UL_LEN); 131 | printf("Copyright (C) 2001-2012 Charles Cazabon.\n"); 132 | printf("Licensed under the GNU General Public License version 2 (only).\n"); 133 | printf("\n"); 134 | check_posix_system(); 135 | pagesize = memtester_pagesize(); 136 | pagesizemask = (ptrdiff_t) ~(pagesize - 1); 137 | printf("pagesizemask is 0x%tx\n", pagesizemask); 138 | 139 | /* If MEMTESTER_TEST_MASK is set, we use its value as a mask of which 140 | tests we run. 141 | */ 142 | if (env_testmask = getenv("MEMTESTER_TEST_MASK")) { 143 | errno = 0; 144 | testmask = strtoul(env_testmask, 0, 0); 145 | if (errno) { 146 | fprintf(stderr, "error parsing MEMTESTER_TEST_MASK %s: %s\n", 147 | env_testmask, strerror(errno)); 148 | usage(argv[0]); /* doesn't return */ 149 | } 150 | printf("using testmask 0x%lx\n", testmask); 151 | } 152 | 153 | while ((opt = getopt(argc, argv, "p:d:")) != -1) { 154 | switch (opt) { 155 | case 'p': 156 | errno = 0; 157 | physaddrbase = (off_t) strtoull(optarg, &addrsuffix, 16); 158 | if (errno != 0) { 159 | fprintf(stderr, 160 | "failed to parse physaddrbase arg; should be hex " 161 | "address (0x123...)\n"); 162 | usage(argv[0]); /* doesn't return */ 163 | } 164 | if (*addrsuffix != '\0') { 165 | /* got an invalid character in the address */ 166 | fprintf(stderr, 167 | "failed to parse physaddrbase arg; should be hex " 168 | "address (0x123...)\n"); 169 | usage(argv[0]); /* doesn't return */ 170 | } 171 | if (physaddrbase & (pagesize - 1)) { 172 | fprintf(stderr, 173 | "bad physaddrbase arg; does not start on page " 174 | "boundary\n"); 175 | usage(argv[0]); /* doesn't return */ 176 | } 177 | /* okay, got address */ 178 | use_phys = 1; 179 | break; 180 | case 'd': 181 | if (stat(optarg,&statbuf)) { 182 | fprintf(stderr, "can not use %s as device: %s\n", optarg, 183 | strerror(errno)); 184 | usage(argv[0]); /* doesn't return */ 185 | } else { 186 | if (!S_ISCHR(statbuf.st_mode)) { 187 | fprintf(stderr, "can not mmap non-char device %s\n", 188 | optarg); 189 | usage(argv[0]); /* doesn't return */ 190 | } else { 191 | device_name = optarg; 192 | device_specified = 1; 193 | } 194 | } 195 | break; 196 | default: /* '?' */ 197 | usage(argv[0]); /* doesn't return */ 198 | } 199 | } 200 | 201 | if (device_specified && !use_phys) { 202 | fprintf(stderr, 203 | "for mem device, physaddrbase (-p) must be specified\n"); 204 | usage(argv[0]); /* doesn't return */ 205 | } 206 | 207 | if (optind >= argc) { 208 | fprintf(stderr, "need memory argument, in MB\n"); 209 | usage(argv[0]); /* doesn't return */ 210 | } 211 | 212 | errno = 0; 213 | wantraw = (size_t) strtoul(argv[optind], &memsuffix, 0); 214 | if (errno != 0) { 215 | fprintf(stderr, "failed to parse memory argument"); 216 | usage(argv[0]); /* doesn't return */ 217 | } 218 | switch (*memsuffix) { 219 | case 'G': 220 | case 'g': 221 | memshift = 30; /* gigabytes */ 222 | break; 223 | case 'M': 224 | case 'm': 225 | memshift = 20; /* megabytes */ 226 | break; 227 | case 'K': 228 | case 'k': 229 | memshift = 10; /* kilobytes */ 230 | break; 231 | case 'B': 232 | case 'b': 233 | memshift = 0; /* bytes*/ 234 | break; 235 | case '\0': /* no suffix */ 236 | memshift = 20; /* megabytes */ 237 | break; 238 | default: 239 | /* bad suffix */ 240 | usage(argv[0]); /* doesn't return */ 241 | } 242 | wantbytes_orig = wantbytes = ((size_t) wantraw << memshift); 243 | wantmb = (wantbytes_orig >> 20); 244 | optind++; 245 | if (wantmb > maxmb) { 246 | fprintf(stderr, "This system can only address %llu MB.\n", (ull) maxmb); 247 | exit(EXIT_FAIL_NONSTARTER); 248 | } 249 | if (wantbytes < pagesize) { 250 | fprintf(stderr, "bytes %ld < pagesize %ld -- memory argument too large?\n", 251 | wantbytes, pagesize); 252 | exit(EXIT_FAIL_NONSTARTER); 253 | } 254 | 255 | if (optind >= argc) { 256 | loops = 0; 257 | } else { 258 | errno = 0; 259 | loops = strtoul(argv[optind], &loopsuffix, 0); 260 | if (errno != 0) { 261 | fprintf(stderr, "failed to parse number of loops"); 262 | usage(argv[0]); /* doesn't return */ 263 | } 264 | if (*loopsuffix != '\0') { 265 | fprintf(stderr, "loop suffix %c\n", *loopsuffix); 266 | usage(argv[0]); /* doesn't return */ 267 | } 268 | } 269 | 270 | printf("want %lluMB (%llu bytes)\n", (ull) wantmb, (ull) wantbytes); 271 | buf = NULL; 272 | 273 | if (use_phys) { 274 | memfd = open(device_name, O_RDWR | O_SYNC); 275 | if (memfd == -1) { 276 | fprintf(stderr, "failed to open %s for physical memory: %s\n", 277 | device_name, strerror(errno)); 278 | exit(EXIT_FAIL_NONSTARTER); 279 | } 280 | buf = (void volatile *) mmap(0, wantbytes, PROT_READ | PROT_WRITE, 281 | MAP_SHARED | MAP_LOCKED, memfd, 282 | physaddrbase); 283 | if (buf == MAP_FAILED) { 284 | fprintf(stderr, "failed to mmap %s for physical memory: %s\n", 285 | device_name, strerror(errno)); 286 | exit(EXIT_FAIL_NONSTARTER); 287 | } 288 | 289 | if (mlock((void *) buf, wantbytes) < 0) { 290 | fprintf(stderr, "failed to mlock mmap'ed space\n"); 291 | do_mlock = 0; 292 | } 293 | 294 | bufsize = wantbytes; /* accept no less */ 295 | aligned = buf; 296 | done_mem = 1; 297 | } 298 | 299 | while (!done_mem) { 300 | while (!buf && wantbytes) { 301 | buf = (void volatile *) malloc(wantbytes); 302 | if (!buf) wantbytes -= pagesize; 303 | } 304 | bufsize = wantbytes; 305 | printf("got %lluMB (%llu bytes)", (ull) wantbytes >> 20, 306 | (ull) wantbytes); 307 | fflush(stdout); 308 | if (do_mlock) { 309 | printf(", trying mlock ..."); 310 | fflush(stdout); 311 | if ((size_t) buf % pagesize) { 312 | /* printf("aligning to page -- was 0x%tx\n", buf); */ 313 | aligned = (void volatile *) ((size_t) buf & pagesizemask) + pagesize; 314 | /* printf(" now 0x%tx -- lost %d bytes\n", aligned, 315 | * (size_t) aligned - (size_t) buf); 316 | */ 317 | bufsize -= ((size_t) aligned - (size_t) buf); 318 | } else { 319 | aligned = buf; 320 | } 321 | /* Try mlock */ 322 | if (mlock((void *) aligned, bufsize) < 0) { 323 | switch(errno) { 324 | case EAGAIN: /* BSDs */ 325 | printf("over system/pre-process limit, reducing...\n"); 326 | free((void *) buf); 327 | buf = NULL; 328 | wantbytes -= pagesize; 329 | break; 330 | case ENOMEM: 331 | printf("too many pages, reducing...\n"); 332 | free((void *) buf); 333 | buf = NULL; 334 | wantbytes -= pagesize; 335 | break; 336 | case EPERM: 337 | printf("insufficient permission.\n"); 338 | printf("Trying again, unlocked:\n"); 339 | do_mlock = 0; 340 | free((void *) buf); 341 | buf = NULL; 342 | wantbytes = wantbytes_orig; 343 | break; 344 | default: 345 | printf("failed for unknown reason.\n"); 346 | do_mlock = 0; 347 | done_mem = 1; 348 | } 349 | } else { 350 | printf("locked.\n"); 351 | done_mem = 1; 352 | } 353 | } else { 354 | done_mem = 1; 355 | printf("\n"); 356 | } 357 | } 358 | 359 | if (!do_mlock) fprintf(stderr, "Continuing with unlocked memory; testing " 360 | "will be slower and less reliable.\n"); 361 | 362 | halflen = bufsize / 2; 363 | count = halflen / sizeof(ul); 364 | bufa = (ulv *) aligned; 365 | bufb = (ulv *) ((size_t) aligned + halflen); 366 | 367 | for(loop=1; ((!loops) || loop <= loops); loop++) { 368 | printf("Loop %lu", loop); 369 | if (loops) { 370 | printf("/%lu", loops); 371 | } 372 | printf(":\n"); 373 | printf(" %-20s: ", "Stuck Address"); 374 | fflush(stdout); 375 | if (!test_stuck_address(aligned, bufsize / sizeof(ul))) { 376 | printf("ok\n"); 377 | } else { 378 | exit_code |= EXIT_FAIL_ADDRESSLINES; 379 | } 380 | for (i=0;;i++) { 381 | if (!tests[i].name) break; 382 | /* If using a custom testmask, only run this test if the 383 | bit corresponding to this test was set by the user. 384 | */ 385 | if (testmask && (!((1 << i) & testmask))) { 386 | continue; 387 | } 388 | printf(" %-20s: ", tests[i].name); 389 | if (!tests[i].fp(bufa, bufb, count)) { 390 | printf("ok\n"); 391 | } else { 392 | exit_code |= EXIT_FAIL_OTHERTEST; 393 | } 394 | fflush(stdout); 395 | } 396 | printf("\n"); 397 | fflush(stdout); 398 | } 399 | if (do_mlock) munlock((void *) aligned, bufsize); 400 | printf("Done.\n"); 401 | fflush(stdout); 402 | exit(exit_code); 403 | } 404 | -------------------------------------------------------------------------------- /memtester.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple (yet, for some reason, very effective) memory tester. 3 | * Originally by Simon Kirby 4 | * Version 2 by Charles Cazabon 5 | * Version 3 not publicly released. 6 | * Version 4 rewrite: 7 | * Copyright (C) 2004-2012 Charles Cazabon 8 | * Licensed under the terms of the GNU General Public License version 2 (only). 9 | * See the file COPYING for details. 10 | * 11 | * This file contains the declarations for external variables from the main file. 12 | * See other comments in that file. 13 | * 14 | */ 15 | 16 | #include 17 | 18 | /* extern declarations. */ 19 | 20 | extern int use_phys; 21 | extern off_t physaddrbase; 22 | 23 | -------------------------------------------------------------------------------- /sizes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple but very effective user-space memory tester. 3 | * Originally by Simon Kirby 4 | * Version 2 by Charles Cazabon 5 | * Version 3 not publicly released. 6 | * Version 4 rewrite: 7 | * Copyright (C) 2004-2012 Charles Cazabon 8 | * Licensed under the terms of the GNU General Public License version 2 (only). 9 | * See the file COPYING for details. 10 | * 11 | * This file contains some macro definitions for handling 32/64 bit platforms. 12 | * 13 | */ 14 | 15 | #include 16 | 17 | #define rand32() ((unsigned int) rand() | ( (unsigned int) rand() << 16)) 18 | 19 | #if (ULONG_MAX == 4294967295UL) 20 | #define rand_ul() rand32() 21 | #define UL_ONEBITS 0xffffffff 22 | #define UL_LEN 32 23 | #define CHECKERBOARD1 0x55555555 24 | #define CHECKERBOARD2 0xaaaaaaaa 25 | #define UL_BYTE(x) ((x | x << 8 | x << 16 | x << 24)) 26 | #elif (ULONG_MAX == 18446744073709551615ULL) 27 | #define rand64() (((ul) rand32()) << 32 | ((ul) rand32())) 28 | #define rand_ul() rand64() 29 | #define UL_ONEBITS 0xffffffffffffffffUL 30 | #define UL_LEN 64 31 | #define CHECKERBOARD1 0x5555555555555555 32 | #define CHECKERBOARD2 0xaaaaaaaaaaaaaaaa 33 | #define UL_BYTE(x) (((ul)x | (ul)x<<8 | (ul)x<<16 | (ul)x<<24 | (ul)x<<32 | (ul)x<<40 | (ul)x<<48 | (ul)x<<56)) 34 | #else 35 | #error long on this platform is not 32 or 64 bits 36 | #endif 37 | 38 | 39 | -------------------------------------------------------------------------------- /tests.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple but very effective user-space memory tester. 3 | * Originally by Simon Kirby 4 | * Version 2 by Charles Cazabon 5 | * Version 3 not publicly released. 6 | * Version 4 rewrite: 7 | * Copyright (C) 2004-2012 Charles Cazabon 8 | * Licensed under the terms of the GNU General Public License version 2 (only). 9 | * See the file COPYING for details. 10 | * 11 | * This file contains the functions for the actual tests, called from the 12 | * main routine in memtester.c. See other comments in that file. 13 | * 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "types.h" 22 | #include "sizes.h" 23 | #include "memtester.h" 24 | 25 | char progress[] = "-\\|/"; 26 | #define PROGRESSLEN 4 27 | #define PROGRESSOFTEN 2500 28 | #define ONE 0x00000001L 29 | 30 | /* Function definitions. */ 31 | 32 | int compare_regions(ulv *bufa, ulv *bufb, size_t count) { 33 | int r = 0; 34 | size_t i; 35 | ulv *p1 = bufa; 36 | ulv *p2 = bufb; 37 | off_t physaddr; 38 | 39 | for (i = 0; i < count; i++, p1++, p2++) { 40 | if (*p1 != *p2) { 41 | if (use_phys) { 42 | physaddr = physaddrbase + (i * sizeof(ul)); 43 | fprintf(stderr, 44 | "FAILURE: 0x%08lx != 0x%08lx at physical address " 45 | "0x%08lx.\n", 46 | (ul) *p1, (ul) *p2, physaddr); 47 | } else { 48 | fprintf(stderr, 49 | "FAILURE: 0x%08lx != 0x%08lx at offset 0x%08lx.\n", 50 | (ul) *p1, (ul) *p2, (ul) (i * sizeof(ul))); 51 | } 52 | /* printf("Skipping to next test..."); */ 53 | r = -1; 54 | } 55 | } 56 | return r; 57 | } 58 | 59 | int test_stuck_address(ulv *bufa, size_t count) { 60 | ulv *p1 = bufa; 61 | unsigned int j; 62 | size_t i; 63 | off_t physaddr; 64 | 65 | printf(" "); 66 | fflush(stdout); 67 | for (j = 0; j < 16; j++) { 68 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 69 | p1 = (ulv *) bufa; 70 | printf("setting %3u", j); 71 | fflush(stdout); 72 | for (i = 0; i < count; i++) { 73 | *p1 = ((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1); 74 | *p1++; 75 | } 76 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 77 | printf("testing %3u", j); 78 | fflush(stdout); 79 | p1 = (ulv *) bufa; 80 | for (i = 0; i < count; i++, p1++) { 81 | if (*p1 != (((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1))) { 82 | if (use_phys) { 83 | physaddr = physaddrbase + (i * sizeof(ul)); 84 | fprintf(stderr, 85 | "FAILURE: possible bad address line at physical " 86 | "address 0x%08lx.\n", 87 | physaddr); 88 | } else { 89 | fprintf(stderr, 90 | "FAILURE: possible bad address line at offset " 91 | "0x%08lx.\n", 92 | (ul) (i * sizeof(ul))); 93 | } 94 | printf("Skipping to next test...\n"); 95 | fflush(stdout); 96 | return -1; 97 | } 98 | } 99 | } 100 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 101 | fflush(stdout); 102 | return 0; 103 | } 104 | 105 | int test_random_value(ulv *bufa, ulv *bufb, size_t count) { 106 | ulv *p1 = bufa; 107 | ulv *p2 = bufb; 108 | ul j = 0; 109 | size_t i; 110 | 111 | putchar(' '); 112 | fflush(stdout); 113 | for (i = 0; i < count; i++) { 114 | *p1++ = *p2++ = rand_ul(); 115 | if (!(i % PROGRESSOFTEN)) { 116 | putchar('\b'); 117 | putchar(progress[++j % PROGRESSLEN]); 118 | fflush(stdout); 119 | } 120 | } 121 | printf("\b \b"); 122 | fflush(stdout); 123 | return compare_regions(bufa, bufb, count); 124 | } 125 | 126 | int test_xor_comparison(ulv *bufa, ulv *bufb, size_t count) { 127 | ulv *p1 = bufa; 128 | ulv *p2 = bufb; 129 | size_t i; 130 | ul q = rand_ul(); 131 | 132 | for (i = 0; i < count; i++) { 133 | *p1++ ^= q; 134 | *p2++ ^= q; 135 | } 136 | return compare_regions(bufa, bufb, count); 137 | } 138 | 139 | int test_sub_comparison(ulv *bufa, ulv *bufb, size_t count) { 140 | ulv *p1 = bufa; 141 | ulv *p2 = bufb; 142 | size_t i; 143 | ul q = rand_ul(); 144 | 145 | for (i = 0; i < count; i++) { 146 | *p1++ -= q; 147 | *p2++ -= q; 148 | } 149 | return compare_regions(bufa, bufb, count); 150 | } 151 | 152 | int test_mul_comparison(ulv *bufa, ulv *bufb, size_t count) { 153 | ulv *p1 = bufa; 154 | ulv *p2 = bufb; 155 | size_t i; 156 | ul q = rand_ul(); 157 | 158 | for (i = 0; i < count; i++) { 159 | *p1++ *= q; 160 | *p2++ *= q; 161 | } 162 | return compare_regions(bufa, bufb, count); 163 | } 164 | 165 | int test_div_comparison(ulv *bufa, ulv *bufb, size_t count) { 166 | ulv *p1 = bufa; 167 | ulv *p2 = bufb; 168 | size_t i; 169 | ul q = rand_ul(); 170 | 171 | for (i = 0; i < count; i++) { 172 | if (!q) { 173 | q++; 174 | } 175 | *p1++ /= q; 176 | *p2++ /= q; 177 | } 178 | return compare_regions(bufa, bufb, count); 179 | } 180 | 181 | int test_or_comparison(ulv *bufa, ulv *bufb, size_t count) { 182 | ulv *p1 = bufa; 183 | ulv *p2 = bufb; 184 | size_t i; 185 | ul q = rand_ul(); 186 | 187 | for (i = 0; i < count; i++) { 188 | *p1++ |= q; 189 | *p2++ |= q; 190 | } 191 | return compare_regions(bufa, bufb, count); 192 | } 193 | 194 | int test_and_comparison(ulv *bufa, ulv *bufb, size_t count) { 195 | ulv *p1 = bufa; 196 | ulv *p2 = bufb; 197 | size_t i; 198 | ul q = rand_ul(); 199 | 200 | for (i = 0; i < count; i++) { 201 | *p1++ &= q; 202 | *p2++ &= q; 203 | } 204 | return compare_regions(bufa, bufb, count); 205 | } 206 | 207 | int test_seqinc_comparison(ulv *bufa, ulv *bufb, size_t count) { 208 | ulv *p1 = bufa; 209 | ulv *p2 = bufb; 210 | size_t i; 211 | ul q = rand_ul(); 212 | 213 | for (i = 0; i < count; i++) { 214 | *p1++ = *p2++ = (i + q); 215 | } 216 | return compare_regions(bufa, bufb, count); 217 | } 218 | 219 | int test_solidbits_comparison(ulv *bufa, ulv *bufb, size_t count) { 220 | ulv *p1 = bufa; 221 | ulv *p2 = bufb; 222 | unsigned int j; 223 | ul q; 224 | size_t i; 225 | 226 | printf(" "); 227 | fflush(stdout); 228 | for (j = 0; j < 64; j++) { 229 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 230 | q = (j % 2) == 0 ? UL_ONEBITS : 0; 231 | printf("setting %3u", j); 232 | fflush(stdout); 233 | p1 = (ulv *) bufa; 234 | p2 = (ulv *) bufb; 235 | for (i = 0; i < count; i++) { 236 | *p1++ = *p2++ = (i % 2) == 0 ? q : ~q; 237 | } 238 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 239 | printf("testing %3u", j); 240 | fflush(stdout); 241 | if (compare_regions(bufa, bufb, count)) { 242 | return -1; 243 | } 244 | } 245 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 246 | fflush(stdout); 247 | return 0; 248 | } 249 | 250 | int test_checkerboard_comparison(ulv *bufa, ulv *bufb, size_t count) { 251 | ulv *p1 = bufa; 252 | ulv *p2 = bufb; 253 | unsigned int j; 254 | ul q; 255 | size_t i; 256 | 257 | printf(" "); 258 | fflush(stdout); 259 | for (j = 0; j < 64; j++) { 260 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 261 | q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2; 262 | printf("setting %3u", j); 263 | fflush(stdout); 264 | p1 = (ulv *) bufa; 265 | p2 = (ulv *) bufb; 266 | for (i = 0; i < count; i++) { 267 | *p1++ = *p2++ = (i % 2) == 0 ? q : ~q; 268 | } 269 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 270 | printf("testing %3u", j); 271 | fflush(stdout); 272 | if (compare_regions(bufa, bufb, count)) { 273 | return -1; 274 | } 275 | } 276 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 277 | fflush(stdout); 278 | return 0; 279 | } 280 | 281 | int test_blockseq_comparison(ulv *bufa, ulv *bufb, size_t count) { 282 | ulv *p1 = bufa; 283 | ulv *p2 = bufb; 284 | unsigned int j; 285 | size_t i; 286 | 287 | printf(" "); 288 | fflush(stdout); 289 | for (j = 0; j < 256; j++) { 290 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 291 | p1 = (ulv *) bufa; 292 | p2 = (ulv *) bufb; 293 | printf("setting %3u", j); 294 | fflush(stdout); 295 | for (i = 0; i < count; i++) { 296 | *p1++ = *p2++ = (ul) UL_BYTE(j); 297 | } 298 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 299 | printf("testing %3u", j); 300 | fflush(stdout); 301 | if (compare_regions(bufa, bufb, count)) { 302 | return -1; 303 | } 304 | } 305 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 306 | fflush(stdout); 307 | return 0; 308 | } 309 | 310 | int test_walkbits0_comparison(ulv *bufa, ulv *bufb, size_t count) { 311 | ulv *p1 = bufa; 312 | ulv *p2 = bufb; 313 | unsigned int j; 314 | size_t i; 315 | 316 | printf(" "); 317 | fflush(stdout); 318 | for (j = 0; j < UL_LEN * 2; j++) { 319 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 320 | p1 = (ulv *) bufa; 321 | p2 = (ulv *) bufb; 322 | printf("setting %3u", j); 323 | fflush(stdout); 324 | for (i = 0; i < count; i++) { 325 | if (j < UL_LEN) { /* Walk it up. */ 326 | *p1++ = *p2++ = ONE << j; 327 | } else { /* Walk it back down. */ 328 | *p1++ = *p2++ = ONE << (UL_LEN * 2 - j - 1); 329 | } 330 | } 331 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 332 | printf("testing %3u", j); 333 | fflush(stdout); 334 | if (compare_regions(bufa, bufb, count)) { 335 | return -1; 336 | } 337 | } 338 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 339 | fflush(stdout); 340 | return 0; 341 | } 342 | 343 | int test_walkbits1_comparison(ulv *bufa, ulv *bufb, size_t count) { 344 | ulv *p1 = bufa; 345 | ulv *p2 = bufb; 346 | unsigned int j; 347 | size_t i; 348 | 349 | printf(" "); 350 | fflush(stdout); 351 | for (j = 0; j < UL_LEN * 2; j++) { 352 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 353 | p1 = (ulv *) bufa; 354 | p2 = (ulv *) bufb; 355 | printf("setting %3u", j); 356 | fflush(stdout); 357 | for (i = 0; i < count; i++) { 358 | if (j < UL_LEN) { /* Walk it up. */ 359 | *p1++ = *p2++ = UL_ONEBITS ^ (ONE << j); 360 | } else { /* Walk it back down. */ 361 | *p1++ = *p2++ = UL_ONEBITS ^ (ONE << (UL_LEN * 2 - j - 1)); 362 | } 363 | } 364 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 365 | printf("testing %3u", j); 366 | fflush(stdout); 367 | if (compare_regions(bufa, bufb, count)) { 368 | return -1; 369 | } 370 | } 371 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 372 | fflush(stdout); 373 | return 0; 374 | } 375 | 376 | int test_bitspread_comparison(ulv *bufa, ulv *bufb, size_t count) { 377 | ulv *p1 = bufa; 378 | ulv *p2 = bufb; 379 | unsigned int j; 380 | size_t i; 381 | 382 | printf(" "); 383 | fflush(stdout); 384 | for (j = 0; j < UL_LEN * 2; j++) { 385 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 386 | p1 = (ulv *) bufa; 387 | p2 = (ulv *) bufb; 388 | printf("setting %3u", j); 389 | fflush(stdout); 390 | for (i = 0; i < count; i++) { 391 | if (j < UL_LEN) { /* Walk it up. */ 392 | *p1++ = *p2++ = (i % 2 == 0) 393 | ? (ONE << j) | (ONE << (j + 2)) 394 | : UL_ONEBITS ^ ((ONE << j) 395 | | (ONE << (j + 2))); 396 | } else { /* Walk it back down. */ 397 | *p1++ = *p2++ = (i % 2 == 0) 398 | ? (ONE << (UL_LEN * 2 - 1 - j)) | (ONE << (UL_LEN * 2 + 1 - j)) 399 | : UL_ONEBITS ^ (ONE << (UL_LEN * 2 - 1 - j) 400 | | (ONE << (UL_LEN * 2 + 1 - j))); 401 | } 402 | } 403 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 404 | printf("testing %3u", j); 405 | fflush(stdout); 406 | if (compare_regions(bufa, bufb, count)) { 407 | return -1; 408 | } 409 | } 410 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 411 | fflush(stdout); 412 | return 0; 413 | } 414 | 415 | int test_bitflip_comparison(ulv *bufa, ulv *bufb, size_t count) { 416 | ulv *p1 = bufa; 417 | ulv *p2 = bufb; 418 | unsigned int j, k; 419 | ul q; 420 | size_t i; 421 | 422 | printf(" "); 423 | fflush(stdout); 424 | for (k = 0; k < UL_LEN; k++) { 425 | q = ONE << k; 426 | for (j = 0; j < 8; j++) { 427 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 428 | q = ~q; 429 | printf("setting %3u", k * 8 + j); 430 | fflush(stdout); 431 | p1 = (ulv *) bufa; 432 | p2 = (ulv *) bufb; 433 | for (i = 0; i < count; i++) { 434 | *p1++ = *p2++ = (i % 2) == 0 ? q : ~q; 435 | } 436 | printf("\b\b\b\b\b\b\b\b\b\b\b"); 437 | printf("testing %3u", k * 8 + j); 438 | fflush(stdout); 439 | if (compare_regions(bufa, bufb, count)) { 440 | return -1; 441 | } 442 | } 443 | } 444 | printf("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b"); 445 | fflush(stdout); 446 | return 0; 447 | } 448 | 449 | #ifdef TEST_NARROW_WRITES 450 | int test_8bit_wide_random(ulv* bufa, ulv* bufb, size_t count) { 451 | u8v *p1, *t; 452 | ulv *p2; 453 | int attempt; 454 | unsigned int b, j = 0; 455 | size_t i; 456 | 457 | putchar(' '); 458 | fflush(stdout); 459 | for (attempt = 0; attempt < 2; attempt++) { 460 | if (attempt & 1) { 461 | p1 = (u8v *) bufa; 462 | p2 = bufb; 463 | } else { 464 | p1 = (u8v *) bufb; 465 | p2 = bufa; 466 | } 467 | for (i = 0; i < count; i++) { 468 | t = mword8.bytes; 469 | *p2++ = mword8.val = rand_ul(); 470 | for (b=0; b < UL_LEN/8; b++) { 471 | *p1++ = *t++; 472 | } 473 | if (!(i % PROGRESSOFTEN)) { 474 | putchar('\b'); 475 | putchar(progress[++j % PROGRESSLEN]); 476 | fflush(stdout); 477 | } 478 | } 479 | if (compare_regions(bufa, bufb, count)) { 480 | return -1; 481 | } 482 | } 483 | printf("\b \b"); 484 | fflush(stdout); 485 | return 0; 486 | } 487 | 488 | int test_16bit_wide_random(ulv* bufa, ulv* bufb, size_t count) { 489 | u16v *p1, *t; 490 | ulv *p2; 491 | int attempt; 492 | unsigned int b, j = 0; 493 | size_t i; 494 | 495 | putchar( ' ' ); 496 | fflush( stdout ); 497 | for (attempt = 0; attempt < 2; attempt++) { 498 | if (attempt & 1) { 499 | p1 = (u16v *) bufa; 500 | p2 = bufb; 501 | } else { 502 | p1 = (u16v *) bufb; 503 | p2 = bufa; 504 | } 505 | for (i = 0; i < count; i++) { 506 | t = mword16.u16s; 507 | *p2++ = mword16.val = rand_ul(); 508 | for (b = 0; b < UL_LEN/16; b++) { 509 | *p1++ = *t++; 510 | } 511 | if (!(i % PROGRESSOFTEN)) { 512 | putchar('\b'); 513 | putchar(progress[++j % PROGRESSLEN]); 514 | fflush(stdout); 515 | } 516 | } 517 | if (compare_regions(bufa, bufb, count)) { 518 | return -1; 519 | } 520 | } 521 | printf("\b \b"); 522 | fflush(stdout); 523 | return 0; 524 | } 525 | #endif 526 | -------------------------------------------------------------------------------- /tests.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple yet very effective memory tester. 3 | * Originally by Simon Kirby 4 | * Version 2 by Charles Cazabon 5 | * Version 3 not publicly released. 6 | * Version 4 rewrite: 7 | * Copyright (C) 2004-2012 Charles Cazabon 8 | * Licensed under the terms of the GNU General Public License version 2 (only). 9 | * See the file COPYING for details. 10 | * 11 | * This file contains the declarations for the functions for the actual tests, 12 | * called from the main routine in memtester.c. See other comments in that 13 | * file. 14 | * 15 | */ 16 | 17 | /* Function declaration. */ 18 | 19 | int test_stuck_address(unsigned long volatile *bufa, size_t count); 20 | int test_random_value(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 21 | int test_xor_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 22 | int test_sub_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 23 | int test_mul_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 24 | int test_div_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 25 | int test_or_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 26 | int test_and_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 27 | int test_seqinc_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 28 | int test_solidbits_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 29 | int test_checkerboard_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 30 | int test_blockseq_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 31 | int test_walkbits0_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 32 | int test_walkbits1_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 33 | int test_bitspread_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 34 | int test_bitflip_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 35 | #ifdef TEST_NARROW_WRITES 36 | int test_8bit_wide_random(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 37 | int test_16bit_wide_random(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count); 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /trycpp.c: -------------------------------------------------------------------------------- 1 | void main() 2 | { 3 | #ifdef NeXT 4 | printf("nextstep\n"); exit(0); 5 | #endif 6 | printf("unknown\n"); exit(0); 7 | } 8 | -------------------------------------------------------------------------------- /types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Very simple but very effective user-space memory tester. 3 | * Originally by Simon Kirby 4 | * Version 2 by Charles Cazabon 5 | * Version 3 not publicly released. 6 | * Version 4 rewrite: 7 | * Copyright (C) 2004-2010 Charles Cazabon 8 | * Licensed under the terms of the GNU General Public License version 2 (only). 9 | * See the file COPYING for details. 10 | * 11 | * This file contains typedefs, structure, and union definitions. 12 | * 13 | */ 14 | 15 | #include "sizes.h" 16 | 17 | typedef unsigned long ul; 18 | typedef unsigned long long ull; 19 | typedef unsigned long volatile ulv; 20 | typedef unsigned char volatile u8v; 21 | typedef unsigned short volatile u16v; 22 | 23 | struct test { 24 | char *name; 25 | int (*fp)(); 26 | }; 27 | 28 | union { 29 | unsigned char bytes[UL_LEN/8]; 30 | ul val; 31 | } mword8; 32 | 33 | union { 34 | unsigned short u16s[UL_LEN/16]; 35 | ul val; 36 | } mword16; 37 | -------------------------------------------------------------------------------- /warn-auto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # WARNING: This file was auto-generated. Do not edit! 3 | --------------------------------------------------------------------------------