Merge zizzer.eecs.umich.edu:/bk/newmem

into  zeep.eecs.umich.edu:/home/gblack/m5/newmem

src/cpu/ozone/cpu_impl.hh:
    Hand merged

--HG--
extra : convert_revision : f8a5b0205bcb78c8f5e109f456fe7bca80a7abac
This commit is contained in:
Gabe Black 2006-10-02 14:32:02 -04:00
commit e8ced44aea
87 changed files with 8034 additions and 314 deletions

12
configs/boot/ammp.rcS Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
cd /benchmarks/spec/ammp00/
/sbin/m5 checkpoint 0 0
/sbin/m5 checkpoint 100000000 200000000
/sbin/m5 loadsymbol
/sbin/m5 resetstats
./ammp < input/mdred.in
/sbin/m5 exit

257
configs/boot/ammp.symbol Normal file
View file

@ -0,0 +1,257 @@
000000012001da40 T AMMPmonitor
000000012001dfc0 T AMMPmonitor_mute
0000000120034338 D _DYNAMIC
00000001200346c8 D _GLOBAL_OFFSET_TABLE_
0000000120034d60 G _IO_stdin_used
0000000120034500 T _PROCEDURE_LINKAGE_TABLE_
00000001200344e0 d __CTOR_END__
00000001200344d8 d __CTOR_LIST__
00000001200344f0 d __DTOR_END__
00000001200344e8 d __DTOR_LIST__
0000000120034334 r __FRAME_END__
00000001200344f8 d __JCR_END__
00000001200344f8 d __JCR_LIST__
0000000120034da0 A __bss_start
00000001200328c8 D __data_start
0000000120020c40 t __do_global_ctors_aux
0000000120001090 t __do_global_dtors_aux
0000000120034d68 G __dso_handle
00000001200328c8 A __fini_array_end
00000001200328c8 A __fini_array_start
00000001200328c8 A __init_array_end
00000001200328c8 A __init_array_start
0000000120020ba0 T __libc_csu_fini
0000000120020af0 T __libc_csu_init
0000000120001050 W __start
0000000120034da0 A _edata
0000000120035418 A _end
0000000120020ca0 T _fini
0000000120000fe8 T _init
0000000120001050 T _start
000000012000d220 T a_angle
000000012000b3d0 T a_bond
000000012000e1b0 T a_c_angle
0000000120009cd0 T a_d_zero
0000000120009c90 T a_f_zero
0000000120009f70 T a_ftodx
000000012000a000 T a_ftogx
000000012000a090 T a_ftovx
0000000120009d20 T a_g_zero
0000000120010950 T a_hybrid
000000012000a7c0 T a_inactive_f_zero
0000000120009e50 T a_inc_d
0000000120009dc0 T a_inc_f
0000000120009ee0 T a_inc_v
000000012000a370 T a_l2_d
000000012000a220 T a_l2_f
000000012000a290 T a_l2_g
000000012000a300 T a_l2_v
0000000120008bf0 T a_m_serial
000000012000a1a0 T a_max_d
000000012000a120 T a_max_f
000000012000d570 T a_mmangle
000000012000b620 T a_mmbond
0000000120009c30 T a_next
0000000120005350 T a_noel
0000000120004700 T a_nonbon
0000000120009bc0 T a_number
00000001200096b0 T a_pr_beta
000000012000a660 T a_readvelocity
0000000120020750 T a_restrain
000000012001eda0 T a_tether
000000012001a2e0 T a_torsion
0000000120009d70 T a_v_zero
0000000120003c90 T aaerror
0000000120009a60 T activate
000000012001fef0 T alltether
0000000120004370 T analyze
000000012000c0d0 T angle
0000000120034df8 S angle_first
0000000120034e00 S angle_last
0000000120034dd0 s ap.2
0000000120034de0 s ap.4
0000000120008970 T atom
0000000120034dc8 s atomNUMBER
0000000120034dcc s atomUPDATE
000000012000a8b0 T bond
0000000120034de8 S bond_first
0000000120034df0 S bond_last
000000012000bf20 T bond_length
000000012001f240 T bstrot
0000000120034ea0 b buff.0
000000012001ad40 T cngdel
0000000120034da0 s completed.1
00000001200200c0 T cpyvec
00000001200328c8 W data_start
0000000120034d98 g dielecold.0
000000012000efe0 T dump_angles
0000000120008d00 T dump_atoms
000000012000be40 T dump_bonds
000000012000a3e0 T dump_excludes
000000012000a6c0 T dump_force
0000000120011a50 T dump_hybrids
0000000120005c20 T dump_noels
0000000120008f40 T dump_pdb
0000000120020a10 T dump_restrains
000000012001ffe0 T dump_tethers
0000000120017b30 T dump_tgroup
000000012001a170 T dump_torsions
000000012001b7a0 T dump_variable
000000012000a590 T dump_velocity
0000000120034d7c g echo.0
0000000120001760 T eval
000000012000c580 T f_angle
000000012000ac60 T f_bond
0000000120001230 T f_box
000000012000dc50 T f_c_angle
000000012000ea10 T f_ho_angle
000000012000bab0 T f_ho_bond
0000000120011020 T f_ho_hybrid
0000000120005840 T f_ho_noel
000000012001fca0 T f_ho_tether
00000001200102b0 T f_hybrid
000000012000cd10 T f_mmangle
000000012000b0e0 T f_mmbond
0000000120005060 T f_noel
00000001200155d0 T f_nonbon
0000000120020500 T f_restrain
000000012001ebd0 T f_tether
0000000120019850 T f_torsion
000000012000fbd0 T f_trace
0000000120034db8 S first
0000000120035058 B forces
0000000120001130 t frame_dummy
0000000120014b20 T fv_update_nonbon
0000000120034e58 s fx.0
0000000120034e60 s fy.1
0000000120034e68 s fz.2
000000012000ef40 T get_angle
000000012000bda0 T get_bond
000000012000c050 T get_bond_pointer
000000012001b6e0 T get_f_variable
00000001200119b0 T get_hybrid
000000012001b740 T get_i_variable
0000000120005b80 T get_noel
0000000120020970 T get_restrain
000000012001a9f0 T get_torsion
00000001200184a0 T get_torsion_value
000000012001ca50 T getatomdata
000000012000f130 T gsdg
000000012000e5a0 T gsdg_angle
000000012000bfc0 T gsdg_bond
000000012000f810 T gsdg_dgeom
0000000120011790 T gsdg_hybrid
000000012000f6c0 T gsdg_line_search
0000000120005d30 T gsdg_noel
000000012001a850 T gsdg_torsion
0000000120034d84 g highest.0
0000000120007490 T hpac
000000012000fe30 T hybrid
0000000120034e08 S hybrid_first
0000000120034e10 S hybrid_last
0000000120034e70 S in_mom_list
0000000120009920 T inactivate
00000001200097a0 T inactivate_non_zero
0000000120034d80 g inloop.1
0000000120034e74 s ip.1
0000000120034e78 s jp.2
0000000120034e7c s kp.3
0000000120034dc0 S last
0000000120034dd8 s lastmatched.3
000000012001b0d0 T linmin
0000000120003f80 T loadloop
0000000120034e28 s local.3
0000000120034d88 g lowest.1
0000000120034e20 s lsize.2
0000000120001180 T main
0000000120017c10 T match_tgroup
000000012001b450 T match_variable
000000012001b860 T math
000000012001cd40 T math_findlabel
000000012001ccb0 T math_match_atom
0000000120020100 T matmul
0000000120012b90 T mm_fv_update_nonbon
000000012001cef0 T mom
000000012001d3f0 T mom_add
000000012001d900 T mom_jab
00000001200350f8 B mom_list
000000012001d890 T mom_param
000000012001d600 T mom_solve
0000000120004c70 T noel
0000000120034da8 S noel_first
0000000120034db0 S noel_last
0000000120034d78 G nused
0000000120034e18 s oldatomnumber.0
0000000120034d90 g oldcutoff.4
0000000120034d70 g p.0
0000000120006430 T pac
0000000120006dd0 T pacpac
00000001200350a8 B potentials
0000000120007ac0 T ppac
0000000120008180 T ptpac
000000012001e840 T rand3
000000012001e480 T randf
000000012001e760 T randg
0000000120001550 T read_eval_do
00000001200201c0 T restrain
0000000120034e90 S restrain_first
0000000120034e98 S restrain_last
000000012001b4e0 T set_f_variable
000000012001b5e0 T set_i_variable
0000000120018730 T set_torsion
000000012001e2a0 T significance
0000000120034e1c s since.1
000000012001aa90 T steep
0000000120018f50 T tailor_exclude
0000000120018d30 T tailor_include
0000000120019110 T tailor_qab
000000012001e940 T tether
0000000120034e80 S tether_first
0000000120034e88 S tether_last
00000001200171f0 T tg_apply
0000000120017490 T tg_d_apply
0000000120016fd0 T tg_do_search
0000000120034e30 S tg_first
0000000120017a20 T tg_gen_con
0000000120016b90 T tg_init
0000000120017700 T tg_nonbon
0000000120016220 T tgroup
0000000120004220 T tisint
0000000120003cd0 T tisvariable
00000001200189e0 T tmap
0000000120017ec0 T tmin
0000000120019190 T torsion
0000000120034e38 S torsion_first
0000000120034e40 S torsion_last
0000000120006840 T tpac
0000000120016800 T tsearch
0000000120017c80 T tset
0000000120018200 T tset_bond_build
0000000120012100 T u_f_nonbon
0000000120011b60 T u_v_nonbon
0000000120012770 T uselist
000000012000c310 T v_angle
000000012000aac0 T v_bond
0000000120001540 T v_box
000000012000d930 T v_c_angle
000000012000e750 T v_ho_angle
000000012000b8a0 T v_ho_bond
0000000120010ce0 T v_ho_hybrid
00000001200055e0 T v_ho_noel
000000012001faf0 T v_ho_tether
000000012000fff0 T v_hybrid
0000000120005dc0 T v_maxwell
000000012000ca20 T v_mmangle
000000012000aef0 T v_mmbond
0000000120004e60 T v_noel
0000000120015a80 T v_nonbon
0000000120005fd0 T v_rescale
0000000120020360 T v_restrain
000000012001eab0 T v_tether
00000001200193e0 T v_torsion
000000012000f990 T v_trace
000000012001c6f0 T validatom
0000000120034e48 S variableFIRST
0000000120034e50 S variableLAST
00000001200061a0 T verlet
0000000120015ec0 T zone_nonbon

7
configs/boot/art.rcS Normal file
View file

@ -0,0 +1,7 @@
#!/bin/sh
#/benchmarks/spec/art00/art -scanfile c756hel.in -trainfile1 a10.img -stride 2 -startx 134 -starty 220 -endx 184 -endy 240 -objects 3
cd /benchmarks/spec/art00/
/sbin/m5 resetstats
/benchmarks/spec/art00/art -scanfile c756hel.in -trainfile1 a10.img -stride 5 -startx 134 -starty 220 -endx 184 -endy 240 -objects 1
/sbin/m5 exit

13
configs/boot/bonnie.rcS Normal file
View file

@ -0,0 +1,13 @@
#!/bin/sh
#
# /etc/init.d/rcS
#
echo -n "Mounting empty disk..."
mkdir /tmp-space
/bin/mount /dev/hdb1 /tmp-space
chmod a+rwx /tmp-space
echo "done."
/bin/bonnie++ -u 99 -s 700 -r 0 -n 0 -f -F -d /tmp-space
m5 exit

309
configs/boot/bonnie.symbol Normal file
View file

@ -0,0 +1,309 @@
0000000120025cb0 V DW.ref._ZTISt9bad_alloc
0000000120025c98 V DW.ref.__gxx_personality_v0
0000000120025018 D _DYNAMIC
00000001200255a0 D _GLOBAL_OFFSET_TABLE_
0000000120025c80 G _IO_stdin_used
00000001200251e0 T _PROCEDURE_LINKAGE_TABLE_
000000012000e8a0 T _Unwind_Backtrace
000000012000e860 T _Unwind_DeleteException
000000012000c290 T _Unwind_FindEnclosingFunction
0000000120010df0 T _Unwind_Find_FDE
0000000120010850 t _Unwind_Find_registered_FDE
000000012000e470 T _Unwind_ForcedUnwind
000000012000e340 t _Unwind_ForcedUnwind_Phase2
000000012000c260 T _Unwind_GetCFA
000000012000c2d0 T _Unwind_GetDataRelBase
000000012000e9d0 T _Unwind_GetGR
000000012000e9f0 T _Unwind_GetIP
000000012000c270 T _Unwind_GetLanguageSpecificData
000000012000c280 T _Unwind_GetRegionStart
000000012000c2e0 T _Unwind_GetTextRelBase
0000000120010ac0 t _Unwind_IteratePhdrCallback
000000012000e160 T _Unwind_RaiseException
000000012000e070 t _Unwind_RaiseException_Phase2
000000012000e5c0 T _Unwind_Resume
000000012000e710 T _Unwind_Resume_or_Rethrow
000000012000e9e0 T _Unwind_SetGR
000000012000ea00 T _Unwind_SetIP
0000000120003cb0 T _Z10TestDirOpsiiiiR12CGlobalItems
0000000120003220 T _Z11TestFileOpsiR12CGlobalItems
0000000120009250 T _Z11bon_setugidPKcS0_b
00000001200096b4 t _Z12read_sleb128PKhPl
0000000120009678 t _Z12read_uleb128PKhPm
0000000120009a04 t _Z15get_ttype_entryP16lsda_header_infom
0000000120009a84 t _Z16get_adjusted_ptrPKSt9type_infoS1_PPv
000000012000ab40 t _Z16get_globals_dtorPv
000000012000ab9c t _Z16get_globals_initv
00000001200098a8 t _Z17parse_lsda_headerP15_Unwind_ContextPKhP16lsda_header_info
0000000120009b30 t _Z20check_exception_specP16lsda_header_infoPKSt9type_infoPvl
0000000120009be0 t _Z20empty_exception_specP16lsda_header_infol
00000001200095b4 t _Z21base_of_encoded_valuehP15_Unwind_Context
000000012000abe0 t _Z21get_globals_init_oncev
0000000120009548 t _Z21size_of_encoded_valueh
000000012000a3ec t _Z23__gxx_exception_cleanup19_Unwind_Reason_CodeP17_Unwind_Exception
000000012000970c t _Z28read_encoded_value_with_basehmPKhPm
0000000120004200 T _Z5usagev
0000000120004510 T _Z6seekerP4ForkPvi
0000000120004240 T _Z8io_errorPKcb
000000012000a310 T _ZN10__cxxabiv111__terminateEPFvvE
000000012000a374 T _ZN10__cxxabiv112__unexpectedEPFvvE
000000012000b08c T _ZN10__cxxabiv117__class_type_infoD0Ev
000000012000b058 T _ZN10__cxxabiv117__class_type_infoD1Ev
000000012000b024 T _ZN10__cxxabiv117__class_type_infoD2Ev
0000000120025ca0 G _ZN10__cxxabiv119__terminate_handlerE
000000012000b148 T _ZN10__cxxabiv120__si_class_type_infoD0Ev
000000012000b114 T _ZN10__cxxabiv120__si_class_type_infoD1Ev
000000012000b0e0 T _ZN10__cxxabiv120__si_class_type_infoD2Ev
0000000120025ca8 G _ZN10__cxxabiv120__unexpected_handlerE
000000012000b204 T _ZN10__cxxabiv121__vmi_class_type_infoD0Ev
000000012000b1d0 T _ZN10__cxxabiv121__vmi_class_type_infoD1Ev
000000012000b19c T _ZN10__cxxabiv121__vmi_class_type_infoD2Ev
00000001200024b0 T _ZN12CGlobalItems18decrement_and_waitEi
0000000120002380 T _ZN12CGlobalItemsC1EPb
0000000120002250 T _ZN12CGlobalItemsC2EPb
0000000120008de0 T _ZN4Fork2goEPFvPS_PviES1_i
0000000120009080 T _ZN4Fork4ReadEPvii
0000000120009010 T _ZN4Fork4waitEv
0000000120009160 T _ZN4Fork5WriteEPvii
0000000120008d60 T _ZN4Fork7startitEP11THREAD_DATA
0000000120008d40 T _ZN4ForkC1Ev
0000000120008d20 T _ZN4ForkC2Ev
0000000120004cd0 T _ZN7CFileOp10read_blockEPv
0000000120004f90 T _ZN7CFileOp11write_blockEPv
0000000120004e70 T _ZN7CFileOp15read_block_getcEPc
0000000120005080 T _ZN7CFileOp16write_block_putcEv
0000000120005180 T _ZN7CFileOp4openEPKcbb
0000000120004a40 T _ZN7CFileOp4seekEii
0000000120005770 T _ZN7CFileOp5closeEv
0000000120005910 T _ZN7CFileOp6doseekElb
0000000120005630 T _ZN7CFileOp6m_openEPKcib
0000000120005430 T _ZN7CFileOp6reopenEbb
0000000120004760 T _ZN7CFileOp9seek_testEbR9Semaphore
0000000120005330 T _ZN7CFileOpC1ER8BonTimeriib
0000000120005230 T _ZN7CFileOpC2ER8BonTimeriib
0000000120004400 T _ZN7CFileOpD1Ev
00000001200042f0 T _ZN7CFileOpD2Ev
0000000120007b40 T _ZN8BonTimer10InitializeEv
0000000120007820 T _ZN8BonTimer10cpu_so_farEv
0000000120007c80 T _ZN8BonTimer10print_statE7tests_t
0000000120007f80 T _ZN8BonTimer11PrintHeaderEP8_IO_FILE
00000001200078f0 T _ZN8BonTimer11get_cpu_useEv
0000000120007970 T _ZN8BonTimer11get_delta_tE7tests_t
00000001200077e0 T _ZN8BonTimer11time_so_farEv
0000000120007860 T _ZN8BonTimer12get_cur_timeEv
0000000120007b70 T _ZN8BonTimer14print_cpu_statE7tests_t
0000000120007e40 T _ZN8BonTimer15print_file_statE7tests_t
0000000120007a10 T _ZN8BonTimer16add_delta_reportER8report_s7tests_t
00000001200079c0 T _ZN8BonTimer16get_delta_reportER8report_s
0000000120008030 T _ZN8BonTimer8DoReportEPKciiiiiiP8_IO_FILE
0000000120007790 T _ZN8BonTimer9timestampEv
0000000120007b00 T _ZN8BonTimerC1Ev
0000000120007ac0 T _ZN8BonTimerC2Ev
00000001200061a0 T _ZN9COpenTest10make_namesEb
0000000120005bf0 T _ZN9COpenTest11random_sortEv
0000000120007400 T _ZN9COpenTest11stat_randomER8BonTimer
0000000120006520 T _ZN9COpenTest13create_a_fileEPKcPcii
0000000120006710 T _ZN9COpenTest13create_a_linkEPKcS1_i
0000000120006c50 T _ZN9COpenTest13delete_randomER8BonTimer
00000001200074c0 T _ZN9COpenTest15stat_sequentialER8BonTimer
0000000120006f10 T _ZN9COpenTest17delete_sequentialER8BonTimer
0000000120006830 T _ZN9COpenTest6createEPKcR8BonTimeriiiib
0000000120007280 T _ZN9COpenTest9stat_fileEPKc
0000000120005b50 T _ZN9COpenTestC1EibPb
0000000120005ab0 T _ZN9COpenTestC2EibPb
0000000120005f40 T _ZN9COpenTestD1Ev
0000000120005ce0 T _ZN9COpenTestD2Ev
0000000120008aa0 T _ZN9Semaphore18decrement_and_waitEi
0000000120008920 T _ZN9Semaphore6createEi
0000000120008850 T _ZN9Semaphore9clear_semEv
0000000120008be0 T _ZN9Semaphore9get_mutexEv
0000000120008a10 T _ZN9Semaphore9get_semidEv
0000000120008c80 T _ZN9Semaphore9put_mutexEv
00000001200087d0 T _ZN9SemaphoreC1Eiii
0000000120008750 T _ZN9SemaphoreC2Eiii
000000012000b258 T _ZNK10__cxxabiv117__class_type_info10__do_catchEPKSt9type_infoPPvj
000000012000ba74 T _ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PKvRNS0_15__upcast_resultE
000000012000b2b8 T _ZNK10__cxxabiv117__class_type_info11__do_upcastEPKS0_PPv
000000012000b4c0 T _ZNK10__cxxabiv117__class_type_info12__do_dyncastElNS0_10__sub_kindEPKS0_PKvS3_S5_RNS0_16__dyncast_resultE
000000012000b330 T _ZNK10__cxxabiv117__class_type_info20__do_find_public_srcElPKvPKS0_S2_
000000012000baa4 T _ZNK10__cxxabiv120__si_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE
000000012000b510 T _ZNK10__cxxabiv120__si_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE
000000012000b340 T _ZNK10__cxxabiv120__si_class_type_info20__do_find_public_srcElPKvPKNS_17__class_type_infoES2_
000000012000bb38 T _ZNK10__cxxabiv121__vmi_class_type_info11__do_upcastEPKNS_17__class_type_infoEPKvRNS1_15__upcast_resultE
000000012000b5c4 T _ZNK10__cxxabiv121__vmi_class_type_info12__do_dyncastElNS_17__class_type_info10__sub_kindEPKS1_PKvS4_S6_RNS1_16__dyncast_resultE
000000012000b394 T _ZNK10__cxxabiv121__vmi_class_type_info20__do_find_public_srcElPKvPKNS_17__class_type_infoES2_
000000012000ab30 T _ZNKSt9exception4whatEv
000000012000b00c T _ZNKSt9type_info10__do_catchEPKS_PPvj
000000012000b01c T _ZNKSt9type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv
000000012000affc T _ZNKSt9type_info14__is_pointer_pEv
000000012000b004 T _ZNKSt9type_info15__is_function_pEv
000000012000afa8 T _ZNSt10bad_typeidD0Ev
000000012000af74 T _ZNSt10bad_typeidD1Ev
000000012000af40 T _ZNSt10bad_typeidD2Ev
000000012000aadc T _ZNSt13bad_exceptionD0Ev
000000012000aaa8 T _ZNSt13bad_exceptionD1Ev
000000012000aa74 T _ZNSt13bad_exceptionD2Ev
000000012000aeec T _ZNSt8bad_castD0Ev
000000012000aeb8 T _ZNSt8bad_castD1Ev
000000012000ae84 T _ZNSt8bad_castD2Ev
000000012000add4 T _ZNSt9bad_allocD0Ev
000000012000ada0 T _ZNSt9bad_allocD1Ev
000000012000ad6c T _ZNSt9bad_allocD2Ev
000000012000aa40 T _ZNSt9exceptionD0Ev
000000012000aa2c T _ZNSt9exceptionD1Ev
000000012000aa18 T _ZNSt9exceptionD2Ev
000000012000ae50 T _ZNSt9type_infoD0Ev
000000012000ae3c T _ZNSt9type_infoD1Ev
000000012000ae28 T _ZNSt9type_infoD2Ev
000000012000a39c T _ZSt10unexpectedv
000000012000a3bc T _ZSt13set_terminatePFvvE
000000012000a3d4 T _ZSt14set_unexpectedPFvvE
000000012000ad54 T _ZSt15set_new_handlerPFvvE
000000012000a9e4 T _ZSt18uncaught_exceptionv
0000000120025cd0 G _ZSt7nothrow
000000012000a354 T _ZSt9terminatev
00000001200127d8 V _ZTIN10__cxxabiv117__class_type_infoE
00000001200127f0 V _ZTIN10__cxxabiv120__si_class_type_infoE
0000000120012808 V _ZTIN10__cxxabiv121__vmi_class_type_infoE
00000001200127c0 V _ZTISt10bad_typeid
0000000120012578 V _ZTISt13bad_exception
00000001200127a8 V _ZTISt8bad_cast
00000001200125d8 V _ZTISt9bad_alloc
0000000120012568 V _ZTISt9exception
0000000120012798 V _ZTISt9type_info
000000012001286b V _ZTSN10__cxxabiv117__class_type_infoE
0000000120012846 V _ZTSN10__cxxabiv120__si_class_type_infoE
0000000120012820 V _ZTSN10__cxxabiv121__vmi_class_type_infoE
000000012001288d V _ZTSSt10bad_typeid
0000000120012590 V _ZTSSt13bad_exception
000000012001289c V _ZTSSt8bad_cast
00000001200125f0 V _ZTSSt9bad_alloc
00000001200125a2 V _ZTSSt9exception
00000001200128a8 V _ZTSSt9type_info
00000001200126b0 V _ZTVN10__cxxabiv117__class_type_infoE
0000000120012658 V _ZTVN10__cxxabiv120__si_class_type_infoE
0000000120012600 V _ZTVN10__cxxabiv121__vmi_class_type_infoE
0000000120012708 V _ZTVSt10bad_typeid
0000000120012518 V _ZTVSt13bad_exception
0000000120012730 V _ZTVSt8bad_cast
00000001200125b0 V _ZTVSt9bad_alloc
0000000120012540 V _ZTVSt9exception
0000000120012758 V _ZTVSt9type_info
0000000120025cb8 g _ZZ18__gthread_active_pvE20__gthread_active_ptr
0000000120025cc8 g _ZZ18__gthread_active_pvE20__gthread_active_ptr
0000000120025cc4 g _ZZ21get_globals_init_oncevE4once
0000000120009518 T _ZdlPv
000000012000a648 T _Znam
000000012000a580 T _Znwm
00000001200251c0 d __CTOR_END__
00000001200251b8 d __CTOR_LIST__
00000001200251d0 d __DTOR_END__
00000001200251c8 d __DTOR_LIST__
0000000120024f30 r __FRAME_END__
00000001200251d8 d __JCR_END__
00000001200251d8 d __JCR_LIST__
0000000120025ce8 A __bss_start
000000012000a694 T __cxa_allocate_exception
000000012000a884 T __cxa_begin_catch
000000012000a19c T __cxa_call_unexpected
000000012000a930 T __cxa_end_catch
000000012000a7b4 T __cxa_free_exception
000000012000ac84 T __cxa_get_globals
000000012000ac3c T __cxa_get_globals_fast
000000012000a4f8 T __cxa_rethrow
000000012000a45c T __cxa_throw
0000000120024000 D __data_start
000000012000fa50 T __deregister_frame
000000012000fa20 T __deregister_frame_info
000000012000f8c0 T __deregister_frame_info_bases
0000000120011470 t __do_global_ctors_aux
0000000120002160 t __do_global_dtors_aux
0000000120025c88 G __dso_handle
000000012000bd74 T __dynamic_cast
0000000120024000 A __fini_array_end
0000000120024000 A __fini_array_start
000000012000d250 T __frame_state_for
0000000120025ce0 g __gthread_active_ptr.0
0000000120025cd8 g __gthread_active_ptr.1
0000000120009c28 T __gxx_personality_v0
0000000120024000 A __init_array_end
0000000120024000 A __init_array_start
00000001200113e0 T __libc_csu_fini
0000000120011350 T __libc_csu_init
0000000120025d00 S __new_handler
000000012000f6f0 T __register_frame
000000012000f6b0 T __register_frame_info
000000012000f5f0 T __register_frame_info_bases
000000012000f820 T __register_frame_info_table
000000012000f760 T __register_frame_info_table_bases
000000012000f860 T __register_frame_table
0000000120002120 W __start
0000000120025ce8 A _edata
0000000120035db0 A _end
00000001200114d0 T _fini
00000001200020b0 T _init
0000000120002120 T _start
0000000120010250 t add_fdes
0000000120025cea s already_printed_error
00000001200094b0 T arm
0000000120010a30 t base_from_cb_data
000000012000fab0 t base_from_object
000000012000bf50 t base_of_encoded_value
00000001200094f8 T checkpoint
00000001200100e0 t classify_object_over_fdes
0000000120025ce8 s completed.1
00000001200024f0 T ctrl_c_handler
0000000120024000 W data_start
0000000120009508 T debugbreak
00000001200094e8 T dump_stats
00000001200094f0 T dumpreset_stats
0000000120035d40 b dwarf_reg_size_table
0000000120025d30 b emergency_buffer
0000000120024008 d emergency_mutex
0000000120025cf0 s emergency_used
000000012000caa0 t execute_cfa_program
000000012000c520 t execute_stack_op
0000000120025ce9 s exitNow
000000012000c2f0 t extract_cie_info
000000012000fd20 t fde_mixed_encoding_compare
000000012000fc60 t fde_single_encoding_compare
00000001200111d0 t fde_split
000000012000fc30 t fde_unencoded_compare
0000000120002200 t frame_dummy
000000012000fe00 t frame_heapsort
000000012000fb40 t get_cie_encoding
0000000120025cf8 s globals_key
0000000120035d30 b globals_static
000000012000ea10 t init_dwarf_reg_size_table
0000000120010e90 t init_object
00000001200094d8 T initparam
00000001200094c0 T ivlb
00000001200094c8 T ivle
00000001200103d0 t linear_search_fdes
00000001200094d0 T m5exit
0000000120002590 T main
0000000120025d10 s marker.1
0000000120035d88 b object_mutex
0000000120025d08 s once_regsizes.0
0000000120025c90 g p.0
00000001200094b8 T quiesce
000000012000c0d0 t read_encoded_value_with_base
000000012000f460 t read_encoded_value_with_base
000000012000c060 t read_sleb128
000000012000f3f0 t read_sleb128
000000012000c020 t read_uleb128
000000012000f3b0 t read_uleb128
0000000120009500 T readfile
00000001200094e0 T reset_stats
0000000120010560 t search_object
0000000120025d20 s seen_objects
000000012000bed0 t size_of_encoded_value
000000012000f330 t size_of_encoded_value
0000000120009510 T switchcpu
0000000120025d18 s unseen_objects
0000000120025cc0 g use_thread_key
000000012000cf90 t uw_frame_state_for
000000012000d590 t uw_init_context_1
000000012000d650 t uw_install_context_1
000000012000d540 t uw_update_context
000000012000d390 t uw_update_context_1

6
configs/boot/bzip.rcS Normal file
View file

@ -0,0 +1,6 @@
#!/bin/sh
cd /benchmarks/spec/bzip200/
/sbin/m5 resetstats
/benchmarks/spec/bzip200/bzip2 lgred.graphic 1
/sbin/m5 exit

3454
configs/boot/cc1.symbol Normal file

File diff suppressed because it is too large Load diff

12
configs/boot/equake.rcS Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
cd /benchmarks/spec/equake00/
/sbin/m5 checkpoint 0 0
/sbin/m5 checkpoint 100000000 200000000
/sbin/m5 loadsymbol
/sbin/m5 resetstats
/benchmarks/spec/equake00/equake < lgred.in
/sbin/m5 exit

View file

@ -0,0 +1,94 @@
000000012001a868 S ARCHcholeskylen
000000012001a878 S ARCHcoord
000000012001a930 S ARCHcorners
000000012001a938 S ARCHduration
000000012001a940 S ARCHelems
000000012001a8b0 S ARCHglobalelem
000000012001a8d0 S ARCHglobalelems
000000012001a8e8 S ARCHglobalnode
000000012001a8a8 S ARCHglobalnodes
000000012001a8d8 S ARCHmatrixcol
000000012001a898 S ARCHmatrixindex
000000012001a924 S ARCHmatrixlen
000000012001a8ac S ARCHmesh_dim
000000012001a8f8 S ARCHmine
000000012001a90c S ARCHnodes
000000012001a908 S ARCHpriv
000000012001a920 S ARCHsubdomains
000000012001a8b8 S ARCHvertex
000000012001a900 S C
000000012001a918 S C23
000000012001a9a8 B Damp
000000012001a9c8 B Exc
000000012001a8a0 S K
000000012001a928 S M
000000012001a888 S M23
000000012001a950 B Src
000000012001a890 S V23
000000012001a388 D _DYNAMIC
000000012001a5f8 D _GLOBAL_OFFSET_TABLE_
000000012001a848 G _IO_stdin_used
000000012001a550 T _PROCEDURE_LINKAGE_TABLE_
000000012001a530 d __CTOR_END__
000000012001a528 d __CTOR_LIST__
000000012001a540 d __DTOR_END__
000000012001a538 d __DTOR_LIST__
000000012001a384 r __FRAME_END__
000000012001a548 d __JCR_END__
000000012001a548 d __JCR_LIST__
000000012001a860 A __bss_start
000000012001a000 D __data_start
0000000120008c50 t __do_global_ctors_aux
00000001200008d0 t __do_global_dtors_aux
000000012001a850 G __dso_handle
000000012001a000 A __fini_array_end
000000012001a000 A __fini_array_start
000000012001a000 A __init_array_end
000000012001a000 A __init_array_start
0000000120008bb0 T __libc_csu_fini
0000000120008b00 T __libc_csu_init
0000000120000890 W __start
000000012001a860 A _edata
000000012001a9e0 A _end
0000000120008cb0 T _fini
0000000120000828 T _init
0000000120000890 T _start
00000001200049c4 T abe_matrix
00000001200056b8 T arch_bail
00000001200056e4 T arch_info
0000000120006584 T arch_init
00000001200057e0 T arch_parsecommandline
0000000120005bf4 T arch_readdouble
0000000120005ad0 T arch_readelemvector
00000001200059ac T arch_readnodevector
0000000120004530 T area_triangle
00000001200051e8 T centroid
000000012001a860 s completed.1
000000012001a000 W data_start
000000012001a948 S disp
00000001200050bc T distance
0000000120003c70 T element_matrices
0000000120000970 t frame_dummy
00000001200036f8 T get_Enu
0000000120003820 T inv_J
00000001200009c0 T main
0000000120007a88 T mem_init
00000001200054b8 T mv12x12
000000012001a8c0 S nodekind
000000012001a910 S nodekindf
000000012001a8f0 S options
000000012001a858 g p.0
000000012001a8c8 S packfile
0000000120004bc4 T phi0
0000000120004cc4 T phi1
0000000120004d98 T phi2
00000001200052e8 T point2fault
000000012001a870 S progname
0000000120005cd8 T readpackfile
000000012000360c T shape_ders
0000000120004e84 T slip
0000000120006604 T smvp
00000001200070f8 T smvp_opt
000000012001a880 S source_elms
000000012001a8e0 S vel
000000012000561c T vv12x12

12
configs/boot/gcc.rcS Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
cd /benchmarks/spec/gcc00/
/sbin/m5 checkpoint 0 0
/sbin/m5 checkpoint 100000000 200000000
/sbin/m5 loadsymbol
/sbin/m5 resetstats
./cc1 mdred.rtlanal.i
/sbin/m5 exit

12
configs/boot/gzip.rcS Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
cd /benchmarks/spec/gzip00/
/sbin/m5 checkpoint 0 0
/sbin/m5 checkpoint 100000000 200000000
/sbin/m5 loadsymbol
/sbin/m5 resetstats
./gzip lgred.log 1
/sbin/m5 exit

268
configs/boot/gzip.symbol Normal file
View file

@ -0,0 +1,268 @@
0000000120022c08 D _DYNAMIC
0000000120022fd0 D _GLOBAL_OFFSET_TABLE_
0000000120023498 G _IO_stdin_used
0000000120022dc0 T _PROCEDURE_LINKAGE_TABLE_
0000000120022da0 d __CTOR_END__
0000000120022d98 d __CTOR_LIST__
0000000120022db0 d __DTOR_END__
0000000120022da8 d __DTOR_LIST__
0000000120022c04 r __FRAME_END__
0000000120022db8 d __JCR_END__
0000000120022db8 d __JCR_LIST__
00000001200234f8 A __bss_start
0000000120021030 D __data_start
000000012000fbc0 t __do_global_ctors_aux
00000001200012a0 t __do_global_dtors_aux
00000001200234a0 G __dso_handle
0000000120021030 A __fini_array_end
0000000120021030 A __fini_array_start
0000000120021030 A __init_array_end
0000000120021030 A __init_array_start
000000012000fb20 T __libc_csu_fini
000000012000fa70 T __libc_csu_init
0000000120001260 W __start
00000001200234f8 A _edata
0000000120073b10 A _end
000000012000fc20 T _fini
00000001200011f8 T _init
0000000120001260 T _start
0000000120004cf0 T abort_gzip
000000012000de80 T add_envopt
0000000120023550 S args
0000000120023520 S ascii
000000012002551c b base_dist
00000001200254a8 b base_length
0000000120023698 S bb
00000001200234fc s bi_buf
0000000120001ad0 T bi_init
0000000120001b20 T bi_reverse
0000000120023500 s bi_valid
00000001200015d0 T bi_windup
00000001200235b8 s bitbuf
00000001200235e0 s bitbuf
00000001200235c0 s bitcount
0000000120023690 S bk
0000000120024654 b bl_count
0000000120021830 d bl_desc
0000000120021858 d bl_order
00000001200245b8 b bl_tree
00000001200234ec G block_mode
0000000120023610 S block_start
00000001200235b4 s blocksize
0000000120021540 d border
0000000120009620 t build_tree
0000000120023650 S bytes_in
0000000120023668 S bytes_out
0000000120004740 t check_ofname
000000012000d5c0 T check_zipfile
000000012000e540 T clear_bufs
00000001200234f8 s completed.1
0000000120023518 s compr_level
00000001200092e0 t compress_block
00000001200235a0 s compressed_len
0000000120021030 d configuration_table
000000012000e280 T copy
00000001200017d0 T copy_block
0000000120004ae0 t copy_stat
0000000120021644 d cpdext
0000000120021608 d cpdist
000000012002158c d cplens
00000001200215ca d cplext
00000001200235f8 s crc
00000001200234f0 g crc.0
0000000120021870 D crc_32_tab
0000000120002b90 t create_outfile
0000000120008450 T ct_init
0000000120008f60 T ct_tally
000000012002ea20 B d_buf
0000000120021808 d d_desc
0000000120021030 W data_start
00000001200234e8 G dbglvl
00000001200234e4 G dbits
0000000120008440 T debug_time
000000012000a5e0 t decode
000000012000ad50 t decode_c
000000012000ab90 t decode_start
0000000120023528 S decompress
00000001200236c0 S decrypt
0000000120002250 T deflate
0000000120002770 t deflate_fast
0000000120024f68 b depth
000000012000ee70 T display_ratio
00000001200252a5 b dist_code
0000000120004c60 t do_exit
0000000120003f00 t do_list
0000000120023540 S do_lzw
00000001200235c8 s done
0000000120023fcc b dyn_dtree
00000001200236d8 b dyn_ltree
0000000120023678 S env
000000012002350c s eofile
000000012000e1c0 T error
0000000120023548 S exit_code
00000001200235f4 S ext_header
0000000120021794 d extra_blbits
000000012002171c d extra_dbits
00000001200216a8 d extra_lbits
00000001200236b8 S file_method
000000012000f9c0 T file_read
00000001200236b0 S file_type
000000012000e580 T fill_inbuf
0000000120002030 t fill_window
00000001200234d8 g first_time.2
000000012002358d s flag_bit
0000000120025594 b flag_buf
000000012002358c s flags
0000000120008ba0 T flush_block
000000012000e730 T flush_outbuf
000000012000e860 T flush_window
000000012002352c S force
0000000120023640 S foreground
0000000120001340 t frame_dummy
000000012000a1a0 t gen_bitlen
0000000120008a80 t gen_codes
0000000120002dd0 t get_istat
00000001200032c0 T get_method
0000000120004d50 t get_suffix
0000000120023618 S good_match
000000012000ebf0 T gzipbasename
00000001200236d0 S header_bytes
0000000120024674 b heap
0000000120023578 s heap_len
000000012002357c s heap_max
00000001200214b8 d help_msg.5
0000000120004ee0 T huft_build
0000000120005670 T huft_free
00000001200236a0 S hufts
00000001200235b0 s i.0
0000000120023688 S ifd
0000000120023658 S ifile_size
000000012005eea8 B ifname
000000012002356c s in_exit.4
00000001200269e0 B inbuf
0000000120006e00 T inflate
0000000120006bf0 T inflate_block
00000001200056d0 T inflate_codes
00000001200062b0 T inflate_dynamic
00000001200060f0 T inflate_fixed
0000000120005e10 T inflate_stored
0000000120008960 t init_block
0000000120023684 S inptr
00000001200235a8 s input_len
0000000120023508 s ins_h
0000000120023644 S insize
000000012003ea20 B istat
00000001200235c4 s j
00000001200236c8 S key
00000001200213f8 d known_suffixes.0
00000001200217e0 d l_desc
0000000120023584 s last_dist
0000000120023588 s last_flags
0000000120023580 s last_lit
000000012002364c S last_member
00000001200234e0 G lbits
0000000120026910 b leaves
00000001200251a5 b length_code
00000001200234c8 G level
0000000120021080 d license_msg
0000000120023534 S list
00000001200268a8 b lit_base
00000001200267a8 b literal
0000000120001b60 T lm_init
0000000120001d90 T longest_match
00000001200210f8 D longopts
0000000120023510 s lookahead
0000000120006ed0 T lzw
0000000120007a80 T main
0000000120003040 t make_ofname
000000012000ec40 T make_simple_name
000000012000c130 t make_table
0000000120021680 D mask_bits
0000000120023624 S match_start
000000012002361c S max_chain_length
0000000120023514 s max_lazy_match
00000001200235d8 s max_len
00000001200234c0 G maxbits
00000001200234c4 G method
0000000120021470 d methods.3
0000000120023570 s msg_done
0000000120004310 t name_too_long
0000000120023608 S nice_match
00000001200234b8 G no_name
00000001200234bc G no_time
0000000120023630 S ofd
000000012003eaa8 B ofname
0000000120023590 s opt_len
00000001200235d0 s orig_len
000000012005f2a8 B outbuf
0000000120023648 S outcnt
00000001200234a8 g p.0
0000000120026978 b parents
0000000120023680 S part_nb
00000001200235dc s peek_bits
00000001200235f0 S pkzip
000000012003eea8 B prev
000000012002360c S prev_length
0000000120023628 S progname
0000000120026594 b pt_len
00000001200265a8 b pt_table
000000012002353c S quiet
00000001200080c0 T ran
0000000120023600 S read_buf
000000012000b8c0 t read_c_len
000000012000ed50 T read_error
000000012000b130 t read_pt_len
000000012000d2a0 t read_tree
0000000120023530 S recursive
0000000120023568 S remove_ofname
0000000120023660 S save_orig_name
0000000120009d90 t scan_tree
00000001200236a8 S seedi
0000000120001390 T send_bits
0000000120009f40 t send_tree
0000000120009540 t set_file_type
0000000120004420 t shorten_name
0000000120007f90 T spec_compress
0000000120073ac8 B spec_fd
0000000120007800 T spec_getc
0000000120006f70 T spec_init
0000000120007f40 T spec_initbufs
0000000120007430 T spec_load
0000000120008350 T spec_putc
0000000120007090 T spec_random_load
0000000120007670 T spec_read
00000001200081b0 T spec_reset
0000000120008190 T spec_rewind
0000000120008010 T spec_uncompress
0000000120007930 T spec_ungetc
0000000120008210 T spec_write
0000000120024540 b static_dtree
0000000120023598 s static_len
00000001200240c0 b static_ltree
000000012000eb20 T strlwr
0000000120023620 S strstart
00000001200235bc s subbitbuf
0000000120021440 d suffixes.1
0000000120023544 S test
0000000120023638 S time_stamp
0000000120023524 S to_stdout
0000000120023558 S total_in
0000000120023560 S total_out
000000012000a510 T unlzh
000000012000c5c0 T unlzw
000000012000cde0 T unpack
000000012000d7a0 T unzip
000000012000e4c0 T updcrc
00000001200235e8 s valid
0000000120023538 S verbose
000000012000ecd0 T warn
0000000120063aa8 B window
00000001200234b0 G window_size
00000001200234d0 G work
000000012000ea20 T write_buf
000000012000ee00 T write_error
000000012000e220 T xmalloc
0000000120023670 S z_len
0000000120073aa8 B z_suffix
0000000120023504 s zfile
000000012000ef80 T zip

1
configs/boot/halt.sh Normal file
View file

@ -0,0 +1 @@
m5 exit

18
configs/boot/ls.rcS Normal file
View file

@ -0,0 +1,18 @@
ls
ls
ls
ls
cd bin
ls
ls
ls
ls
ls
ls
ls
ls
cd ../benchmarks
ls
ls
ls
ls

12
configs/boot/mcf.rcS Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
cd /benchmarks/spec/mcf00/
/sbin/m5 checkpoint 0 0
/sbin/m5 checkpoint 100000000 200000000
/sbin/m5 loadsymbol
/sbin/m5 resetstats
/benchmarks/spec/mcf00/mcf mdred.in
/sbin/m5 exit

65
configs/boot/mcf.symbol Normal file
View file

@ -0,0 +1,65 @@
0000000120014350 D _DYNAMIC
0000000120014608 D _GLOBAL_OFFSET_TABLE_
0000000120014770 G _IO_stdin_used
0000000120014518 T _PROCEDURE_LINKAGE_TABLE_
00000001200144f8 d __CTOR_END__
00000001200144f0 d __CTOR_LIST__
0000000120014508 d __DTOR_END__
0000000120014500 d __DTOR_LIST__
000000012001434c r __FRAME_END__
0000000120014510 d __JCR_END__
0000000120014510 d __JCR_LIST__
0000000120014790 A __bss_start
0000000120014000 D __data_start
00000001200034d0 t __do_global_ctors_aux
0000000120000a40 t __do_global_dtors_aux
0000000120014778 G __dso_handle
0000000120014000 A __fini_array_end
0000000120014000 A __fini_array_start
0000000120014000 A __init_array_end
0000000120014000 A __init_array_start
0000000120003430 T __libc_csu_fini
0000000120003380 T __libc_csu_init
0000000120000a00 W __start
0000000120014790 A _edata
0000000120017c30 A _end
0000000120003530 T _fini
0000000120000998 T _init
0000000120000a00 T _start
00000001200147b0 b basket
0000000120014798 s basket_size
0000000120003320 T bea_compute_red_cost
0000000120003340 T bea_is_dual_infeasible
0000000120014790 s completed.1
0000000120002410 T compute_red_cost
0000000120014000 W data_start
0000000120001480 T dual_feasible
0000000120001090 T flow_cost
00000001200011d0 T flow_org_cost
0000000120000ae0 t frame_dummy
00000001200015f0 T getfree
0000000120000e30 T global_opt
00000001200147a8 s group_pos
0000000120014788 g initialize
0000000120002420 T insert_new_arc
0000000120000b30 T main
00000001200179d0 B net
00000001200147a0 s nr_group
0000000120014780 g p.0
0000000120016d48 b perm
0000000120001d20 T price_out_impl
0000000120003080 T primal_bea_mpp
0000000120001310 T primal_feasible
0000000120002a60 T primal_iminus
0000000120002c00 T primal_net_simplex
0000000120002510 T primal_start_artificial
0000000120002ba0 T primal_update_flow
00000001200016b0 T read_min
0000000120001580 T refresh_neighbour_lists
0000000120000fa0 T refresh_potential
0000000120001c10 T replace_weaker_arc
0000000120002310 T resize_prob
0000000120002f30 T sort_basket
00000001200021b0 T suspend_impl
00000001200027e0 T update_tree
0000000120002600 T write_circulations

12
configs/boot/mesa.rcS Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
cd /benchmarks/spec/mesa00/
/sbin/m5 checkpoint 0 0
/sbin/m5 checkpoint 100000000 200000000
/sbin/m5 loadsymbol
/sbin/m5 resetstats
/benchmarks/spec/mesa00/mesa -frames 1 -meshfile lgred.in
/sbin/m5 exit

1135
configs/boot/mesa.symbol Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,3 @@
/benchmarks/micros/lmbench/bin/alphaev6-linux-gnu/lat_mem_rd_2MB 2 8192
m5 exit

View file

@ -0,0 +1,3 @@
/benchmarks/micros/lmbench/bin/alphaev6-linux-gnu/lat_mem_rd_2MB 20 8192
m5 exit

View file

@ -554,6 +554,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
return NoFault;
}
void
AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
{
@ -562,6 +563,7 @@ AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
}
}
/**
* Check for special simulator handling of specific PAL calls.
* If return value is false, actual PAL call will be suppressed.

View file

@ -105,6 +105,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
Param<string> boot_osflags;
Param<string> readfile;
Param<string> symbolfile;
Param<unsigned int> init_param;
Param<uint64_t> system_type;
@ -124,6 +125,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(symbolfile, "file to read symbols from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
@ -143,6 +145,7 @@ CREATE_SIM_OBJECT(FreebsdAlphaSystem)
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
p->symbolfile = symbolfile;
p->system_type = system_type;
p->system_rev = system_rev;
return new FreebsdAlphaSystem(p);

View file

@ -779,10 +779,10 @@ decode OPCODE default Unknown::unknown() {
}}, IsNonSpeculative, IsQuiesce);
0x03: quiesceCycles({{
AlphaPseudo::quiesceCycles(xc->tcBase(), R16);
}}, IsNonSpeculative, IsQuiesce);
}}, IsNonSpeculative, IsQuiesce, IsUnverifiable);
0x04: quiesceTime({{
R0 = AlphaPseudo::quiesceTime(xc->tcBase());
}}, IsNonSpeculative);
}}, IsNonSpeculative, IsUnverifiable);
0x10: ivlb({{
AlphaPseudo::ivlb(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
@ -795,6 +795,9 @@ decode OPCODE default Unknown::unknown() {
0x21: m5exit({{
AlphaPseudo::m5exit(xc->tcBase(), R16);
}}, No_OpClass, IsNonSpeculative);
0x31: loadsymbol({{
AlphaPseudo::loadsymbol(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }});
0x40: resetstats({{
AlphaPseudo::resetstats(xc->tcBase(), R16, R17);

View file

@ -528,7 +528,7 @@ def template MiscInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
warn("Misc instruction does not support split access method!");
return NoFault;
}
}};
@ -539,7 +539,7 @@ def template MiscCompleteAcc {{
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
warn("Misc instruction does not support split access method!");
return NoFault;
}

View file

@ -199,6 +199,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
Param<string> boot_osflags;
Param<string> readfile;
Param<string> symbolfile;
Param<unsigned int> init_param;
Param<uint64_t> system_type;
@ -218,6 +219,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(symbolfile, "file to read symbols from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
@ -237,6 +239,7 @@ CREATE_SIM_OBJECT(LinuxAlphaSystem)
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
p->symbolfile = symbolfile;
p->system_type = system_type;
p->system_rev = system_rev;
return new LinuxAlphaSystem(p);

View file

@ -229,6 +229,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
Param<std::string> boot_osflags;
Param<std::string> readfile;
Param<std::string> symbolfile;
Param<unsigned int> init_param;
Param<uint64_t> system_type;
@ -248,6 +249,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(symbolfile, "file to read symbols from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
@ -267,6 +269,7 @@ CREATE_SIM_OBJECT(AlphaSystem)
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
p->symbolfile = symbolfile;
p->system_type = system_type;
p->system_rev = system_rev;
return new AlphaSystem(p);

View file

@ -103,6 +103,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
Param<string> boot_osflags;
Param<string> readfile;
Param<string> symbolfile;
Param<unsigned int> init_param;
Param<uint64_t> system_type;
@ -122,6 +123,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
"a"),
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(symbolfile, "file to read symbols from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1)
@ -141,6 +143,7 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem)
p->boot_osflags = boot_osflags;
p->init_param = init_param;
p->readfile = readfile;
p->symbolfile = symbolfile;
p->system_type = system_type;
p->system_rev = system_rev;

View file

@ -48,6 +48,9 @@
#include "base/trace.hh"
// Hack
#include "sim/stat_control.hh"
using namespace std;
vector<BaseCPU *> BaseCPU::cpuList;
@ -57,6 +60,39 @@ vector<BaseCPU *> BaseCPU::cpuList;
// been initialized
int maxThreadsPerCPU = 1;
CPUProgressEvent::CPUProgressEvent(EventQueue *q, Tick ival,
BaseCPU *_cpu)
: Event(q, Event::Stat_Event_Pri), interval(ival),
lastNumInst(0), cpu(_cpu)
{
if (interval)
schedule(curTick + interval);
}
void
CPUProgressEvent::process()
{
Counter temp = cpu->totalInstructions();
#ifndef NDEBUG
double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1));
DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n",
cpu->name(), temp - lastNumInst, ipc);
ipc = 0.0;
#else
cprintf("%lli: %s progress event, instructions committed: %lli\n",
curTick, cpu->name(), temp - lastNumInst);
#endif
lastNumInst = temp;
schedule(curTick + interval);
}
const char *
CPUProgressEvent::description()
{
return "CPU Progress event";
}
#if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p)
: MemObject(p->name), clock(p->clock), checkInterrupts(true),
@ -67,6 +103,7 @@ BaseCPU::BaseCPU(Params *p)
number_of_threads(p->numberOfThreads), system(p->system)
#endif
{
// currentTick = curTick;
DPRINTF(FullCPU, "BaseCPU: Creating object, mem address %#x.\n", this);
// add self to global list of CPUs
@ -153,7 +190,6 @@ BaseCPU::BaseCPU(Params *p)
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
#endif
}
BaseCPU::Params::Params()
@ -188,6 +224,11 @@ BaseCPU::startup()
if (!params->deferRegistration && profileEvent)
profileEvent->schedule(curTick);
#endif
if (params->progress_interval) {
new CPUProgressEvent(&mainEventQueue, params->progress_interval,
this);
}
}
@ -238,7 +279,11 @@ BaseCPU::registerThreadContexts()
void
BaseCPU::switchOut()
{
panic("This CPU doesn't support sampling!");
// panic("This CPU doesn't support sampling!");
#if FULL_SYSTEM
if (profileEvent && profileEvent->scheduled())
profileEvent->deschedule();
#endif
}
void
@ -261,18 +306,22 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
assert(newTC->getProcessPtr() == oldTC->getProcessPtr());
newTC->getProcessPtr()->replaceThreadContext(newTC, newTC->readCpuId());
#endif
// TheISA::compareXCs(oldXC, newXC);
}
#if FULL_SYSTEM
for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
interrupts[i] = oldCPU->interrupts[i];
intstatus = oldCPU->intstatus;
checkInterrupts = oldCPU->checkInterrupts;
for (int i = 0; i < threadContexts.size(); ++i)
threadContexts[i]->profileClear();
if (profileEvent)
profileEvent->schedule(curTick);
// The Sampler must take care of this!
// if (profileEvent)
// profileEvent->schedule(curTick);
#endif
}

View file

@ -46,6 +46,21 @@ class ThreadContext;
class System;
class Port;
class CPUProgressEvent : public Event
{
protected:
Tick interval;
Counter lastNumInst;
BaseCPU *cpu;
public:
CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu);
void process();
virtual const char *description();
};
class BaseCPU : public MemObject
{
protected:
@ -53,6 +68,7 @@ class BaseCPU : public MemObject
Tick clock;
public:
// Tick currentTick;
inline Tick frequency() const { return Clock::Frequency / clock; }
inline Tick cycles(int numCycles) const { return clock * numCycles; }
inline Tick curCycle() const { return curTick / clock; }
@ -128,6 +144,7 @@ class BaseCPU : public MemObject
int cpu_id;
Tick profile;
#endif
Tick progress_interval;
BaseCPU *checker;
Params();

View file

@ -197,7 +197,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
union Result {
uint64_t integer;
float fp;
// float fp;
double dbl;
};
@ -394,7 +394,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
uint64_t readIntResult() { return instResult.integer; }
/** Returns the result of a floating point instruction. */
float readFloatResult() { return instResult.fp; }
float readFloatResult() { return (float)instResult.dbl; }
/** Returns the result of a floating point (double) instruction. */
double readDoubleResult() { return instResult.dbl; }
@ -409,7 +409,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
void setFloatReg(const StaticInst *si, int idx, FloatReg val, int width)
{
if (width == 32)
instResult.fp = val;
instResult.dbl = (double)val;
else if (width == 64)
instResult.dbl = val;
else
@ -419,7 +419,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
/** Records an fp register being set to a value. */
void setFloatReg(const StaticInst *si, int idx, FloatReg val)
{
instResult.fp = val;
// instResult.fp = val;
instResult.dbl = (double)val;
}
/** Records an fp register being set to an integer value. */

View file

@ -102,6 +102,7 @@ class CheckerCPU : public BaseCPU
Process *process;
#endif
bool exitOnError;
bool updateOnError;
bool warnOnlyOnLoadError;
};
@ -148,7 +149,7 @@ class CheckerCPU : public BaseCPU
union Result {
uint64_t integer;
float fp;
// float fp;
double dbl;
};
@ -257,7 +258,7 @@ class CheckerCPU : public BaseCPU
thread->setFloatReg(reg_idx, val, width);
switch(width) {
case 32:
result.fp = val;
result.dbl = (double)val;
break;
case 64:
result.dbl = val;
@ -269,7 +270,7 @@ class CheckerCPU : public BaseCPU
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
thread->setFloatReg(reg_idx, val);
result.fp = val;
result.dbl = (double)val;
}
void setFloatRegBits(const StaticInst *si, int idx, FloatRegBits val,
@ -318,7 +319,7 @@ class CheckerCPU : public BaseCPU
return thread->setMiscRegWithEffect(misc_reg, val);
}
void recordPCChange(uint64_t val) { changedPC = true; }
void recordPCChange(uint64_t val) { changedPC = true; newPC = val; }
void recordNextPCChange(uint64_t val) { changedNextPC = true; }
bool translateInstReq(Request *req);
@ -360,6 +361,7 @@ class CheckerCPU : public BaseCPU
uint64_t newPC;
bool changedNextPC;
bool exitOnError;
bool updateOnError;
bool warnOnlyOnLoadError;
InstSeqNum youngestSN;
@ -376,7 +378,7 @@ class Checker : public CheckerCPU
{
public:
Checker(Params *p)
: CheckerCPU(p)
: CheckerCPU(p), updateThisCycle(false), unverifiedInst(NULL)
{ }
void switchOut();
@ -393,12 +395,19 @@ class Checker : public CheckerCPU
private:
void handleError(DynInstPtr &inst)
{
if (exitOnError)
if (exitOnError) {
dumpAndExit(inst);
} else if (updateOnError) {
updateThisCycle = true;
}
}
void dumpAndExit(DynInstPtr &inst);
bool updateThisCycle;
DynInstPtr unverifiedInst;
std::list<DynInstPtr> instList;
typedef typename std::list<DynInstPtr>::iterator InstListIt;
void dumpInsts();

View file

@ -94,6 +94,8 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
}
}
unverifiedInst = inst;
// Try to check all instructions that are completed, ending if we
// run out of instructions to check or if an instruction is not
// yet completed.
@ -171,7 +173,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
return;
break;
} else {
// The instruction is carrying an ITB fault. Handle
// the fault and see if our results match the CPU on
@ -220,7 +222,8 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
thread->funcExeInst++;
fault = curStaticInst->execute(this, NULL);
if (!inst->isUnverifiable())
fault = curStaticInst->execute(this, NULL);
// Checks to make sure instrution results are correct.
validateExecution(inst);
@ -289,6 +292,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
break;
}
}
unverifiedInst = NULL;
}
template <class DynInstPtr>
@ -395,6 +399,24 @@ template <class DynInstPtr>
void
Checker<DynInstPtr>::validateState()
{
if (updateThisCycle) {
warn("%lli: Instruction PC %#x results didn't match up, copying all "
"registers from main CPU", curTick, unverifiedInst->readPC());
// Heavy-weight copying of all registers
thread->copyArchRegs(unverifiedInst->tcBase());
// Also advance the PC. Hopefully no PC-based events happened.
#if THE_ISA != MIPS_ISA
// go to the next instruction
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#else
// go to the next instruction
thread->setPC(thread->readNextPC());
thread->setNextPC(thread->readNextNPC());
thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
#endif
updateThisCycle = false;
}
}
template <class DynInstPtr>

View file

@ -56,6 +56,7 @@ SimObjectParam<System *> system;
Param<int> cpu_id;
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
Param<Tick> profile;
#else
SimObjectVectorParam<Process *> workload;
#endif // FULL_SYSTEM
@ -68,6 +69,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
Param<unsigned> cachePorts;
@ -162,6 +164,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(itb, "Instruction translation buffer"),
INIT_PARAM(dtb, "Data translation buffer"),
INIT_PARAM(profile, ""),
#else
INIT_PARAM(workload, "Processes to run"),
#endif // FULL_SYSTEM
@ -184,6 +187,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
"Terminate when all threads have reached this load"
"count",
0),
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(cachePorts, "Cache Ports", 200),
@ -305,6 +309,7 @@ CREATE_SIM_OBJECT(DerivO3CPU)
params->cpu_id = cpu_id;
params->itb = itb;
params->dtb = dtb;
params->profile = profile;
#else
params->workload = workload;
#endif // FULL_SYSTEM
@ -317,6 +322,7 @@ CREATE_SIM_OBJECT(DerivO3CPU)
params->max_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
params->progress_interval = progress_interval;
//
// Caches

View file

@ -64,6 +64,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@ -78,6 +79,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<bool> defer_registration;
Param<bool> exitOnError;
Param<bool> updateOnError;
Param<bool> warnOnlyOnLoadError;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@ -94,6 +96,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@ -109,6 +112,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"),
INIT_PARAM(updateOnError, "Update the checker with the main CPU's state on error"),
INIT_PARAM_DFLT(warnOnlyOnLoadError, "warn, but don't exit, if a load "
"result errors", false),
INIT_PARAM(function_trace, "Enable function trace"),
@ -127,6 +131,7 @@ CREATE_SIM_OBJECT(O3Checker)
params->max_loads_any_thread = 0;
params->max_loads_all_threads = 0;
params->exitOnError = exitOnError;
params->updateOnError = updateOnError;
params->warnOnlyOnLoadError = warnOnlyOnLoadError;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
@ -139,6 +144,9 @@ CREATE_SIM_OBJECT(O3Checker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
Tick temp2 = progress_interval;
params->progress_interval = 0;
temp2++;
#if FULL_SYSTEM
params->itb = itb;

View file

@ -1083,12 +1083,26 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
// Generate trap squash event.
generateTrapEvent(tid);
// warn("%lli fault (%d) handled @ PC %08p", curTick, inst_fault->name(), head_inst->readPC());
return false;
}
updateComInstStats(head_inst);
#if FULL_SYSTEM
if (thread[tid]->profile) {
// bool usermode =
// (cpu->readMiscReg(AlphaISA::IPR_DTB_CM, tid) & 0x18) != 0;
// thread[tid]->profilePC = usermode ? 1 : head_inst->readPC();
thread[tid]->profilePC = head_inst->readPC();
ProfileNode *node = thread[tid]->profile->consume(thread[tid]->getTC(),
head_inst->staticInst);
if (node)
thread[tid]->profileNode = node;
}
#endif
if (head_inst->traceData) {
head_inst->traceData->setFetchSeq(head_inst->seqNum);
head_inst->traceData->setCPSeq(thread[tid]->numInst);
@ -1102,6 +1116,9 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
head_inst->renamedDestRegIdx(i));
}
if (head_inst->isCopy())
panic("Should not commit any copy instructions!");
// Finally clear the head ROB entry.
rob->retireHead(tid);

View file

@ -33,6 +33,7 @@
#include "config/use_checker.hh"
#if FULL_SYSTEM
#include "cpu/quiesce_event.hh"
#include "sim/system.hh"
#else
#include "sim/process.hh"
@ -793,6 +794,7 @@ template <class Impl>
unsigned int
FullO3CPU<Impl>::drain(Event *drain_event)
{
DPRINTF(O3CPU, "Switching out\n");
drainCount = 0;
fetch.drain();
decode.drain();
@ -849,6 +851,8 @@ FullO3CPU<Impl>::signalDrained()
changeState(SimObject::Drained);
BaseCPU::switchOut();
if (drainEvent) {
drainEvent->process();
drainEvent = NULL;
@ -863,6 +867,7 @@ FullO3CPU<Impl>::switchOut()
{
fetch.switchOut();
rename.switchOut();
iew.switchOut();
commit.switchOut();
instList.clear();
while (!removeList.empty()) {
@ -874,6 +879,8 @@ FullO3CPU<Impl>::switchOut()
if (checker)
checker->switchOut();
#endif
if (tickEvent.scheduled())
tickEvent.squash();
}
template <class Impl>

View file

@ -442,6 +442,7 @@ DefaultFetch<Impl>::takeOverFrom()
wroteToTimeBuffer = false;
_status = Inactive;
switchedOut = false;
interruptPending = false;
branchPred.takeOverFrom();
}
@ -563,7 +564,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid
unsigned flags = 0;
#endif // FULL_SYSTEM
if (cacheBlocked || (interruptPending && flags == 0)) {
if (cacheBlocked || isSwitchedOut() || (interruptPending && flags == 0)) {
// Hold off fetch from getting new instructions when:
// Cache is blocked, or
// while an interrupt is pending and we're not in PAL mode, or
@ -1152,8 +1153,8 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetch_PC = next_PC;
if (instruction->isQuiesce()) {
warn("cycle %lli: Quiesce instruction encountered, halting fetch!",
curTick);
// warn("%lli: Quiesce instruction encountered, halting fetch!",
// curTick);
fetchStatus[tid] = QuiescePending;
++numInst;
status_change = true;
@ -1268,7 +1269,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
fetchStatus[tid] = TrapPending;
status_change = true;
warn("cycle %lli: fault (%s) detected @ PC %08p", curTick, fault->name(), PC[tid]);
// warn("%lli fault (%d) detected @ PC %08p", curTick, fault, PC[tid]);
#else // !FULL_SYSTEM
warn("cycle %lli: fault (%s) detected @ PC %08p", curTick, fault->name(), PC[tid]);
#endif // FULL_SYSTEM

View file

@ -216,6 +216,7 @@ class DefaultIEW
if (++wbOutstanding == wbMax)
ableToIssue = false;
DPRINTF(IEW, "wbOutstanding: %i\n", wbOutstanding);
assert(wbOutstanding <= wbMax);
#ifdef DEBUG
wbList.insert(sn);
#endif
@ -226,6 +227,7 @@ class DefaultIEW
if (wbOutstanding-- == wbMax)
ableToIssue = true;
DPRINTF(IEW, "wbOutstanding: %i\n", wbOutstanding);
assert(wbOutstanding >= 0);
#ifdef DEBUG
assert(wbList.find(sn) != wbList.end());
wbList.erase(sn);
@ -450,7 +452,9 @@ class DefaultIEW
unsigned wbCycle;
/** Number of instructions in flight that will writeback. */
unsigned wbOutstanding;
/** Number of instructions in flight that will writeback. */
int wbOutstanding;
/** Writeback width. */
unsigned wbWidth;
@ -507,6 +511,8 @@ class DefaultIEW
Stats::Scalar<> iewExecutedInsts;
/** Stat for total number of executed load instructions. */
Stats::Vector<> iewExecLoadInsts;
/** Stat for total number of executed store instructions. */
// Stats::Scalar<> iewExecStoreInsts;
/** Stat for total number of squashed instructions skipped at execute. */
Stats::Scalar<> iewExecSquashedInsts;
/** Number of executed software prefetches. */

View file

@ -162,17 +162,17 @@ DefaultIEW<Impl>::regStats()
branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
iewExecutedInsts
.name(name() + ".EXEC:insts")
.name(name() + ".iewExecutedInsts")
.desc("Number of executed instructions");
iewExecLoadInsts
.init(cpu->number_of_threads)
.name(name() + ".EXEC:loads")
.name(name() + ".iewExecLoadInsts")
.desc("Number of load instructions executed")
.flags(total);
iewExecSquashedInsts
.name(name() + ".EXEC:squashedInsts")
.name(name() + ".iewExecSquashedInsts")
.desc("Number of squashed instructions skipped in execute");
iewExecutedSwp
@ -372,6 +372,8 @@ DefaultIEW<Impl>::switchOut()
{
// Clear any state.
switchedOut = true;
assert(insts[0].empty());
assert(skidBuffer[0].empty());
instQueue.switchOut();
ldstQueue.switchOut();
@ -410,7 +412,6 @@ DefaultIEW<Impl>::takeOverFrom()
updateLSQNextCycle = false;
// @todo: Fix hardcoded number
for (int i = 0; i < issueToExecQueue.getSize(); ++i) {
issueToExecQueue.advance();
}
@ -611,9 +612,11 @@ DefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
wbNumInst = 0;
}
assert((wbCycle * wbWidth + wbNumInst) < wbMax);
assert((wbCycle * wbWidth + wbNumInst) <= wbMax);
}
DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n",
wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst);
// Add finished instruction to queue to commit.
(*iewQueue)[wbCycle].insts[wbNumInst] = inst;
(*iewQueue)[wbCycle].size++;
@ -1273,13 +1276,23 @@ DefaultIEW<Impl>::executeInsts()
// event adds the instruction to the queue to commit
fault = ldstQueue.executeLoad(inst);
} else if (inst->isStore()) {
ldstQueue.executeStore(inst);
fault = ldstQueue.executeStore(inst);
// If the store had a fault then it may not have a mem req
if (inst->req && !(inst->req->getFlags() & LOCKED)) {
if (!inst->isStoreConditional() && fault == NoFault) {
inst->setExecuted();
instToCommit(inst);
} else if (fault != NoFault) {
// If the instruction faulted, then we need to send it along to commit
// without the instruction completing.
// Send this instruction to commit, also make sure iew stage
// realizes there is activity.
inst->setExecuted();
instToCommit(inst);
activityThisCycle();
}
// Store conditionals will mark themselves as
@ -1404,7 +1417,7 @@ DefaultIEW<Impl>::writebackInsts()
// E.g. Uncached loads have not actually executed when they
// are first sent to commit. Instead commit must tell the LSQ
// when it's ready to execute the uncached load.
if (!inst->isSquashed() && inst->isExecuted()) {
if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) {
int dependents = instQueue.wakeDependents(inst);
for (int i = 0; i < inst->numDestRegs(); i++) {

View file

@ -479,13 +479,13 @@ class InstructionQueue
/** Distribution of number of instructions in the queue.
* @todo: Need to create struct to track the entry time for each
* instruction. */
Stats::VectorDistribution<> queueResDist;
// Stats::VectorDistribution<> queueResDist;
/** Distribution of the number of instructions issued. */
Stats::Distribution<> numIssuedDist;
/** Distribution of the cycles it takes to issue an instruction.
* @todo: Need to create struct to track the ready time for each
* instruction. */
Stats::VectorDistribution<> issueDelayDist;
// Stats::VectorDistribution<> issueDelayDist;
/** Number of times an instruction could not be issued because a
* FU was busy.

View file

@ -230,7 +230,7 @@ InstructionQueue<Impl>::regStats()
.name(name() + ".iqSquashedNonSpecRemoved")
.desc("Number of squashed non-spec instructions that were removed")
.prereq(iqSquashedNonSpecRemoved);
/*
queueResDist
.init(Num_OpClasses, 0, 99, 2)
.name(name() + ".IQ:residence:")
@ -240,6 +240,7 @@ InstructionQueue<Impl>::regStats()
for (int i = 0; i < Num_OpClasses; ++i) {
queueResDist.subname(i, opClassStrings[i]);
}
*/
numIssuedDist
.init(0,totalWidth,1)
.name(name() + ".ISSUE:issued_per_cycle")
@ -268,7 +269,7 @@ InstructionQueue<Impl>::regStats()
//
// How long did instructions for a particular FU type wait prior to issue
//
/*
issueDelayDist
.init(Num_OpClasses,0,99,2)
.name(name() + ".ISSUE:")
@ -281,7 +282,7 @@ InstructionQueue<Impl>::regStats()
subname << opClassStrings[i] << "_delay";
issueDelayDist.subname(i, subname.str());
}
*/
issueRate
.name(name() + ".ISSUE:rate")
.desc("Inst issue rate")
@ -385,8 +386,16 @@ template <class Impl>
void
InstructionQueue<Impl>::switchOut()
{
/*
if (!instList[0].empty() || (numEntries != freeEntries) ||
!readyInsts[0].empty() || !nonSpecInsts.empty() || !listOrder.empty()) {
dumpInsts();
// assert(0);
}
*/
resetState();
dependGraph.reset();
instsToExecute.clear();
switchedOut = true;
for (int i = 0; i < numThreads; ++i) {
memDepUnit[i].switchOut();
@ -642,9 +651,12 @@ template <class Impl>
void
InstructionQueue<Impl>::processFUCompletion(DynInstPtr &inst, int fu_idx)
{
DPRINTF(IQ, "Processing FU completion [sn:%lli]\n", inst->seqNum);
// The CPU could have been sleeping until this op completed (*extremely*
// long latency op). Wake it if it was. This may be overkill.
if (isSwitchedOut()) {
DPRINTF(IQ, "FU completion not processed, IQ is switched out [sn:%lli]\n",
inst->seqNum);
return;
}
@ -1036,6 +1048,10 @@ InstructionQueue<Impl>::doSquash(unsigned tid)
(squashed_inst->isMemRef() &&
!squashed_inst->memOpDone)) {
DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x "
"squashed.\n",
tid, squashed_inst->seqNum, squashed_inst->readPC());
// Remove the instruction from the dependency list.
if (!squashed_inst->isNonSpeculative() &&
!squashed_inst->isStoreConditional() &&
@ -1066,7 +1082,7 @@ InstructionQueue<Impl>::doSquash(unsigned tid)
++iqSquashedOperandsExamined;
}
} else {
} else if (!squashed_inst->isStoreConditional() || !squashed_inst->isCompleted()) {
NonSpecMapIt ns_inst_it =
nonSpecInsts.find(squashed_inst->seqNum);
assert(ns_inst_it != nonSpecInsts.end());
@ -1093,10 +1109,6 @@ InstructionQueue<Impl>::doSquash(unsigned tid)
count[squashed_inst->threadNumber]--;
++freeEntries;
DPRINTF(IQ, "[tid:%i]: Instruction [sn:%lli] PC %#x "
"squashed.\n",
tid, squashed_inst->seqNum, squashed_inst->readPC());
}
instList[tid].erase(squash_it--);

View file

@ -407,7 +407,6 @@ class LSQUnit {
// Will also need how many read/write ports the Dcache has. Or keep track
// of that in stage that is one level up, and only call executeLoad/Store
// the appropriate number of times.
/** Total number of loads forwaded from LSQ stores. */
Stats::Scalar<> lsqForwLoads;
@ -421,6 +420,9 @@ class LSQUnit {
* ignored due to the instruction already being squashed. */
Stats::Scalar<> lsqIgnoredResponses;
/** Tota number of memory ordering violations. */
Stats::Scalar<> lsqMemOrderViolation;
/** Total number of squashed stores. */
Stats::Scalar<> lsqSquashedStores;

View file

@ -180,6 +180,10 @@ LSQUnit<Impl>::regStats()
.name(name() + ".ignoredResponses")
.desc("Number of memory responses ignored because the instruction is squashed");
lsqMemOrderViolation
.name(name() + ".memOrderViolation")
.desc("Number of memory ordering violations");
lsqSquashedStores
.name(name() + ".squashedStores")
.desc("Number of stores squashed");
@ -220,8 +224,10 @@ void
LSQUnit<Impl>::switchOut()
{
switchedOut = true;
for (int i = 0; i < loadQueue.size(); ++i)
for (int i = 0; i < loadQueue.size(); ++i) {
assert(!loadQueue[i]);
loadQueue[i] = NULL;
}
assert(storesToWB == 0);
}
@ -408,6 +414,11 @@ LSQUnit<Impl>::executeLoad(DynInstPtr &inst)
if (load_fault != NoFault) {
// Send this instruction to commit, also make sure iew stage
// realizes there is activity.
// Mark it as executed unless it is an uncached load that
// needs to hit the head of commit.
if (!(inst->req->getFlags() & UNCACHEABLE) || inst->isAtCommit()) {
inst->setExecuted();
}
iewStage->instToCommit(inst);
iewStage->activityThisCycle();
}
@ -467,6 +478,7 @@ LSQUnit<Impl>::executeStore(DynInstPtr &store_inst)
// A load incorrectly passed this store. Squash and refetch.
// For now return a fault to show that it was unsuccessful.
memDepViolator = loadQueue[load_idx];
++lsqMemOrderViolation;
return genMachineCheckFault();
}
@ -820,6 +832,7 @@ LSQUnit<Impl>::completeStore(int store_idx)
// A bit conservative because a store completion may not free up entries,
// but hopefully avoids two store completions in one cycle from making
// the CPU tick twice.
cpu->wakeCPU();
cpu->activityThisCycle();
if (store_idx == storeHead) {

View file

@ -109,6 +109,9 @@ template <class MemDepPred, class Impl>
void
MemDepUnit<MemDepPred, Impl>::switchOut()
{
assert(instList[0].empty());
assert(instsToReplay.empty());
assert(memDepHash.empty());
// Clear any state.
for (int i = 0; i < Impl::MaxThreads; ++i) {
instList[i].clear();

View file

@ -417,6 +417,8 @@ class DefaultRename
/** The maximum skid buffer size. */
unsigned skidBufferMax;
PhysRegIndex maxPhysicalRegs;
/** Enum to record the source of a structure full stall. Can come from
* either ROB, IQ, LSQ, and it is priortized in that order.
*/

View file

@ -41,7 +41,8 @@ DefaultRename<Impl>::DefaultRename(Params *params)
commitToRenameDelay(params->commitToRenameDelay),
renameWidth(params->renameWidth),
commitWidth(params->commitWidth),
numThreads(params->numberOfThreads)
numThreads(params->numberOfThreads),
maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs)
{
_status = Inactive;
@ -286,6 +287,11 @@ DefaultRename<Impl>::switchOut()
// Put the renamed physical register back on the free list.
freeList->addReg(hb_it->newPhysReg);
// Be sure to mark its register as ready if it's a misc register.
if (hb_it->newPhysReg >= maxPhysicalRegs) {
scoreboard->setReg(hb_it->newPhysReg);
}
historyBuffer[i].erase(hb_it++);
}
insts[i].clear();
@ -889,6 +895,11 @@ DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, unsigned tid)
// Put the renamed physical register back on the free list.
freeList->addReg(hb_it->newPhysReg);
// Be sure to mark its register as ready if it's a misc register.
if (hb_it->newPhysReg >= maxPhysicalRegs) {
scoreboard->setReg(hb_it->newPhysReg);
}
historyBuffer[tid].erase(hb_it++);
++renameUndoneMaps;

View file

@ -54,7 +54,7 @@ template <class Impl>
void
O3ThreadContext<Impl>::dumpFuncProfile()
{
// Currently not supported
thread->dumpFuncProfile();
}
#endif
@ -239,12 +239,16 @@ O3ThreadContext<Impl>::readLastSuspend()
template <class Impl>
void
O3ThreadContext<Impl>::profileClear()
{}
{
thread->profileClear();
}
template <class Impl>
void
O3ThreadContext<Impl>::profileSample()
{}
{
thread->profileSample();
}
#endif
template <class Impl>

View file

@ -31,8 +31,11 @@
#ifndef __CPU_O3_THREAD_STATE_HH__
#define __CPU_O3_THREAD_STATE_HH__
#include "base/callback.hh"
#include "base/output.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
#include "sim/sim_exit.hh"
class Event;
class Process;
@ -75,8 +78,22 @@ struct O3ThreadState : public ThreadState {
#if FULL_SYSTEM
O3ThreadState(O3CPU *_cpu, int _thread_num)
: ThreadState(-1, _thread_num),
inSyscall(0), trapPending(0)
{ }
cpu(_cpu), inSyscall(0), trapPending(0)
{
if (cpu->params->profile) {
profile = new FunctionProfile(cpu->params->system->kernelSymtab);
Callback *cb =
new MakeCallback<O3ThreadState,
&O3ThreadState::dumpFuncProfile>(this);
registerExitCallback(cb);
}
// let's fill with a dummy node for now so we don't get a segfault
// on the first cycle when there's no node available.
static ProfileNode dummyNode;
profileNode = &dummyNode;
profilePC = 3;
}
#else
O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process, int _asid,
MemObject *mem)
@ -95,6 +112,14 @@ struct O3ThreadState : public ThreadState {
/** Handles the syscall. */
void syscall(int64_t callnum) { process->syscall(callnum, tc); }
#endif
#if FULL_SYSTEM
void dumpFuncProfile()
{
std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
profile->dump(tc, *os);
}
#endif
};
#endif // __CPU_O3_THREAD_STATE_HH__

View file

@ -62,6 +62,8 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
for (int i = 0; i < localPredictorSize; ++i)
localCtrs[i].setBits(localCtrBits);
localPredictorMask = floorPow2(localPredictorSize) - 1;
if (!isPowerOf2(localHistoryTableSize)) {
fatal("Invalid local history table size!\n");
}
@ -158,7 +160,7 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
//Lookup in the local predictor to get its branch prediction
local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_idx = localHistoryTable[local_history_idx]
& localHistoryMask;
& localPredictorMask;
local_prediction = localCtrs[local_predictor_idx].read() > threshold;
//Lookup in the global predictor to get its branch prediction
@ -176,7 +178,8 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
bp_history = (void *)history;
assert(globalHistory < globalPredictorSize &&
local_history_idx < localPredictorSize);
local_history_idx < localHistoryTableSize &&
local_predictor_idx < localPredictorSize);
// Commented code is for doing speculative update of counters and
// all histories.
@ -234,7 +237,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
// Get the local predictor's current prediction
local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_hist = localHistoryTable[local_history_idx];
local_predictor_idx = local_predictor_hist & localHistoryMask;
local_predictor_idx = local_predictor_hist & localPredictorMask;
// Update the choice predictor to tell it which one was correct if
// there was a prediction.
@ -256,6 +259,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
}
assert(globalHistory < globalPredictorSize &&
local_history_idx < localHistoryTableSize &&
local_predictor_idx < localPredictorSize);
// Update the counters and local history with the proper

View file

@ -159,6 +159,9 @@ class TournamentBP
/** Size of the local predictor. */
unsigned localPredictorSize;
/** Mask to get the proper index bits into the predictor. */
unsigned localPredictorMask;
/** Number of bits of the local predictor's counters. */
unsigned localCtrBits;

View file

@ -65,6 +65,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@ -79,6 +80,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<bool> defer_registration;
Param<bool> exitOnError;
Param<bool> updateOnError;
Param<bool> warnOnlyOnLoadError;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@ -95,6 +97,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@ -110,6 +113,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"),
INIT_PARAM(updateOnError, "Update the checker with the main CPU's state on error"),
INIT_PARAM_DFLT(warnOnlyOnLoadError, "warn, but don't exit, if a load "
"result errors", false),
INIT_PARAM(function_trace, "Enable function trace"),
@ -128,6 +132,7 @@ CREATE_SIM_OBJECT(OzoneChecker)
params->max_loads_any_thread = 0;
params->max_loads_all_threads = 0;
params->exitOnError = exitOnError;
params->updateOnError = updateOnError;
params->warnOnlyOnLoadError = warnOnlyOnLoadError;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
@ -140,6 +145,9 @@ CREATE_SIM_OBJECT(OzoneChecker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
Tick temp2 = progress_interval;
temp2++;
params->progress_interval = 0;
#if FULL_SYSTEM
params->itb = itb;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,6 +33,7 @@
#include <set>
#include "arch/regfile.hh"
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "config/full_system.hh"
@ -81,13 +82,13 @@ template <class>
class Checker;
/**
* Declaration of Out-of-Order CPU class. Basically it is a SimpleCPU with
* simple out-of-order capabilities added to it. It is still a 1 CPI machine
* (?), but is capable of handling cache misses. Basically it models having
* a ROB/IQ by only allowing a certain amount of instructions to execute while
* the cache miss is outstanding.
* Light weight out of order CPU model that approximates an out of
* order CPU. It is separated into a front end and a back end, with
* the template parameter Impl describing the classes used for each.
* The goal is to be able to specify through the Impl the class to use
* for the front end and back end, with different classes used to
* model different levels of detail.
*/
template <class Impl>
class OzoneCPU : public BaseCPU
{
@ -273,6 +274,7 @@ class OzoneCPU : public BaseCPU
typedef OzoneThreadState<Impl> ImplState;
private:
// Committed thread state for the OzoneCPU.
OzoneThreadState<Impl> thread;
public:
@ -310,12 +312,6 @@ class OzoneCPU : public BaseCPU
tickEvent.squash();
}
private:
Trace::InstRecord *traceData;
template<typename T>
void trace_data(T data);
public:
enum Status {
Running,
@ -326,8 +322,6 @@ class OzoneCPU : public BaseCPU
Status _status;
public:
bool checkInterrupts;
void post_interrupt(int int_num, int index);
void zero_fill_64(Addr addr) {
@ -379,6 +373,7 @@ class OzoneCPU : public BaseCPU
FrontEnd *frontEnd;
BackEnd *backEnd;
private:
Status status() const { return _status; }
void setStatus(Status new_status) { _status = new_status; }
@ -410,12 +405,11 @@ class OzoneCPU : public BaseCPU
// number of idle cycles
Stats::Average<> notIdleFraction;
Stats::Formula idleFraction;
public:
public:
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string &section);
#if FULL_SYSTEM
/** Translates instruction requestion. */
Fault translateInstReq(RequestPtr &req, OzoneThreadState<Impl> *thread)
@ -582,12 +576,9 @@ class OzoneCPU : public BaseCPU
Fault copy(Addr dest);
InstSeqNum globalSeqNum;
public:
void squashFromTC();
// @todo: This can be a useful debug function. Implement it.
void dumpInsts() { frontEnd->dumpInsts(); }
#if FULL_SYSTEM
@ -605,7 +596,6 @@ class OzoneCPU : public BaseCPU
ThreadContext *tcBase() { return tc; }
bool decoupledFrontEnd;
struct CommStruct {
InstSeqNum doneSeqNum;
InstSeqNum nonSpecSeqNum;
@ -614,8 +604,13 @@ class OzoneCPU : public BaseCPU
bool stall;
};
InstSeqNum globalSeqNum;
TimeBuffer<CommStruct> comm;
bool decoupledFrontEnd;
bool lockFlag;
Stats::Scalar<> quiesceCycles;

View file

@ -63,6 +63,7 @@ SimObjectParam<System *> system;
Param<int> cpu_id;
SimObjectParam<AlphaITB *> itb;
SimObjectParam<AlphaDTB *> dtb;
Param<Tick> profile;
#else
SimObjectVectorParam<Process *> workload;
//SimObjectParam<PageTable *> page_table;
@ -76,16 +77,18 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
//SimObjectParam<BaseCache *> icache;
//SimObjectParam<BaseCache *> dcache;
Param<unsigned> cachePorts;
Param<unsigned> width;
Param<unsigned> frontEndLatency;
Param<unsigned> frontEndWidth;
Param<unsigned> backEndLatency;
Param<unsigned> backEndWidth;
Param<unsigned> backEndSquashLatency;
Param<unsigned> backEndLatency;
Param<unsigned> maxInstBufferSize;
Param<unsigned> numPhysicalRegs;
Param<unsigned> maxOutstandingMemOps;
@ -140,6 +143,7 @@ Param<unsigned> RASSize;
Param<unsigned> LQEntries;
Param<unsigned> SQEntries;
Param<bool> lsqLimits;
Param<unsigned> LFSTSize;
Param<unsigned> SSITSize;
@ -181,6 +185,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
INIT_PARAM(cpu_id, "processor ID"),
INIT_PARAM(itb, "Instruction translation buffer"),
INIT_PARAM(dtb, "Data translation buffer"),
INIT_PARAM(profile, ""),
#else
INIT_PARAM(workload, "Processes to run"),
// INIT_PARAM(page_table, "Page table"),
@ -204,16 +209,18 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
"Terminate when all threads have reached this load"
"count",
0),
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
// INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
// INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
INIT_PARAM_DFLT(cachePorts, "Cache Ports", 200),
INIT_PARAM_DFLT(width, "Width", 1),
INIT_PARAM_DFLT(frontEndLatency, "Front end latency", 1),
INIT_PARAM_DFLT(frontEndWidth, "Front end width", 1),
INIT_PARAM_DFLT(backEndLatency, "Back end latency", 1),
INIT_PARAM_DFLT(backEndWidth, "Back end width", 1),
INIT_PARAM_DFLT(backEndSquashLatency, "Back end squash latency", 1),
INIT_PARAM_DFLT(backEndLatency, "Back end latency", 1),
INIT_PARAM_DFLT(maxInstBufferSize, "Maximum instruction buffer size", 16),
INIT_PARAM(numPhysicalRegs, "Number of physical registers"),
INIT_PARAM_DFLT(maxOutstandingMemOps, "Maximum outstanding memory operations", 4),
@ -274,6 +281,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
INIT_PARAM(LQEntries, "Number of load queue entries"),
INIT_PARAM(SQEntries, "Number of store queue entries"),
INIT_PARAM_DFLT(lsqLimits, "LSQ size limits dispatch", true),
INIT_PARAM(LFSTSize, "Last fetched store table size"),
INIT_PARAM(SSITSize, "Store set ID table size"),
@ -336,6 +344,7 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
params->cpu_id = cpu_id;
params->itb = itb;
params->dtb = dtb;
params->profile = profile;
#else
params->workload = workload;
// params->pTable = page_table;
@ -347,6 +356,7 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
params->max_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
params->progress_interval = progress_interval;
//
// Caches
@ -357,6 +367,7 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
params->width = width;
params->frontEndWidth = frontEndWidth;
params->frontEndLatency = frontEndLatency;
params->backEndWidth = backEndWidth;
params->backEndSquashLatency = backEndSquashLatency;
params->backEndLatency = backEndLatency;
@ -414,6 +425,7 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
params->LQEntries = LQEntries;
params->SQEntries = SQEntries;
params->lsqLimits = lsqLimits;
params->SSITSize = SSITSize;
params->LFSTSize = LFSTSize;

View file

@ -35,7 +35,7 @@
#include "arch/isa_traits.hh" // For MachInst
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/exetrace.hh"
#include "cpu/ozone/cpu.hh"
@ -51,7 +51,6 @@
#include "arch/alpha/types.hh"
#include "arch/vtophys.hh"
#include "base/callback.hh"
//#include "base/remote_gdb.hh"
#include "cpu/profile.hh"
#include "kern/kernel_stats.hh"
#include "mem/physical.hh"
@ -69,15 +68,6 @@
using namespace TheISA;
template <class Impl>
template<typename T>
void
OzoneCPU<Impl>::trace_data(T data) {
if (traceData) {
traceData->setData(data);
}
}
template <class Impl>
OzoneCPU<Impl>::TickEvent::TickEvent(OzoneCPU *c, int w)
: Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w)
@ -128,6 +118,8 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
panic("Checker enabled but not compiled in!");
#endif
} else {
// If checker is not being used, then the xcProxy points
// directly to the CPU's ExecContext.
checker = NULL;
thread.tc = &ozoneTC;
tc = &ozoneTC;
@ -140,7 +132,7 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.setStatus(ThreadContext::Suspended);
#if FULL_SYSTEM
/***** All thread state stuff *****/
// Setup thread state stuff.
thread.cpu = this;
thread.setTid(0);
@ -189,12 +181,15 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
frontEnd->setBackEnd(backEnd);
backEnd->setFrontEnd(frontEnd);
decoupledFrontEnd = p->decoupledFrontEnd;
globalSeqNum = 1;
#if FULL_SYSTEM
checkInterrupts = false;
#endif
lockFlag = 0;
// Setup rename table, initializing all values to ready.
for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
thread.renameTable[i] = new DynInst(this);
thread.renameTable[i]->setResultReady();
@ -235,8 +230,6 @@ OzoneCPU<Impl>::OzoneCPU(Params *p)
thread.setVirtPort(virt_port);
#endif
lockFlag = 0;
DPRINTF(OzoneCPU, "OzoneCPU: Created Ozone cpu object.\n");
}
@ -249,6 +242,7 @@ template <class Impl>
void
OzoneCPU<Impl>::switchOut()
{
BaseCPU::switchOut();
switchCount = 0;
// Front end needs state from back end, so switch out the back end first.
backEnd->switchOut();
@ -259,6 +253,8 @@ template <class Impl>
void
OzoneCPU<Impl>::signalSwitched()
{
// Only complete the switchout when both the front end and back
// end have signalled they are ready to switch.
if (++switchCount == 2) {
backEnd->doSwitchOut();
frontEnd->doSwitchOut();
@ -268,6 +264,17 @@ OzoneCPU<Impl>::signalSwitched()
#endif
_status = SwitchedOut;
#ifndef NDEBUG
// Loop through all registers
for (int i = 0; i < AlphaISA::TotalNumRegs; ++i) {
assert(thread.renameTable[i] == frontEnd->renameTable[i]);
assert(thread.renameTable[i] == backEnd->renameTable[i]);
DPRINTF(OzoneCPU, "Checking if register %i matches.\n", i);
}
#endif
if (tickEvent.scheduled())
tickEvent.squash();
}
@ -280,13 +287,25 @@ OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
{
BaseCPU::takeOverFrom(oldCPU);
thread.trapPending = false;
thread.inSyscall = false;
backEnd->takeOverFrom();
frontEnd->takeOverFrom();
frontEnd->renameTable.copyFrom(thread.renameTable);
backEnd->renameTable.copyFrom(thread.renameTable);
assert(!tickEvent.scheduled());
#ifndef NDEBUG
// Check rename table.
for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
assert(thread.renameTable[i]->isResultReady());
}
#endif
// @todo: Fix hardcoded number
// Clear out any old information in time buffer.
for (int i = 0; i < 6; ++i) {
for (int i = 0; i < 15; ++i) {
comm.advance();
}
@ -318,6 +337,10 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
notIdleFraction++;
scheduleTickEvent(delay);
_status = Running;
#if FULL_SYSTEM
if (thread.quiesceEvent && thread.quiesceEvent->scheduled())
thread.quiesceEvent->deschedule();
#endif
thread.setStatus(ThreadContext::Active);
frontEnd->wakeFromQuiesce();
}
@ -395,7 +418,7 @@ template <class Impl>
void
OzoneCPU<Impl>::resetStats()
{
startNumInst = numInst;
// startNumInst = numInst;
notIdleFraction = (_status != Idle);
}
@ -443,6 +466,15 @@ OzoneCPU<Impl>::serialize(std::ostream &os)
ozoneTC.serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
// Use SimpleThread's ability to checkpoint to make it easier to
// write out the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp;
nameOut(os, csprintf("%s.xc.0", name()));
temp.copyTC(thread.getTC());
temp.serialize(os);
}
template <class Impl>
@ -453,6 +485,15 @@ OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_ENUM(_status);
ozoneTC.unserialize(cp, csprintf("%s.tc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
// Use SimpleThread's ability to checkpoint to make it easier to
// read in the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp;
temp.copyTC(thread.getTC());
temp.unserialize(cp, csprintf("%s.xc.0", section));
thread.getTC()->copyArchRegs(temp.getTC());
}
template <class Impl>
@ -707,11 +748,13 @@ OzoneCPU<Impl>::processInterrupts()
if (ipl && ipl > thread.readMiscReg(IPR_IPLR)) {
thread.setMiscReg(IPR_ISR, summary);
thread.setMiscReg(IPR_INTID, ipl);
#if USE_CHECKER
// @todo: Make this more transparent
if (checker) {
checker->threadBase()->setMiscReg(IPR_ISR, summary);
checker->threadBase()->setMiscReg(IPR_INTID, ipl);
}
#endif
Fault fault = new InterruptFault;
fault->invoke(thread.getTC());
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
@ -812,7 +855,9 @@ OzoneCPU<Impl>::OzoneTC::halt()
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::dumpFuncProfile()
{ }
{
thread->dumpFuncProfile();
}
#endif
template <class Impl>
@ -831,6 +876,7 @@ OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
copyArchRegs(old_context);
setCpuId(old_context->readCpuId());
thread->setInst(old_context->getInst());
#if !FULL_SYSTEM
setFuncExeInst(old_context->readFuncExeInst());
#else
@ -844,6 +890,7 @@ OzoneCPU<Impl>::OzoneTC::takeOverFrom(ThreadContext *old_context)
thread->quiesceEvent->tc = this;
}
// Copy kernel stats pointer from old context.
thread->kernelStats = old_context->getKernelStats();
// storeCondFailures = 0;
cpu->lockFlag = false;
@ -865,7 +912,11 @@ OzoneCPU<Impl>::OzoneTC::regStats(const std::string &name)
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::serialize(std::ostream &os)
{ }
{
// Once serialization is added, serialize the quiesce event and
// kernel stats. Will need to make sure there aren't multiple
// things that serialize them.
}
template <class Impl>
void
@ -898,16 +949,14 @@ template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::profileClear()
{
if (thread->profile)
thread->profile->clear();
thread->profileClear();
}
template <class Impl>
void
OzoneCPU<Impl>::OzoneTC::profileSample()
{
if (thread->profile)
thread->profile->sample(thread->profileNode, thread->profilePC);
thread->profileSample();
}
#endif
@ -918,7 +967,6 @@ OzoneCPU<Impl>::OzoneTC::getThreadNum()
return thread->readTid();
}
// Also somewhat obnoxious. Really only used for the TLB fault.
template <class Impl>
TheISA::MachInst
OzoneCPU<Impl>::OzoneTC::getInst()
@ -936,14 +984,20 @@ OzoneCPU<Impl>::OzoneTC::copyArchRegs(ThreadContext *tc)
cpu->frontEnd->setPC(thread->PC);
cpu->frontEnd->setNextPC(thread->nextPC);
for (int i = 0; i < TheISA::TotalNumRegs; ++i) {
if (i < TheISA::FP_Base_DepTag) {
thread->renameTable[i]->setIntResult(tc->readIntReg(i));
} else if (i < (TheISA::FP_Base_DepTag + TheISA::NumFloatRegs)) {
int fp_idx = i - TheISA::FP_Base_DepTag;
thread->renameTable[i]->setDoubleResult(
tc->readFloatReg(fp_idx, 64));
}
// First loop through the integer registers.
for (int i = 0; i < TheISA::NumIntRegs; ++i) {
/* DPRINTF(OzoneCPU, "Copying over register %i, had data %lli, "
"now has data %lli.\n",
i, thread->renameTable[i]->readIntResult(),
tc->readIntReg(i));
*/
thread->renameTable[i]->setIntResult(tc->readIntReg(i));
}
// Then loop through the floating point registers.
for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
int fp_idx = i + TheISA::FP_Base_DepTag;
thread->renameTable[fp_idx]->setIntResult(tc->readFloatRegBits(i));
}
#if !FULL_SYSTEM

View file

@ -34,6 +34,7 @@
#include <deque>
#include "arch/utility.hh"
#include "base/timebuf.hh"
#include "cpu/inst_seq.hh"
#include "cpu/o3/bpred_unit.hh"
#include "cpu/ozone/rename_table.hh"
@ -246,15 +247,21 @@ class FrontEnd
void dumpInsts();
private:
TimeBuffer<int> numInstsReady;
typedef typename std::deque<DynInstPtr> InstBuff;
typedef typename InstBuff::iterator InstBuffIt;
InstBuff feBuffer;
InstBuff instBuffer;
int instBufferSize;
int maxInstBufferSize;
int latency;
int width;
int freeRegs;

View file

@ -92,8 +92,10 @@ FrontEnd<Impl>::FrontEnd(Params *params)
: branchPred(params),
icachePort(this),
mem(params->mem),
numInstsReady(params->frontEndLatency, 0),
instBufferSize(0),
maxInstBufferSize(params->maxInstBufferSize),
latency(params->frontEndLatency),
width(params->frontEndWidth),
freeRegs(params->numPhysicalRegs),
numPhysRegs(params->numPhysicalRegs),
@ -326,6 +328,18 @@ FrontEnd<Impl>::tick()
if (switchedOut)
return;
for (int insts_to_queue = numInstsReady[-latency];
!instBuffer.empty() && insts_to_queue;
--insts_to_queue)
{
DPRINTF(FE, "Transferring instruction [sn:%lli] to the feBuffer\n",
instBuffer.front()->seqNum);
feBuffer.push_back(instBuffer.front());
instBuffer.pop_front();
}
numInstsReady.advance();
// @todo: Maybe I want to just have direct communication...
if (fromCommit->doneSeqNum) {
branchPred.update(fromCommit->doneSeqNum, 0);
@ -339,8 +353,8 @@ FrontEnd<Impl>::tick()
cacheBlkValid = true;
status = Running;
if (barrierInst)
status = SerializeBlocked;
// if (barrierInst)
// status = SerializeBlocked;
if (freeRegs <= 0)
status = RenameBlocked;
checkBE();
@ -414,11 +428,12 @@ FrontEnd<Impl>::tick()
// latency
instBuffer.push_back(inst);
++instBufferSize;
numInstsReady[0]++;
++num_inst;
#if FULL_SYSTEM
if (inst->isQuiesce()) {
warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
// warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
status = QuiescePending;
break;
}
@ -572,10 +587,10 @@ FrontEnd<Impl>::processBarriers(DynInstPtr &inst)
// Change status over to SerializeBlocked so that other stages know
// what this is blocked on.
status = SerializeBlocked;
// status = SerializeBlocked;
barrierInst = inst;
return true;
// barrierInst = inst;
// return true;
} else if ((inst->isStoreConditional() || inst->isSerializeAfter())
&& !inst->isSerializeHandled()) {
DPRINTF(FE, "Serialize after instruction encountered.\n");
@ -620,6 +635,7 @@ FrontEnd<Impl>::handleFault(Fault &fault)
instruction->fault = fault;
instruction->setCanIssue();
instBuffer.push_back(instruction);
numInstsReady[0]++;
++instBufferSize;
}
@ -649,6 +665,21 @@ FrontEnd<Impl>::squash(const InstSeqNum &squash_num, const Addr &next_PC,
freeRegs+= inst->numDestRegs();
}
while (!feBuffer.empty() &&
feBuffer.back()->seqNum > squash_num) {
DynInstPtr inst = feBuffer.back();
DPRINTF(FE, "Squashing instruction [sn:%lli] PC %#x\n",
inst->seqNum, inst->readPC());
inst->clearDependents();
feBuffer.pop_back();
--instBufferSize;
freeRegs+= inst->numDestRegs();
}
// Copy over rename table from the back end.
renameTable.copyFrom(backEnd->renameTable);
@ -666,12 +697,12 @@ FrontEnd<Impl>::squash(const InstSeqNum &squash_num, const Addr &next_PC,
DPRINTF(FE, "Squashing outstanding Icache access.\n");
memReq = NULL;
}
/*
if (status == SerializeBlocked) {
assert(barrierInst->seqNum > squash_num);
barrierInst = NULL;
}
*/
// Unless this squash originated from the front end, we're probably
// in running mode now.
// Actually might want to make this latency dependent.
@ -683,13 +714,22 @@ template <class Impl>
typename Impl::DynInstPtr
FrontEnd<Impl>::getInst()
{
if (instBufferSize == 0) {
if (feBuffer.empty()) {
return NULL;
}
DynInstPtr inst = instBuffer.front();
DynInstPtr inst = feBuffer.front();
instBuffer.pop_front();
if (inst->isSerializeBefore() || inst->isIprAccess()) {
DPRINTF(FE, "Back end is getting a serialize before inst\n");
if (!backEnd->robEmpty()) {
DPRINTF(FE, "Rob is not empty yet, not returning inst\n");
return NULL;
}
inst->clearSerializeBefore();
}
feBuffer.pop_front();
--instBufferSize;
@ -784,11 +824,11 @@ FrontEnd<Impl>::updateStatus()
}
if (status == BEBlocked && !be_block) {
if (barrierInst) {
status = SerializeBlocked;
} else {
// if (barrierInst) {
// status = SerializeBlocked;
// } else {
status = Running;
}
// }
ret_val = true;
}
return ret_val;
@ -810,6 +850,7 @@ template <class Impl>
typename Impl::DynInstPtr
FrontEnd<Impl>::getInstFromCacheline()
{
/*
if (status == SerializeComplete) {
DynInstPtr inst = barrierInst;
status = Running;
@ -817,7 +858,7 @@ FrontEnd<Impl>::getInstFromCacheline()
inst->clearSerializeBefore();
return inst;
}
*/
InstSeqNum inst_seq;
MachInst inst;
// @todo: Fix this magic number used here to handle word offset (and
@ -932,6 +973,7 @@ FrontEnd<Impl>::doSwitchOut()
squash(0, 0);
instBuffer.clear();
instBufferSize = 0;
feBuffer.clear();
status = Idle;
}

View file

@ -284,7 +284,7 @@ InorderBackEnd<Impl>::executeInsts()
}
inst->setExecuted();
inst->setCompleted();
inst->setResultReady();
inst->setCanCommit();
instList.pop_front();

View file

@ -850,13 +850,13 @@ template <class Impl>
void
InstQueue<Impl>::addReadyMemInst(DynInstPtr &ready_inst)
{
OpClass op_class = ready_inst->opClass();
// OpClass op_class = ready_inst->opClass();
readyInsts.push(ready_inst);
DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
"the ready list, PC %#x opclass:%i [sn:%lli].\n",
ready_inst->readPC(), op_class, ready_inst->seqNum);
ready_inst->readPC(), ready_inst->opClass(), ready_inst->seqNum);
}
/*
template <class Impl>
@ -1177,11 +1177,11 @@ InstQueue<Impl>::addIfReady(DynInstPtr &inst)
return;
}
OpClass op_class = inst->opClass();
// OpClass op_class = inst->opClass();
DPRINTF(IQ, "Instruction is ready to issue, putting it onto "
"the ready list, PC %#x opclass:%i [sn:%lli].\n",
inst->readPC(), op_class, inst->seqNum);
inst->readPC(), inst->opClass(), inst->seqNum);
readyInsts.push(inst);
}

View file

@ -80,7 +80,7 @@ class LWBackEnd
TimeBuffer<IssueToExec> i2e;
typename TimeBuffer<IssueToExec>::wire instsToExecute;
TimeBuffer<ExecToCommit> e2c;
TimeBuffer<Writeback> numInstsToWB;
TimeBuffer<int> numInstsToWB;
TimeBuffer<CommStruct> *comm;
typename TimeBuffer<CommStruct>::wire toIEW;
@ -139,7 +139,7 @@ class LWBackEnd
Tick lastCommitCycle;
bool robEmpty() { return instList.empty(); }
bool robEmpty() { return numInsts == 0; }
bool isFull() { return numInsts >= numROBEntries; }
bool isBlocked() { return status == Blocked || dispatchStatus == Blocked; }
@ -194,6 +194,7 @@ class LWBackEnd
}
void instToCommit(DynInstPtr &inst);
void readyInstsForCommit();
void switchOut();
void doSwitchOut();
@ -255,12 +256,13 @@ class LWBackEnd
RenameTable<Impl> renameTable;
private:
int latency;
// General back end width. Used if the more specific isn't given.
int width;
// Dispatch width.
int dispatchWidth;
int numDispatchEntries;
int dispatchSize;
int waitingInsts;
@ -285,6 +287,7 @@ class LWBackEnd
int numROBEntries;
int numInsts;
bool lsqLimits;
std::set<InstSeqNum> waitingMemOps;
typedef std::set<InstSeqNum>::iterator MemIt;
@ -295,9 +298,6 @@ class LWBackEnd
InstSeqNum squashSeqNum;
Addr squashNextPC;
Fault faultFromFetch;
bool fetchHasFault;
bool switchedOut;
bool switchPending;
@ -321,8 +321,6 @@ class LWBackEnd
std::list<DynInstPtr> replayList;
std::list<DynInstPtr> writeback;
int latency;
int squashLatency;
bool exactFullStall;
@ -331,37 +329,39 @@ class LWBackEnd
/* Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall;
*/
Stats::Vector<> rob_cap_events;
Stats::Vector<> rob_cap_inst_count;
Stats::Vector<> iq_cap_events;
Stats::Vector<> iq_cap_inst_count;
Stats::Vector<> robCapEvents;
Stats::Vector<> robCapInstCount;
Stats::Vector<> iqCapEvents;
Stats::Vector<> iqCapInstCount;
// total number of instructions executed
Stats::Vector<> exe_inst;
Stats::Vector<> exe_swp;
Stats::Vector<> exe_nop;
Stats::Vector<> exe_refs;
Stats::Vector<> exe_loads;
Stats::Vector<> exe_branches;
Stats::Vector<> exeInst;
Stats::Vector<> exeSwp;
Stats::Vector<> exeNop;
Stats::Vector<> exeRefs;
Stats::Vector<> exeLoads;
Stats::Vector<> exeBranches;
Stats::Vector<> issued_ops;
Stats::Vector<> issuedOps;
// total number of loads forwaded from LSQ stores
Stats::Vector<> lsq_forw_loads;
Stats::Vector<> lsqForwLoads;
// total number of loads ignored due to invalid addresses
Stats::Vector<> inv_addr_loads;
Stats::Vector<> invAddrLoads;
// total number of software prefetches ignored due to invalid addresses
Stats::Vector<> inv_addr_swpfs;
Stats::Vector<> invAddrSwpfs;
// ready loads blocked due to memory disambiguation
Stats::Vector<> lsq_blocked_loads;
Stats::Vector<> lsqBlockedLoads;
Stats::Scalar<> lsqInversion;
Stats::Vector<> n_issued_dist;
Stats::VectorDistribution<> issue_delay_dist;
Stats::Vector<> nIssuedDist;
/*
Stats::VectorDistribution<> issueDelayDist;
Stats::VectorDistribution<> queue_res_dist;
Stats::VectorDistribution<> queueResDist;
*/
/*
Stats::Vector<> stat_fu_busy;
Stats::Vector2d<> stat_fuBusy;
@ -379,37 +379,37 @@ class LWBackEnd
Stats::Formula commit_ipb;
Stats::Formula lsq_inv_rate;
*/
Stats::Vector<> writeback_count;
Stats::Vector<> producer_inst;
Stats::Vector<> consumer_inst;
Stats::Vector<> wb_penalized;
Stats::Vector<> writebackCount;
Stats::Vector<> producerInst;
Stats::Vector<> consumerInst;
Stats::Vector<> wbPenalized;
Stats::Formula wb_rate;
Stats::Formula wb_fanout;
Stats::Formula wb_penalized_rate;
Stats::Formula wbRate;
Stats::Formula wbFanout;
Stats::Formula wbPenalizedRate;
// total number of instructions committed
Stats::Vector<> stat_com_inst;
Stats::Vector<> stat_com_swp;
Stats::Vector<> stat_com_refs;
Stats::Vector<> stat_com_loads;
Stats::Vector<> stat_com_membars;
Stats::Vector<> stat_com_branches;
Stats::Vector<> statComInst;
Stats::Vector<> statComSwp;
Stats::Vector<> statComRefs;
Stats::Vector<> statComLoads;
Stats::Vector<> statComMembars;
Stats::Vector<> statComBranches;
Stats::Distribution<> n_committed_dist;
Stats::Distribution<> nCommittedDist;
Stats::Scalar<> commit_eligible_samples;
Stats::Vector<> commit_eligible;
Stats::Scalar<> commitEligibleSamples;
Stats::Vector<> commitEligible;
Stats::Vector<> squashedInsts;
Stats::Vector<> ROBSquashedInsts;
Stats::Scalar<> ROB_fcount;
Stats::Formula ROB_full_rate;
Stats::Scalar<> ROBFcount;
Stats::Formula ROBFullRate;
Stats::Vector<> ROB_count; // cumulative ROB occupancy
Stats::Formula ROB_occ_rate;
Stats::VectorDistribution<> ROB_occ_dist;
Stats::Vector<> ROBCount; // cumulative ROB occupancy
Stats::Formula ROBOccRate;
// Stats::VectorDistribution<> ROBOccDist;
public:
void dumpInsts();

View file

@ -141,13 +141,14 @@ LWBackEnd<Impl>::replayMemInst(DynInstPtr &inst)
template <class Impl>
LWBackEnd<Impl>::LWBackEnd(Params *params)
: d2i(5, 5), i2e(5, 5), e2c(5, 5), numInstsToWB(5, 5),
: d2i(5, 5), i2e(5, 5), e2c(5, 5), numInstsToWB(params->backEndLatency, 0),
trapSquash(false), tcSquash(false),
width(params->backEndWidth), exactFullStall(true)
latency(params->backEndLatency),
width(params->backEndWidth), lsqLimits(params->lsqLimits),
exactFullStall(true)
{
numROBEntries = params->numROBEntries;
numInsts = 0;
numDispatchEntries = 32;
maxOutstandingMemOps = params->maxOutstandingMemOps;
numWaitingMemOps = 0;
waitingInsts = 0;
@ -184,78 +185,79 @@ void
LWBackEnd<Impl>::regStats()
{
using namespace Stats;
rob_cap_events
LSQ.regStats();
robCapEvents
.init(cpu->number_of_threads)
.name(name() + ".ROB:cap_events")
.desc("number of cycles where ROB cap was active")
.flags(total)
;
rob_cap_inst_count
robCapInstCount
.init(cpu->number_of_threads)
.name(name() + ".ROB:cap_inst")
.desc("number of instructions held up by ROB cap")
.flags(total)
;
iq_cap_events
iqCapEvents
.init(cpu->number_of_threads)
.name(name() +".IQ:cap_events" )
.desc("number of cycles where IQ cap was active")
.flags(total)
;
iq_cap_inst_count
iqCapInstCount
.init(cpu->number_of_threads)
.name(name() + ".IQ:cap_inst")
.desc("number of instructions held up by IQ cap")
.flags(total)
;
exe_inst
exeInst
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:count")
.desc("number of insts issued")
.flags(total)
;
exe_swp
exeSwp
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:swp")
.desc("number of swp insts issued")
.flags(total)
;
exe_nop
exeNop
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:nop")
.desc("number of nop insts issued")
.flags(total)
;
exe_refs
exeRefs
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:refs")
.desc("number of memory reference insts issued")
.flags(total)
;
exe_loads
exeLoads
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:loads")
.desc("number of load insts issued")
.flags(total)
;
exe_branches
exeBranches
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:branches")
.desc("Number of branches issued")
.flags(total)
;
issued_ops
issuedOps
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:op_count")
.desc("number of insts issued")
@ -272,28 +274,28 @@ LWBackEnd<Impl>::regStats()
//
// Other stats
//
lsq_forw_loads
lsqForwLoads
.init(cpu->number_of_threads)
.name(name() + ".LSQ:forw_loads")
.desc("number of loads forwarded via LSQ")
.flags(total)
;
inv_addr_loads
invAddrLoads
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:addr_loads")
.desc("number of invalid-address loads")
.flags(total)
;
inv_addr_swpfs
invAddrSwpfs
.init(cpu->number_of_threads)
.name(name() + ".ISSUE:addr_swpfs")
.desc("number of invalid-address SW prefetches")
.flags(total)
;
lsq_blocked_loads
lsqBlockedLoads
.init(cpu->number_of_threads)
.name(name() + ".LSQ:blocked_loads")
.desc("number of ready loads not issued due to memory disambiguation")
@ -305,51 +307,52 @@ LWBackEnd<Impl>::regStats()
.desc("Number of times LSQ instruction issued early")
;
n_issued_dist
nIssuedDist
.init(issueWidth + 1)
.name(name() + ".ISSUE:issued_per_cycle")
.desc("Number of insts issued each cycle")
.flags(total | pdf | dist)
;
issue_delay_dist
/*
issueDelayDist
.init(Num_OpClasses,0,99,2)
.name(name() + ".ISSUE:")
.desc("cycles from operands ready to issue")
.flags(pdf | cdf)
;
queue_res_dist
queueResDist
.init(Num_OpClasses, 0, 99, 2)
.name(name() + ".IQ:residence:")
.desc("cycles from dispatch to issue")
.flags(total | pdf | cdf )
;
for (int i = 0; i < Num_OpClasses; ++i) {
queue_res_dist.subname(i, opClassStrings[i]);
queueResDist.subname(i, opClassStrings[i]);
}
writeback_count
*/
writebackCount
.init(cpu->number_of_threads)
.name(name() + ".WB:count")
.desc("cumulative count of insts written-back")
.flags(total)
;
producer_inst
producerInst
.init(cpu->number_of_threads)
.name(name() + ".WB:producers")
.desc("num instructions producing a value")
.flags(total)
;
consumer_inst
consumerInst
.init(cpu->number_of_threads)
.name(name() + ".WB:consumers")
.desc("num instructions consuming a value")
.flags(total)
;
wb_penalized
wbPenalized
.init(cpu->number_of_threads)
.name(name() + ".WB:penalized")
.desc("number of instrctions required to write to 'other' IQ")
@ -357,71 +360,71 @@ LWBackEnd<Impl>::regStats()
;
wb_penalized_rate
wbPenalizedRate
.name(name() + ".WB:penalized_rate")
.desc ("fraction of instructions written-back that wrote to 'other' IQ")
.flags(total)
;
wb_penalized_rate = wb_penalized / writeback_count;
wbPenalizedRate = wbPenalized / writebackCount;
wb_fanout
wbFanout
.name(name() + ".WB:fanout")
.desc("average fanout of values written-back")
.flags(total)
;
wb_fanout = producer_inst / consumer_inst;
wbFanout = producerInst / consumerInst;
wb_rate
wbRate
.name(name() + ".WB:rate")
.desc("insts written-back per cycle")
.flags(total)
;
wb_rate = writeback_count / cpu->numCycles;
wbRate = writebackCount / cpu->numCycles;
stat_com_inst
statComInst
.init(cpu->number_of_threads)
.name(name() + ".COM:count")
.desc("Number of instructions committed")
.flags(total)
;
stat_com_swp
statComSwp
.init(cpu->number_of_threads)
.name(name() + ".COM:swp_count")
.desc("Number of s/w prefetches committed")
.flags(total)
;
stat_com_refs
statComRefs
.init(cpu->number_of_threads)
.name(name() + ".COM:refs")
.desc("Number of memory references committed")
.flags(total)
;
stat_com_loads
statComLoads
.init(cpu->number_of_threads)
.name(name() + ".COM:loads")
.desc("Number of loads committed")
.flags(total)
;
stat_com_membars
statComMembars
.init(cpu->number_of_threads)
.name(name() + ".COM:membars")
.desc("Number of memory barriers committed")
.flags(total)
;
stat_com_branches
statComBranches
.init(cpu->number_of_threads)
.name(name() + ".COM:branches")
.desc("Number of branches committed")
.flags(total)
;
n_committed_dist
nCommittedDist
.init(0,commitWidth,1)
.name(name() + ".COM:committed_per_cycle")
.desc("Number of insts commited each cycle")
@ -441,14 +444,14 @@ LWBackEnd<Impl>::regStats()
// -> The standard deviation is computed only over cycles where
// we reached the BW limit
//
commit_eligible
commitEligible
.init(cpu->number_of_threads)
.name(name() + ".COM:bw_limited")
.desc("number of insts not committed due to BW limits")
.flags(total)
;
commit_eligible_samples
commitEligibleSamples
.name(name() + ".COM:bw_lim_events")
.desc("number cycles where commit BW limit reached")
;
@ -465,37 +468,38 @@ LWBackEnd<Impl>::regStats()
.desc("Number of instructions removed from inst list when they reached the head of the ROB")
;
ROB_fcount
ROBFcount
.name(name() + ".ROB:full_count")
.desc("number of cycles where ROB was full")
;
ROB_count
ROBCount
.init(cpu->number_of_threads)
.name(name() + ".ROB:occupancy")
.desc(name() + ".ROB occupancy (cumulative)")
.flags(total)
;
ROB_full_rate
ROBFullRate
.name(name() + ".ROB:full_rate")
.desc("ROB full per cycle")
;
ROB_full_rate = ROB_fcount / cpu->numCycles;
ROBFullRate = ROBFcount / cpu->numCycles;
ROB_occ_rate
ROBOccRate
.name(name() + ".ROB:occ_rate")
.desc("ROB occupancy rate")
.flags(total)
;
ROB_occ_rate = ROB_count / cpu->numCycles;
ROB_occ_dist
ROBOccRate = ROBCount / cpu->numCycles;
/*
ROBOccDist
.init(cpu->number_of_threads,0,numROBEntries,2)
.name(name() + ".ROB:occ_dist")
.desc("ROB Occupancy per cycle")
.flags(total | cdf)
;
*/
}
template <class Impl>
@ -588,18 +592,22 @@ LWBackEnd<Impl>::tick()
{
DPRINTF(BE, "Ticking back end\n");
// Read in any done instruction information and update the IQ or LSQ.
updateStructures();
if (switchPending && robEmpty() && !LSQ.hasStoresToWB()) {
cpu->signalSwitched();
return;
}
ROB_count[0]+= numInsts;
readyInstsForCommit();
numInstsToWB.advance();
ROBCount[0]+= numInsts;
wbCycle = 0;
// Read in any done instruction information and update the IQ or LSQ.
updateStructures();
#if FULL_SYSTEM
checkInterrupts();
#endif
@ -674,6 +682,10 @@ LWBackEnd<Impl>::dispatchInsts()
while (numInsts < numROBEntries &&
numWaitingMemOps < maxOutstandingMemOps) {
// Get instruction from front of time buffer
if (lsqLimits && LSQ.isFull()) {
break;
}
DynInstPtr inst = frontEnd->getInst();
if (!inst) {
break;
@ -732,6 +744,7 @@ LWBackEnd<Impl>::dispatchInsts()
inst->setIssued();
inst->setExecuted();
inst->setCanCommit();
numInstsToWB[0]++;
} else {
DPRINTF(BE, "Instruction [sn:%lli] ready, addding to "
"exeList.\n",
@ -866,8 +879,17 @@ LWBackEnd<Impl>::executeInsts()
if (inst->isLoad()) {
LSQ.executeLoad(inst);
} else if (inst->isStore()) {
LSQ.executeStore(inst);
if (inst->req && !(inst->req->getFlags() & LOCKED)) {
Fault fault = LSQ.executeStore(inst);
if (!inst->isStoreConditional() && fault == NoFault) {
inst->setExecuted();
instToCommit(inst);
} else if (fault != NoFault) {
// If the instruction faulted, then we need to send it along to commit
// without the instruction completing.
// Send this instruction to commit, also make sure iew stage
// realizes there is activity.
inst->setExecuted();
instToCommit(inst);
@ -908,36 +930,54 @@ LWBackEnd<Impl>::executeInsts()
}
}
issued_ops[0]+= num_executed;
n_issued_dist[num_executed]++;
issuedOps[0]+= num_executed;
nIssuedDist[num_executed]++;
}
template<class Impl>
void
LWBackEnd<Impl>::instToCommit(DynInstPtr &inst)
{
DPRINTF(BE, "Sending instructions to commit [sn:%lli] PC %#x.\n",
inst->seqNum, inst->readPC());
if (!inst->isSquashed()) {
DPRINTF(BE, "Writing back instruction [sn:%lli] PC %#x.\n",
inst->seqNum, inst->readPC());
inst->setCanCommit();
if (inst->isExecuted()) {
inst->setResultReady();
int dependents = wakeDependents(inst);
if (dependents) {
producer_inst[0]++;
consumer_inst[0]+= dependents;
producerInst[0]++;
consumerInst[0]+= dependents;
}
}
}
writeback_count[0]++;
writeback.push_back(inst);
numInstsToWB[0]++;
writebackCount[0]++;
}
template <class Impl>
void
LWBackEnd<Impl>::readyInstsForCommit()
{
for (int i = numInstsToWB[-latency];
!writeback.empty() && i;
--i)
{
DynInstPtr inst = writeback.front();
writeback.pop_front();
if (!inst->isSquashed()) {
DPRINTF(BE, "Writing back instruction [sn:%lli] PC %#x.\n",
inst->seqNum, inst->readPC());
inst->setCanCommit();
}
}
}
#if 0
template <class Impl>
void
@ -1010,7 +1050,7 @@ LWBackEnd<Impl>::commitInst(int inst_num)
// or store inst. Signal backwards that it should be executed.
if (!inst->isExecuted()) {
if (inst->isNonSpeculative() ||
inst->isStoreConditional() ||
(inst->isStoreConditional() && inst->getFault() == NoFault) ||
inst->isMemBarrier() ||
inst->isWriteBarrier()) {
#if !FULL_SYSTEM
@ -1151,6 +1191,20 @@ LWBackEnd<Impl>::commitInst(int inst_num)
++freed_regs;
}
#if FULL_SYSTEM
if (thread->profile) {
// bool usermode =
// (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
// thread->profilePC = usermode ? 1 : inst->readPC();
thread->profilePC = inst->readPC();
ProfileNode *node = thread->profile->consume(thread->getTC(),
inst->staticInst);
if (node)
thread->profileNode = node;
}
#endif
if (inst->traceData) {
inst->traceData->setFetchSeq(inst->seqNum);
inst->traceData->setCPSeq(thread->numInst);
@ -1158,6 +1212,9 @@ LWBackEnd<Impl>::commitInst(int inst_num)
inst->traceData = NULL;
}
if (inst->isCopy())
panic("Should not commit any copy instructions!");
inst->clearDependents();
frontEnd->addFreeRegs(freed_regs);
@ -1207,9 +1264,9 @@ LWBackEnd<Impl>::commitInsts()
while (!instList.empty() && inst_num < commitWidth) {
if (instList.back()->isSquashed()) {
instList.back()->clearDependents();
ROBSquashedInsts[instList.back()->threadNumber]++;
instList.pop_back();
--numInsts;
ROBSquashedInsts[instList.back()->threadNumber]++;
continue;
}
@ -1221,7 +1278,7 @@ LWBackEnd<Impl>::commitInsts()
break;
}
}
n_committed_dist.sample(inst_num);
nCommittedDist.sample(inst_num);
}
template <class Impl>
@ -1231,10 +1288,10 @@ LWBackEnd<Impl>::squash(const InstSeqNum &sn)
LSQ.squash(sn);
int freed_regs = 0;
InstListIt waiting_list_end = waitingList.end();
InstListIt insts_end_it = waitingList.end();
InstListIt insts_it = waitingList.begin();
while (insts_it != waiting_list_end && (*insts_it)->seqNum > sn)
while (insts_it != insts_end_it && (*insts_it)->seqNum > sn)
{
if ((*insts_it)->isSquashed()) {
++insts_it;
@ -1260,6 +1317,7 @@ LWBackEnd<Impl>::squash(const InstSeqNum &sn)
while (!instList.empty() && (*insts_it)->seqNum > sn)
{
if ((*insts_it)->isSquashed()) {
panic("Instruction should not be already squashed and on list!");
++insts_it;
continue;
}
@ -1291,18 +1349,6 @@ LWBackEnd<Impl>::squash(const InstSeqNum &sn)
--numInsts;
}
insts_it = waitingList.begin();
while (!waitingList.empty() && insts_it != waitingList.end()) {
if ((*insts_it)->seqNum < sn) {
++insts_it;
continue;
}
assert((*insts_it)->isSquashed());
waitingList.erase(insts_it++);
waitingInsts--;
}
while (memBarrier && memBarrier->seqNum > sn) {
DPRINTF(BE, "[sn:%lli] Memory barrier squashed (or previously "
"squashed)\n", memBarrier->seqNum);
@ -1320,6 +1366,18 @@ LWBackEnd<Impl>::squash(const InstSeqNum &sn)
}
}
insts_it = replayList.begin();
insts_end_it = replayList.end();
while (!replayList.empty() && insts_it != insts_end_it) {
if ((*insts_it)->seqNum < sn) {
++insts_it;
continue;
}
assert((*insts_it)->isSquashed());
replayList.erase(insts_it++);
}
frontEnd->addFreeRegs(freed_regs);
}
@ -1390,14 +1448,6 @@ LWBackEnd<Impl>::squashDueToMemBlocked(DynInstPtr &inst)
frontEnd->squash(inst->seqNum - 1, inst->readPC());
}
template <class Impl>
void
LWBackEnd<Impl>::fetchFault(Fault &fault)
{
faultFromFetch = fault;
fetchHasFault = true;
}
template <class Impl>
void
LWBackEnd<Impl>::switchOut()
@ -1416,17 +1466,25 @@ LWBackEnd<Impl>::doSwitchOut()
// yet written back.
assert(robEmpty());
assert(!LSQ.hasStoresToWB());
writeback.clear();
for (int i = 0; i < numInstsToWB.getSize() + 1; ++i)
numInstsToWB.advance();
// squash(0);
assert(waitingList.empty());
assert(instList.empty());
assert(replayList.empty());
assert(writeback.empty());
LSQ.switchOut();
squash(0);
}
template <class Impl>
void
LWBackEnd<Impl>::takeOverFrom(ThreadContext *old_tc)
{
switchedOut = false;
assert(!squashPending);
squashSeqNum = 0;
squashNextPC = 0;
tcSquash = false;
trapSquash = false;
@ -1451,27 +1509,27 @@ LWBackEnd<Impl>::updateExeInstStats(DynInstPtr &inst)
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch())
exe_swp[thread_number]++;
exeSwp[thread_number]++;
else
exe_inst[thread_number]++;
exeInst[thread_number]++;
#else
exe_inst[thread_number]++;
exeInst[thread_number]++;
#endif
//
// Control operations
//
if (inst->isControl())
exe_branches[thread_number]++;
exeBranches[thread_number]++;
//
// Memory operations
//
if (inst->isMemRef()) {
exe_refs[thread_number]++;
exeRefs[thread_number]++;
if (inst->isLoad())
exe_loads[thread_number]++;
exeLoads[thread_number]++;
}
}
@ -1491,33 +1549,33 @@ LWBackEnd<Impl>::updateComInstStats(DynInstPtr &inst)
//
#ifdef TARGET_ALPHA
if (inst->isDataPrefetch()) {
stat_com_swp[tid]++;
statComSwp[tid]++;
} else {
stat_com_inst[tid]++;
statComInst[tid]++;
}
#else
stat_com_inst[tid]++;
statComInst[tid]++;
#endif
//
// Control Instructions
//
if (inst->isControl())
stat_com_branches[tid]++;
statComBranches[tid]++;
//
// Memory references
//
if (inst->isMemRef()) {
stat_com_refs[tid]++;
statComRefs[tid]++;
if (inst->isLoad()) {
stat_com_loads[tid]++;
statComLoads[tid]++;
}
}
if (inst->isMemBarrier()) {
stat_com_membars[tid]++;
statComMembars[tid]++;
}
}
@ -1569,6 +1627,45 @@ LWBackEnd<Impl>::dumpInsts()
++num;
}
inst_list_it = --(writeback.end());
cprintf("Writeback list size: %i\n", writeback.size());
while (inst_list_it != writeback.end())
{
cprintf("Instruction:%i\n",
num);
if (!(*inst_list_it)->isSquashed()) {
if (!(*inst_list_it)->isIssued()) {
++valid_num;
cprintf("Count:%i\n", valid_num);
} else if ((*inst_list_it)->isMemRef() &&
!(*inst_list_it)->memOpDone) {
// Loads that have not been marked as executed still count
// towards the total instructions.
++valid_num;
cprintf("Count:%i\n", valid_num);
}
}
cprintf("PC:%#x\n[sn:%lli]\n[tid:%i]\n"
"Issued:%i\nSquashed:%i\n",
(*inst_list_it)->readPC(),
(*inst_list_it)->seqNum,
(*inst_list_it)->threadNumber,
(*inst_list_it)->isIssued(),
(*inst_list_it)->isSquashed());
if ((*inst_list_it)->isMemRef()) {
cprintf("MemOpDone:%i\n", (*inst_list_it)->memOpDone);
}
cprintf("\n");
inst_list_it--;
++num;
}
cprintf("Waiting list size: %i\n", waitingList.size());
inst_list_it = --(waitingList.end());

View file

@ -84,6 +84,8 @@ class OzoneLWLSQ {
/** Returns the name of the LSQ unit. */
std::string name() const;
void regStats();
/** Sets the CPU pointer. */
void setCPU(OzoneCPU *cpu_ptr);
@ -179,7 +181,7 @@ class OzoneLWLSQ {
int numLoads() { return loads; }
/** Returns the number of stores in the SQ. */
int numStores() { return stores; }
int numStores() { return stores + storesInFlight; }
/** Returns if either the LQ or SQ is full. */
bool isFull() { return lqFull() || sqFull(); }
@ -188,7 +190,7 @@ class OzoneLWLSQ {
bool lqFull() { return loads >= (LQEntries - 1); }
/** Returns if the SQ is full. */
bool sqFull() { return stores >= (SQEntries - 1); }
bool sqFull() { return (stores + storesInFlight) >= (SQEntries - 1); }
/** Debugging function to dump instructions in the LSQ. */
void dumpInsts();
@ -223,7 +225,9 @@ class OzoneLWLSQ {
void storePostSend(Packet *pkt, DynInstPtr &inst);
/** Completes the store at the specified index. */
void completeStore(int store_idx);
void completeStore(DynInstPtr &inst);
void removeStore(int store_idx);
/** Handles doing the retry. */
void recvRetry();
@ -394,6 +398,10 @@ class OzoneLWLSQ {
int storesToWB;
public:
int storesInFlight;
private:
/// @todo Consider moving to a more advanced model with write vs read ports
/** The number of cache ports available each cycle. */
int cachePorts;
@ -403,6 +411,9 @@ class OzoneLWLSQ {
//list<InstSeqNum> mshrSeqNums;
/** Tota number of memory ordering violations. */
Stats::Scalar<> lsqMemOrderViolation;
//Stats::Scalar<> dcacheStallCycles;
Counter lastDcacheStall;
@ -525,7 +536,7 @@ OzoneLWLSQ<Impl>::read(RequestPtr req, T &data, int load_idx)
store_size = (*sq_it).size;
if (store_size == 0) {
if (store_size == 0 || (*sq_it).committed) {
sq_it++;
continue;
}

View file

@ -121,7 +121,7 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
}
if (inst->isStore()) {
completeStore(state->idx);
completeStore(inst);
}
}
@ -132,7 +132,7 @@ OzoneLWLSQ<Impl>::completeDataAccess(PacketPtr pkt)
template <class Impl>
OzoneLWLSQ<Impl>::OzoneLWLSQ()
: switchedOut(false), dcachePort(this), loads(0), stores(0),
storesToWB(0), stalled(false), isStoreBlocked(false),
storesToWB(0), storesInFlight(0), stalled(false), isStoreBlocked(false),
isLoadBlocked(false), loadBlockedHandled(false)
{
}
@ -171,6 +171,15 @@ OzoneLWLSQ<Impl>::name() const
return "lsqunit";
}
template<class Impl>
void
OzoneLWLSQ<Impl>::regStats()
{
lsqMemOrderViolation
.name(name() + ".memOrderViolation")
.desc("Number of memory ordering violations");
}
template<class Impl>
void
OzoneLWLSQ<Impl>::setCPU(OzoneCPU *cpu_ptr)
@ -321,7 +330,7 @@ unsigned
OzoneLWLSQ<Impl>::numFreeEntries()
{
unsigned free_lq_entries = LQEntries - loads;
unsigned free_sq_entries = SQEntries - stores;
unsigned free_sq_entries = SQEntries - (stores + storesInFlight);
// Both the LQ and SQ entries have an extra dummy entry to differentiate
// empty/full conditions. Subtract 1 from the free entries.
@ -385,6 +394,9 @@ OzoneLWLSQ<Impl>::executeLoad(DynInstPtr &inst)
// Actually probably want the oldest faulting load
if (load_fault != NoFault) {
DPRINTF(OzoneLSQ, "Load [sn:%lli] has a fault\n", inst->seqNum);
if (!(inst->req->getFlags() & UNCACHEABLE && !inst->isAtCommit())) {
inst->setExecuted();
}
// Maybe just set it as can commit here, although that might cause
// some other problems with sending traps to the ROB too quickly.
be->instToCommit(inst);
@ -461,6 +473,7 @@ OzoneLWLSQ<Impl>::executeStore(DynInstPtr &store_inst)
// A load incorrectly passed this store. Squash and refetch.
// For now return a fault to show that it was unsuccessful.
memDepViolator = (*lq_it);
++lsqMemOrderViolation;
return TheISA::genMachineCheckFault();
}
@ -553,8 +566,8 @@ OzoneLWLSQ<Impl>::writebackStores()
if ((*sq_it).size == 0 && !(*sq_it).completed) {
sq_it--;
completeStore(inst->sqIdx);
removeStore(inst->sqIdx);
completeStore(inst);
continue;
}
@ -626,6 +639,8 @@ OzoneLWLSQ<Impl>::writebackStores()
inst->sqIdx,inst->readPC(),
req->paddr, *(req->data),
inst->seqNum);
DPRINTF(OzoneLSQ, "StoresInFlight: %i\n",
storesInFlight + 1);
if (dcacheInterface) {
assert(!req->completionEvent);
@ -687,6 +702,8 @@ OzoneLWLSQ<Impl>::writebackStores()
}
sq_it--;
}
++storesInFlight;
// removeStore(inst->sqIdx);
} else {
panic("Must HAVE DCACHE!!!!!\n");
}
@ -704,7 +721,7 @@ void
OzoneLWLSQ<Impl>::squash(const InstSeqNum &squashed_num)
{
DPRINTF(OzoneLSQ, "Squashing until [sn:%lli]!"
"(Loads:%i Stores:%i)\n",squashed_num,loads,stores);
"(Loads:%i Stores:%i)\n",squashed_num,loads,stores+storesInFlight);
LQIt lq_it = loadQueue.begin();
@ -881,7 +898,7 @@ OzoneLWLSQ<Impl>::writeback(DynInstPtr &inst, PacketPtr pkt)
template <class Impl>
void
OzoneLWLSQ<Impl>::completeStore(int store_idx)
OzoneLWLSQ<Impl>::removeStore(int store_idx)
{
SQHashIt sq_hash_it = SQItHash.find(store_idx);
assert(sq_hash_it != SQItHash.end());
@ -891,8 +908,6 @@ OzoneLWLSQ<Impl>::completeStore(int store_idx)
(*sq_it).completed = true;
DynInstPtr inst = (*sq_it).inst;
--storesToWB;
if (isStalled() &&
inst->seqNum == stallingStoreIsn) {
DPRINTF(OzoneLSQ, "Unstalling, stalling store [sn:%lli] "
@ -910,6 +925,13 @@ OzoneLWLSQ<Impl>::completeStore(int store_idx)
SQItHash.erase(sq_hash_it);
SQIndices.push(inst->sqIdx);
storeQueue.erase(sq_it);
}
template <class Impl>
void
OzoneLWLSQ<Impl>::completeStore(DynInstPtr &inst)
{
--storesToWB;
--stores;
inst->setCompleted();
@ -935,9 +957,14 @@ OzoneLWLSQ<Impl>::switchOut()
switchedOut = true;
// Clear the queue to free up resources
assert(stores == 0);
assert(storeQueue.empty());
assert(loads == 0);
assert(loadQueue.empty());
assert(storesInFlight == 0);
storeQueue.clear();
loadQueue.clear();
loads = stores = storesToWB = 0;
loads = stores = storesToWB = storesInFlight = 0;
}
template <class Impl>

View file

@ -71,10 +71,11 @@ class SimpleParams : public BaseCPU::Params
unsigned cachePorts;
unsigned width;
unsigned frontEndLatency;
unsigned frontEndWidth;
unsigned backEndLatency;
unsigned backEndWidth;
unsigned backEndSquashLatency;
unsigned backEndLatency;
unsigned maxInstBufferSize;
unsigned numPhysicalRegs;
unsigned maxOutstandingMemOps;
@ -150,6 +151,7 @@ class SimpleParams : public BaseCPU::Params
//
unsigned LQEntries;
unsigned SQEntries;
bool lsqLimits;
//
// Memory dependence

View file

@ -34,9 +34,12 @@
#include "arch/faults.hh"
#include "arch/types.hh"
#include "arch/regfile.hh"
#include "base/callback.hh"
#include "base/output.hh"
#include "cpu/thread_context.hh"
#include "cpu/thread_state.hh"
#include "sim/process.hh"
#include "sim/sim_exit.hh"
class Event;
//class Process;
@ -65,8 +68,21 @@ struct OzoneThreadState : public ThreadState {
#if FULL_SYSTEM
OzoneThreadState(CPUType *_cpu, int _thread_num)
: ThreadState(-1, _thread_num),
intrflag(0), inSyscall(0), trapPending(0)
intrflag(0), cpu(_cpu), inSyscall(0), trapPending(0)
{
if (cpu->params->profile) {
profile = new FunctionProfile(cpu->params->system->kernelSymtab);
Callback *cb =
new MakeCallback<OzoneThreadState,
&OzoneThreadState::dumpFuncProfile>(this);
registerExitCallback(cb);
}
// let's fill with a dummy node for now so we don't get a segfault
// on the first cycle when there's no node available.
static ProfileNode dummyNode;
profileNode = &dummyNode;
profilePC = 3;
miscRegFile.clear();
}
#else
@ -130,6 +146,14 @@ struct OzoneThreadState : public ThreadState {
void setNextPC(uint64_t val)
{ nextPC = val; }
#if FULL_SYSTEM
void dumpFuncProfile()
{
std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
profile->dump(tc, *os);
}
#endif
};
#endif // __CPU_OZONE_THREAD_STATE_HH__

View file

@ -170,7 +170,7 @@ BaseSimpleCPU::regStats()
void
BaseSimpleCPU::resetStats()
{
startNumInst = numInst;
// startNumInst = numInst;
// notIdleFraction = (_status != Idle);
}

View file

@ -162,6 +162,11 @@ SimpleThread::takeOverFrom(ThreadContext *oldContext)
if (quiesceEvent) {
quiesceEvent->tc = tc;
}
Kernel::Statistics *stats = oldContext->getKernelStats();
if (stats) {
kernelStats = stats;
}
#endif
storeCondFailures = 0;

View file

@ -32,6 +32,7 @@
#define __CPU_THREAD_STATE_HH__
#include "arch/types.hh"
#include "cpu/profile.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
@ -191,6 +192,7 @@ struct ThreadState {
// simulation only; all functional memory accesses should use
// one of the FunctionalMemory pointers above.
short asid;
#endif
/** Current instruction the thread is committing. Only set and

View file

@ -242,6 +242,10 @@ class IdeDisk : public SimObject
Stats::Scalar<> dmaWriteFullPages;
Stats::Scalar<> dmaWriteBytes;
Stats::Scalar<> dmaWriteTxs;
Stats::Formula rdBandwidth;
Stats::Formula wrBandwidth;
Stats::Formula totBandwidth;
Stats::Formula totBytes;
public:
/**

View file

@ -144,6 +144,8 @@ add_option("--trace-flags", metavar="FLAG[,FLAG]", action='append', split=',',
help="Sets the flags for tracing")
add_option("--trace-start", metavar="TIME", default='0s',
help="Start tracing at TIME (must have units)")
add_option("--trace-cycle", metavar="CYCLE", default='0',
help="Start tracing at CYCLE")
add_option("--trace-file", metavar="FILE", default="cout",
help="Sets the output file for tracing [Default: %default]")
add_option("--trace-circlebuf", metavar="SIZE", type="int", default=0,

View file

@ -26,6 +26,7 @@ class BaseCPU(SimObject):
"terminate when all threads have reached this load count")
max_loads_any_thread = Param.Counter(0,
"terminate when any thread reaches this load count")
progress_interval = Param.Tick(0, "interval to print out the progress message")
defer_registration = Param.Bool(False,
"defer registration with system (for sampling)")

View file

@ -9,6 +9,8 @@ class DerivO3CPU(BaseCPU):
activity = Param.Unsigned(0, "Initial count")
numThreads = Param.Unsigned(1, "number of HW thread contexts")
if build_env['FULL_SYSTEM']:
profile = Param.Latency('0ns', "trace the kernel stack")
if build_env['USE_CHECKER']:
if not build_env['FULL_SYSTEM']:
checker = Param.BaseCPU(O3Checker(workload=Parent.workload,

View file

@ -8,12 +8,15 @@ class DerivOzoneCPU(BaseCPU):
numThreads = Param.Unsigned("number of HW thread contexts")
checker = Param.BaseCPU("Checker CPU")
if build_env['FULL_SYSTEM']:
profile = Param.Latency('0ns', "trace the kernel stack")
icache_port = Port("Instruction Port")
dcache_port = Port("Data Port")
width = Param.Unsigned("Width")
frontEndWidth = Param.Unsigned("Front end width")
frontEndLatency = Param.Unsigned("Front end latency")
backEndWidth = Param.Unsigned("Back end width")
backEndSquashLatency = Param.Unsigned("Back end squash latency")
backEndLatency = Param.Unsigned("Back end latency")
@ -76,6 +79,7 @@ class DerivOzoneCPU(BaseCPU):
LQEntries = Param.Unsigned("Number of load queue entries")
SQEntries = Param.Unsigned("Number of store queue entries")
lsqLimits = Param.Bool(True, "LSQ size limits dispatch")
LFSTSize = Param.Unsigned("Last fetched store table size")
SSITSize = Param.Unsigned("Store set ID table size")

View file

@ -1,6 +1,7 @@
from m5.SimObject import SimObject
from m5.params import *
from Serialize import Serialize
from Serialize import Statreset
from Statistics import Statistics
from Trace import Trace
from ExeTrace import ExecutionTrace

View file

@ -16,6 +16,7 @@ class System(SimObject):
boot_osflags = Param.String("a", "boot flags to pass to the kernel")
kernel = Param.String("file that contains the kernel code")
readfile = Param.String("", "file to read startup script from")
symbolfile = Param.String("", "file to get the symbols from")
class AlphaSystem(System):
type = 'AlphaSystem'

View file

@ -46,6 +46,7 @@
#include "sim/host.hh" // for Tick
#include "base/fast_alloc.hh"
#include "base/misc.hh"
#include "base/trace.hh"
#include "sim/serialize.hh"
@ -135,7 +136,7 @@ class Event : public Serializable, public FastAlloc
/// same cycle (after unscheduling the old CPU's tick event).
/// The switch needs to come before any tick events to make
/// sure we don't tick both CPUs in the same cycle.
CPU_Switch_Pri = 31,
CPU_Switch_Pri = -31,
/// Serailization needs to occur before tick events also, so
/// that a serialize/unserialize is identical to an on-line
@ -351,7 +352,8 @@ inline void
Event::schedule(Tick t)
{
assert(!scheduled());
assert(t >= curTick);
// if (t < curTick)
// warn("t is less than curTick, ensure you don't want cycles");
setFlags(Scheduled);
#if TRACING_ON

View file

@ -148,6 +148,54 @@ namespace AlphaPseudo
exitSimLoop(when, "m5_exit instruction encountered");
}
void
loadsymbol(ThreadContext *tc)
{
const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
if (filename.empty()) {
return;
}
std::string buffer;
ifstream file(filename.c_str());
if (!file)
fatal("file error: Can't open symbol table file %s\n", filename);
while (!file.eof()) {
getline(file, buffer);
if (buffer.empty())
continue;
int idx = buffer.find(' ');
if (idx == string::npos)
continue;
string address = "0x" + buffer.substr(0, idx);
eat_white(address);
if (address.empty())
continue;
// Skip over letter and space
string symbol = buffer.substr(idx + 3);
eat_white(symbol);
if (symbol.empty())
continue;
Addr addr;
if (!to_number(address, addr))
continue;
if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
continue;
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
}
file.close();
}
void
resetstats(ThreadContext *tc, Tick delay, Tick period)
{

View file

@ -51,6 +51,7 @@ namespace AlphaPseudo
void ivle(ThreadContext *tc);
void m5exit(ThreadContext *tc, Tick delay);
void m5exit_old(ThreadContext *tc);
void loadsymbol(ThreadContext *xc);
void resetstats(ThreadContext *tc, Tick delay, Tick period);
void dumpstats(ThreadContext *tc, Tick delay, Tick period);
void dumpresetstats(ThreadContext *tc, Tick delay, Tick period);

View file

@ -52,6 +52,9 @@
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
// For stat reset hack
#include "sim/stat_control.hh"
using namespace std;
int Serializable::ckptMaxCount = 0;
@ -404,3 +407,36 @@ Checkpoint::sectionExists(const std::string &section)
{
return db->sectionExists(section);
}
/** Hacked stat reset event */
class StatresetParamContext : public ParamContext
{
public:
StatresetParamContext(const string &section);
~StatresetParamContext();
void startup();
};
StatresetParamContext statParams("statsreset");
Param<Tick> reset_cycle(&statParams, "reset_cycle",
"Cycle to reset stats on", 0);
StatresetParamContext::StatresetParamContext(const string &section)
: ParamContext(section)
{ }
StatresetParamContext::~StatresetParamContext()
{
}
void
StatresetParamContext::startup()
{
if (reset_cycle > 0) {
Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0);
cprintf("Stats reset event scheduled for %lli\n",
curTick + reset_cycle);
}
}

View file

@ -160,13 +160,13 @@ class StatEvent : public Event
Tick repeat;
public:
StatEvent(int _flags, Tick _when, Tick _repeat);
StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat);
virtual void process();
virtual const char *description();
};
StatEvent::StatEvent(int _flags, Tick _when, Tick _repeat)
: Event(&mainEventQueue, Stat_Event_Pri),
StatEvent::StatEvent(EventQueue *queue, int _flags, Tick _when, Tick _repeat)
: Event(queue, Stat_Event_Pri),
flags(_flags), repeat(_repeat)
{
setFlags(AutoDelete);
@ -185,8 +185,10 @@ StatEvent::process()
if (flags & Stats::Dump)
DumpNow();
if (flags & Stats::Reset)
if (flags & Stats::Reset) {
cprintf("Resetting stats!\n");
reset();
}
if (repeat)
schedule(curTick + repeat);
@ -214,9 +216,12 @@ DumpNow()
}
void
SetupEvent(int flags, Tick when, Tick repeat)
SetupEvent(int flags, Tick when, Tick repeat, EventQueue *queue)
{
new StatEvent(flags, when, repeat);
if (queue == NULL)
queue = &mainEventQueue;
new StatEvent(queue, flags, when, repeat);
}
/* namespace Stats */ }

View file

@ -34,6 +34,8 @@
#include <fstream>
#include <list>
class EventQueue;
namespace Stats {
enum {
@ -45,7 +47,7 @@ class Output;
extern std::list<Output *> OutputList;
void DumpNow();
void SetupEvent(int flags, Tick when, Tick repeat = 0);
void SetupEvent(int flags, Tick when, Tick repeat = 0, EventQueue *queue = NULL);
void InitSimStats();

View file

@ -182,6 +182,7 @@ class System : public SimObject
std::string kernel_path;
std::string readfile;
std::string symbolfile;
#endif
};

249
util/batch/batch.py Normal file
View file

@ -0,0 +1,249 @@
# Copyright (c) 2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Kevin Lim
import os, popen2, re, sys
class MyPOpen(object):
def __init__(self, cmd, input = None, output = None, bufsize = -1):
self.status = -1
if input is None:
p2c_read, p2c_write = os.pipe()
self.tochild = os.fdopen(p2c_write, 'w', bufsize)
else:
p2c_write = None
if isinstance(input, file):
p2c_read = input.fileno()
elif isinstance(input, str):
input = file(input, 'r')
p2c_read = input.fileno()
elif isinstance(input, int):
p2c_read = input
else:
raise AttributeError
if output is None:
c2p_read, c2p_write = os.pipe()
self.fromchild = os.fdopen(c2p_read, 'r', bufsize)
else:
c2p_read = None
if isinstance(output, file):
c2p_write = output.fileno()
elif isinstance(output, str):
output = file(output, 'w')
c2p_write = output.fileno()
elif isinstance(output, int):
c2p_write = output
else:
raise AttributeError
self.pid = os.fork()
if self.pid == 0:
os.dup2(p2c_read, sys.stdin.fileno())
os.dup2(c2p_write, sys.stdout.fileno())
os.dup2(c2p_write, sys.stderr.fileno())
try:
os.execvp(cmd[0], cmd)
finally:
os._exit(1)
os.close(p2c_read)
os.close(c2p_write)
def poll(self):
if self.status < 0:
pid, status = os.waitpid(self.pid, os.WNOHANG)
if pid == self.pid:
self.status = status
return self.status
def wait(self):
if self.status < 0:
pid, status = os.waitpid(self.pid, 0)
if pid == self.pid:
self.status = status
return self.status
class oarsub:
def __init__(self):
self.walltime = None
self.queue = None
self.properties = None
# OAR 2.0 parameters only!
self.name = None
self.afterok = None
self.notify = None
self.stderr = None
self.stdout = None
self.oarhost = None
self.oarsub = 'oarsub'
self.jobid = re.compile('IdJob = (\S+)')
#self.outfile = open("jobnames.dat", "a+")
def build(self, script, args = []):
self.cmd = [ self.oarsub ]
print "args:", args
print "script:", script
if self.properties:
self.cmd.append('-p"%s"' % self.properties )
if self.queue:
self.cmd.append('-q "%s"' % self.queue)
if self.walltime:
self.cmd.append('-l walltime=%s' % self.walltime)
if script[0] != "/":
self.script = os.getcwd()
else:
self.script = script
self.cmd.extend(args)
self.cmd.append(self.script)
#cmd = [ 'ssh', '-x', self.oarhost, '"cd %s; %s"' % (os.getcwd(), self.command) ]
self.command = ' '.join(self.cmd)
print "command: [%s]" % self.command
def do(self):
oar = MyPOpen(self.cmd)
self.result = oar.fromchild.read()
ec = oar.wait()
if ec != 0 and self.oarhost:
pstdin, pstdout = os.popen4(self.command)
self.result = pstdout.read()
jobid = self.jobid.match(self.result)
if jobid == None:
print "Couldn't get jobid from [%s]" % self.result
sys.exit(1)
else:
#self.outfile.write("%d %s\n" %(int(jobid.group(1)), self.name));
#self.outfile.flush()
self.result = jobid.group(1)
return 0
class qsub:
def __init__(self):
self.afterok = None
self.hold = False
self.join = False
self.keep_stdout = False
self.keep_stderr = False
self.node_type = None
self.mail_abort = False
self.mail_begin = False
self.mail_end = False
self.name = None
self.stdout = None
self.priority = None
self.queue = None
self.pbshost = None
self.qsub = 'qsub'
self.env = {}
def build(self, script, args = []):
self.cmd = [ self.qsub ]
if self.env:
arg = '-v'
arg += ','.join([ '%s=%s' % i for i in self.env.iteritems() ])
self.cmd.append(arg)
if self.hold:
self.cmd.append('-h')
if self.stdout:
self.cmd.append('-olocalhost:' + self.stdout)
if self.keep_stdout and self.keep_stderr:
self.cmd.append('-koe')
elif self.keep_stdout:
self.cmd.append('-ko')
elif self.keep_stderr:
self.cmd.append('-ke')
else:
self.cmd.append('-kn')
if self.join:
self.cmd.append('-joe')
if self.node_type:
self.cmd.append('-lnodes=' + self.node_type)
if self.mail_abort or self.mail_begin or self.mail_end:
flags = ''
if self.mail_abort:
flags.append('a')
if self.mail_begin:
flags.append('b')
if self.mail_end:
flags.append('e')
if len(flags):
self.cmd.append('-m ' + flags)
else:
self.cmd.append('-mn')
if self.name:
self.cmd.append("-N%s" % self.name)
if self.priority:
self.cmd.append('-p' + self.priority)
if self.queue:
self.cmd.append('-q' + self.queue)
if self.afterok:
self.cmd.append('-Wdepend=afterok:%s' % self.afterok)
self.cmd.extend(args)
self.script = script
self.command = ' '.join(self.cmd + [ self.script ])
def do(self):
pbs = MyPOpen(self.cmd + [ self.script ])
self.result = pbs.fromchild.read()
ec = pbs.wait()
if ec != 0 and self.pbshost:
cmd = ' '.join(self.cmd + [ '-' ])
cmd = [ 'ssh', '-x', self.pbshost, cmd ]
self.command = ' '.join(cmd)
ssh = MyPOpen(cmd, input = self.script)
self.result = ssh.fromchild.read()
ec = ssh.wait()
return ec

246
util/batch/job.py Executable file
View file

@ -0,0 +1,246 @@
#!/usr/bin/env python
# Copyright (c) 2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Kevin Lim
import os, os.path, shutil, signal, socket, sys
from os import environ as env
from os.path import join as joinpath, expanduser
def date():
import time
return time.strftime('%a %b %e %H:%M:%S %Z %Y', time.localtime())
def cleandir(dir):
for root, dirs, files in os.walk(dir, False):
for name in files:
os.remove(joinpath(root, name))
for name in dirs:
os.rmdir(joinpath(root, name))
class rsync:
def __init__(self):
self.sudo = False
self.rsync = 'rsync'
self.compress = False
self.archive = True
self.delete = False
self.options = ''
def do(self, src, dst):
args = []
if self.sudo:
args.append('sudo')
args.append(self.rsync)
if (self.archive):
args.append('-a')
if (self.compress):
args.append('-z')
if (self.delete):
args.append('--delete')
if len(self.options):
args.append(self.options)
args.append(src)
args.append(dst)
return os.spawnvp(os.P_WAIT, args[0], args)
class JobDir(object):
def __init__(self, dir):
self.dir = dir
def file(self, filename):
return joinpath(self.dir, filename)
def create(self):
if os.path.exists(self.dir):
if not os.path.isdir(self.dir):
sys.exit('%s is not a directory. Cannot build job' % self.dir)
else:
os.mkdir(self.dir)
def exists(self):
return os.path.isdir(self.dir)
def clean(self):
cleandir(self.dir)
def hasfile(self, filename):
return os.path.isfile(self.file(filename))
def echofile(self, filename, string):
filename = self.file(filename)
try:
f = file(filename, 'w')
print >>f, string
f.flush()
f.close()
except IOError,e:
sys.exit(e)
def rmfile(self, filename):
filename = self.file(filename)
if os.path.isfile(filename):
os.unlink(filename)
def readval(self, filename):
filename = self.file(filename)
f = file(filename, 'r')
value = f.readline().strip()
f.close()
return value
def setstatus(self, string):
filename = self.file('.status')
try:
f = file(filename, 'a')
print >>f, string
f.flush()
f.close()
except IOError,e:
sys.exit(e)
def getstatus(self):
filename = self.file('.status')
try:
f = file(filename, 'r')
except IOError, e:
return 'none'
# fast forward to the end
for line in f: pass
# the first word on the last line is the status
return line.split(' ')[0]
def __str__(self):
return self.dir
if __name__ == '__main__':
import platform
binaries = { 'i686' : 'm5.i386',
'x86_64' : 'm5.amd64' }
binary = binaries[platform.machine()]
cwd = os.getcwd()
rootdir = env.setdefault('ROOTDIR', os.path.dirname(cwd))
oar_jobid = int(env['OAR_JOBID'])
oar_jobname = os.path.basename(cwd)
#pbs_jobname = env['PBS_JOBNAME']
basedir = joinpath(rootdir, 'Base')
jobname = env.setdefault('JOBNAME', oar_jobname)
jobfile = env.setdefault('JOBFILE', joinpath(rootdir, 'Test.py'))
outdir = env.setdefault('OUTPUT_DIR', cwd)
env['POOLJOB'] = 'True'
if os.path.isdir("/work"):
workbase = "/work"
else:
workbase = "/tmp/"
workdir = joinpath(workbase, '%s.%s' % (env['USER'], oar_jobid))
host = socket.gethostname()
os.umask(0022)
jobdir = JobDir(outdir)
started = date()
jobdir.echofile('.running', started)
jobdir.rmfile('.queued')
jobdir.echofile('.host', host)
jobdir.setstatus('running on %s on %s' % (host, started))
if os.path.isdir(workdir):
cleandir(workdir)
else:
os.mkdir(workdir)
if False and os.path.isdir('/z/dist'):
sync = rsync()
sync.delete = True
sync.sudo = True
sync.do('poolfs::dist/m5/', '/z/dist/m5/')
try:
os.chdir(workdir)
except OSError,e:
sys.exit(e)
os.symlink(jobdir.file('output'), 'status.out')
args = [ joinpath(basedir, binary), joinpath(basedir, 'run.py') ]
if not len(args):
sys.exit("no arguments")
print 'starting job... %s' % started
print ' '.join(args)
print
sys.stdout.flush()
childpid = os.fork()
if not childpid:
# Execute command
sys.stdin.close()
fd = os.open(jobdir.file("output"),
os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
os.dup2(fd, sys.stdout.fileno())
os.dup2(fd, sys.stderr.fileno())
os.execvp(args[0], args)
def handler(signum, frame):
if childpid != 0:
os.kill(childpid, signum)
signal.signal(signal.SIGHUP, handler)
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGQUIT, handler)
signal.signal(signal.SIGTERM, handler)
signal.signal(signal.SIGCONT, handler)
signal.signal(signal.SIGUSR1, handler)
signal.signal(signal.SIGUSR2, handler)
done = 0
while not done:
try:
thepid,ec = os.waitpid(childpid, 0)
if ec:
print 'Exit code ', ec
status = 'failure'
else:
status = 'success'
done = 1
except OSError:
pass
complete = date()
print '\njob complete... %s' % complete
jobdir.echofile('.%s' % status, complete)
jobdir.rmfile('.running')
jobdir.setstatus('%s on %s' % (status, complete))

539
util/batch/jobfile.py Normal file
View file

@ -0,0 +1,539 @@
# Copyright (c) 2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Kevin Lim
import sys
class ternary(object):
def __new__(cls, *args):
if len(args) > 1:
raise TypeError, \
'%s() takes at most 1 argument (%d given)' % \
(cls.__name__, len(args))
if args:
if not isinstance(args[0], (bool, ternary)):
raise TypeError, \
'%s() argument must be True, False, or Any' % \
cls.__name__
return args[0]
return super(ternary, cls).__new__(cls)
def __bool__(self):
return True
def __neg__(self):
return self
def __eq__(self, other):
return True
def __ne__(self, other):
return False
def __str__(self):
return 'Any'
def __repr__(self):
return 'Any'
Any = ternary()
class Flags(dict):
def __init__(self, *args, **kwargs):
super(Flags, self).__init__()
self.update(*args, **kwargs)
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
def __setitem__(self, item, value):
return super(Flags, self).__setitem__(item, ternary(value))
def __getitem__(self, item):
if item not in self:
return False
return super(Flags, self).__getitem__(item)
def update(self, *args, **kwargs):
for arg in args:
if isinstance(arg, Flags):
super(Flags, self).update(arg)
elif isinstance(arg, dict):
for key,val in kwargs.iteritems():
self[key] = val
else:
raise AttributeError, \
'flags not of type %s or %s, but %s' % \
(Flags, dict, type(arg))
for key,val in kwargs.iteritems():
self[key] = val
def match(self, *args, **kwargs):
match = Flags(*args, **kwargs)
for key,value in match.iteritems():
if self[key] != value:
return False
return True
def crossproduct(items):
if not isinstance(items, (list, tuple)):
raise AttributeError, 'crossproduct works only on sequences'
if not items:
yield None
return
current = items[0]
remainder = items[1:]
if not hasattr(current, '__iter__'):
current = [ current ]
for item in current:
for rem in crossproduct(remainder):
data = [ item ]
if rem:
data += rem
yield data
def flatten(items):
if not isinstance(items, (list, tuple)):
yield items
return
for item in items:
for flat in flatten(item):
yield flat
class Data(object):
def __init__(self, name, desc, **kwargs):
self.name = name
self.desc = desc
self.system = None
self.flags = Flags()
self.env = {}
for k,v in kwargs.iteritems():
setattr(self, k, v)
def update(self, obj):
if not isinstance(obj, Data):
raise AttributeError, "can only update from Data object"
self.env.update(obj.env)
self.flags.update(obj.flags)
if obj.system:
if self.system and self.system != obj.system:
raise AttributeError, \
"conflicting values for system: '%s'/'%s'" % \
(self.system, obj.system)
self.system = obj.system
def printinfo(self):
if self.name:
print 'name: %s' % self.name
if self.desc:
print 'desc: %s' % self.desc
if self.system:
print 'system: %s' % self.system
def printverbose(self):
print 'flags:'
keys = self.flags.keys()
keys.sort()
for key in keys:
print ' %s = %s' % (key, self.flags[key])
print 'env:'
keys = self.env.keys()
keys.sort()
for key in keys:
print ' %s = %s' % (key, self.env[key])
print
def __str__(self):
return self.name
class Job(Data):
def __init__(self, options):
super(Job, self).__init__('', '')
self.setoptions(options)
self.checkpoint = False
opts = []
for opt in options:
cpt = opt.group.checkpoint
if not cpt:
self.checkpoint = True
continue
if isinstance(cpt, Option):
opt = cpt.clone(suboptions=False)
else:
opt = opt.clone(suboptions=False)
opts.append(opt)
if not opts:
self.checkpoint = False
if self.checkpoint:
self.checkpoint = Job(opts)
def clone(self):
return Job(self.options)
def __getattribute__(self, attr):
if attr == 'name':
names = [ ]
for opt in self.options:
if opt.name:
names.append(opt.name)
return ':'.join(names)
if attr == 'desc':
descs = [ ]
for opt in self.options:
if opt.desc:
descs.append(opt.desc)
return ', '.join(descs)
return super(Job, self).__getattribute__(attr)
def setoptions(self, options):
config = options[0].config
for opt in options:
if opt.config != config:
raise AttributeError, \
"All options are not from the same Configuration"
self.config = config
self.groups = [ opt.group for opt in options ]
self.options = options
self.update(self.config)
for group in self.groups:
self.update(group)
for option in self.options:
self.update(option)
if option._suboption:
self.update(option._suboption)
def printinfo(self):
super(Job, self).printinfo()
if self.checkpoint:
print 'checkpoint: %s' % self.checkpoint.name
print 'config: %s' % self.config.name
print 'groups: %s' % [ g.name for g in self.groups ]
print 'options: %s' % [ o.name for o in self.options ]
super(Job, self).printverbose()
class SubOption(Data):
def __init__(self, name, desc, **kwargs):
super(SubOption, self).__init__(name, desc, **kwargs)
self.number = None
class Option(Data):
def __init__(self, name, desc, **kwargs):
super(Option, self).__init__(name, desc, **kwargs)
self._suboptions = []
self._suboption = None
self.number = None
def __getattribute__(self, attr):
if attr == 'name':
name = self.__dict__[attr]
if self._suboption is not None:
name = '%s:%s' % (name, self._suboption.name)
return name
if attr == 'desc':
desc = [ self.__dict__[attr] ]
if self._suboption is not None and self._suboption.desc:
desc.append(self._suboption.desc)
return ', '.join(desc)
return super(Option, self).__getattribute__(attr)
def suboption(self, name, desc, **kwargs):
subo = SubOption(name, desc, **kwargs)
subo.config = self.config
subo.group = self.group
subo.option = self
subo.number = len(self._suboptions)
self._suboptions.append(subo)
return subo
def clone(self, suboptions=True):
option = Option(self.__dict__['name'], self.__dict__['desc'])
option.update(self)
option.group = self.group
option.config = self.config
option.number = self.number
if suboptions:
option._suboptions.extend(self._suboptions)
option._suboption = self._suboption
return option
def subopts(self):
if not self._suboptions:
return [ self ]
subopts = []
for subo in self._suboptions:
option = self.clone()
option._suboption = subo
subopts.append(option)
return subopts
def printinfo(self):
super(Option, self).printinfo()
print 'config: %s' % self.config.name
super(Option, self).printverbose()
class Group(Data):
def __init__(self, name, desc, **kwargs):
super(Group, self).__init__(name, desc, **kwargs)
self._options = []
self.checkpoint = False
self.number = None
def option(self, name, desc, **kwargs):
opt = Option(name, desc, **kwargs)
opt.config = self.config
opt.group = self
opt.number = len(self._options)
self._options.append(opt)
return opt
def options(self):
return self._options
def subopts(self):
subopts = []
for opt in self._options:
for subo in opt.subopts():
subopts.append(subo)
return subopts
def printinfo(self):
super(Group, self).printinfo()
print 'config: %s' % self.config.name
print 'options: %s' % [ o.name for o in self._options ]
super(Group, self).printverbose()
class Configuration(Data):
def __init__(self, name, desc, **kwargs):
super(Configuration, self).__init__(name, desc, **kwargs)
self._groups = []
self._posfilters = []
self._negfilters = []
def group(self, name, desc, **kwargs):
grp = Group(name, desc, **kwargs)
grp.config = self
grp.number = len(self._groups)
self._groups.append(grp)
return grp
def groups(self, flags=Flags(), sign=True):
if not flags:
return self._groups
return [ grp for grp in self._groups if sign ^ grp.flags.match(flags) ]
def checkchildren(self, kids):
for kid in kids:
if kid.config != self:
raise AttributeError, "child from the wrong configuration"
def sortgroups(self, groups):
groups = [ (grp.number, grp) for grp in groups ]
groups.sort()
return [ grp[1] for grp in groups ]
def options(self, groups = None, checkpoint = False):
if groups is None:
groups = self._groups
self.checkchildren(groups)
groups = self.sortgroups(groups)
if checkpoint:
groups = [ grp for grp in groups if grp.checkpoint ]
optgroups = [ g.options() for g in groups ]
else:
optgroups = [ g.subopts() for g in groups ]
for options in crossproduct(optgroups):
for opt in options:
cpt = opt.group.checkpoint
if not isinstance(cpt, bool) and cpt != opt:
if checkpoint:
break
else:
yield options
else:
if checkpoint:
yield options
def addfilter(self, filt, pos=True):
import re
filt = re.compile(filt)
if pos:
self._posfilters.append(filt)
else:
self._negfilters.append(filt)
def jobfilter(self, job):
for filt in self._negfilters:
if filt.match(job.name):
return False
if not self._posfilters:
return True
for filt in self._posfilters:
if filt.match(job.name):
return True
return False
def checkpoints(self, groups = None):
for options in self.options(groups, True):
job = Job(options)
if self.jobfilter(job):
yield job
def jobs(self, groups = None):
for options in self.options(groups, False):
job = Job(options)
if self.jobfilter(job):
yield job
def alljobs(self, groups = None):
for options in self.options(groups, True):
yield Job(options)
for options in self.options(groups, False):
yield Job(options)
def find(self, jobname):
for job in self.alljobs():
if job.name == jobname:
return job
else:
raise AttributeError, "job '%s' not found" % jobname
def job(self, options):
self.checkchildren(options)
options = [ (opt.group.number, opt) for opt in options ]
options.sort()
options = [ opt[1] for opt in options ]
job = Job(options)
return job
def printinfo(self):
super(Configuration, self).printinfo()
print 'groups: %s' % [ g.name for g in self._grouips ]
super(Configuration, self).printverbose()
def JobFile(jobfile):
from os.path import expanduser, isfile, join as joinpath
filename = expanduser(jobfile)
# Can't find filename in the current path, search sys.path
if not isfile(filename):
for path in sys.path:
testname = joinpath(path, filename)
if isfile(testname):
filename = testname
break
else:
raise AttributeError, \
"Could not find file '%s'" % jobfile
data = {}
execfile(filename, data)
if 'conf' not in data:
raise ImportError, 'cannot import name conf from %s' % jobfile
conf = data['conf']
import jobfile
if not isinstance(conf, Configuration):
raise AttributeError, \
'conf in jobfile: %s (%s) is not type %s' % \
(jobfile, type(conf), Configuration)
return conf
if __name__ == '__main__':
from jobfile import *
import sys
usage = 'Usage: %s [-b] [-c] [-v] <jobfile>' % sys.argv[0]
try:
import getopt
opts, args = getopt.getopt(sys.argv[1:], '-bcv')
except getopt.GetoptError:
sys.exit(usage)
if len(args) != 1:
raise AttributeError, usage
both = False
checkpoint = False
verbose = False
for opt,arg in opts:
if opt == '-b':
both = True
checkpoint = True
if opt == '-c':
checkpoint = True
if opt == '-v':
verbose = True
jobfile = args[0]
conf = JobFile(jobfile)
if both:
gen = conf.alljobs()
elif checkpoint:
gen = conf.checkpoints()
else:
gen = conf.jobs()
for job in gen:
if not verbose:
cpt = ''
if job.checkpoint:
cpt = job.checkpoint.name
print job.name, cpt
else:
job.printinfo()

306
util/batch/send.py Executable file
View file

@ -0,0 +1,306 @@
#!/usr/bin/env python
# Copyright (c) 2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Kevin Lim
import os, os.path, re, socket, sys
from os import environ as env, listdir
from os.path import basename, isdir, isfile, islink, join as joinpath, normpath
from filecmp import cmp as filecmp
from shutil import copy
def nfspath(dir):
if dir.startswith('/.automount/'):
dir = '/n/%s' % dir[12:]
elif not dir.startswith('/n/'):
dir = '/n/%s%s' % (socket.gethostname().split('.')[0], dir)
return dir
def syncdir(srcdir, destdir):
srcdir = normpath(srcdir)
destdir = normpath(destdir)
if not isdir(destdir):
sys.exit('destination directory "%s" does not exist' % destdir)
for root, dirs, files in os.walk(srcdir):
root = normpath(root)
prefix = os.path.commonprefix([root, srcdir])
root = root[len(prefix):]
if root.startswith('/'):
root = root[1:]
for rem in [ d for d in dirs if d.startswith('.') or d == 'SCCS']:
dirs.remove(rem)
for entry in dirs:
newdir = joinpath(destdir, root, entry)
if not isdir(newdir):
os.mkdir(newdir)
print 'mkdir', newdir
for i,d in enumerate(dirs):
if islink(joinpath(srcdir, root, d)):
dirs[i] = joinpath(d, '.')
for entry in files:
dest = normpath(joinpath(destdir, root, entry))
src = normpath(joinpath(srcdir, root, entry))
if not isfile(dest) or not filecmp(src, dest):
print 'copy %s %s' % (dest, src)
copy(src, dest)
progpath = nfspath(sys.path[0])
progname = basename(sys.argv[0])
usage = """\
Usage:
%(progname)s [-c] [-e] [-f] [-j <jobfile>] [-q queue] [-v] <regexp>
-c clean directory if job can be run
-C submit the checkpointing runs
-d Make jobs be dependent on the completion of the checkpoint runs
-e only echo pbs command info, don't actually send the job
-f force the job to run regardless of state
-q <queue> submit job to the named queue
-j <jobfile> specify the jobfile (default is <rootdir>/Test.py)
-v be verbose
%(progname)s [-j <jobfile>] -l [-v] <regexp>
-j <jobfile> specify the jobfile (default is <rootdir>/Test.py)
-l list job names, don't submit
-v be verbose (list job parameters)
%(progname)s -h
-h display this help
""" % locals()
try:
import getopt
opts, args = getopt.getopt(sys.argv[1:], '-Ccdefhj:lnq:Rt:v')
except getopt.GetoptError:
sys.exit(usage)
depend = False
clean = False
onlyecho = False
exprs = []
force = False
listonly = False
queue = ''
verbose = False
jfile = 'Test.py'
docpts = False
doruns = True
runflag = False
node_type = 'FAST'
update = True
for opt,arg in opts:
if opt == '-C':
docpts = True
if opt == '-c':
clean = True
if opt == '-d':
depend = True
if opt == '-e':
onlyecho = True
if opt == '-f':
force = True
if opt == '-h':
print usage
sys.exit(0)
if opt == '-j':
jfile = arg
if opt == '-l':
listonly = True
if opt == '-n':
update = False
if opt == '-q':
queue = arg
if opt == '-R':
runflag = True
if opt == '-t':
node_type = arg
if opt == '-v':
verbose = True
if docpts:
doruns = runflag
for arg in args:
exprs.append(re.compile(arg))
import jobfile, batch
from job import JobDir, date
conf = jobfile.JobFile(jfile)
if update and not listonly and not onlyecho and isdir(conf.linkdir):
if verbose:
print 'Checking for outdated files in Link directory'
if not isdir(conf.basedir):
os.mkdir(conf.basedir)
syncdir(conf.linkdir, conf.basedir)
jobnames = {}
joblist = []
if docpts and doruns:
gen = conf.alljobs()
elif docpts:
gen = conf.checkpoints()
elif doruns:
gen = conf.jobs()
for job in gen:
if job.name in jobnames:
continue
if exprs:
for expr in exprs:
if expr.match(job.name):
joblist.append(job)
break
else:
joblist.append(job)
if listonly:
if verbose:
for job in joblist:
job.printinfo()
else:
for job in joblist:
print job.name
sys.exit(0)
if not onlyecho:
newlist = []
for job in joblist:
jobdir = JobDir(joinpath(conf.rootdir, job.name))
if jobdir.exists():
if not force:
status = jobdir.getstatus()
if status == 'queued':
continue
if status == 'running':
continue
if status == 'success':
continue
if not clean:
sys.exit('job directory %s not clean!' % jobdir)
jobdir.clean()
newlist.append(job)
joblist = newlist
class NameHack(object):
def __init__(self, host='pbs.pool', port=24465):
self.host = host
self.port = port
self.socket = None
def setname(self, jobid, jobname):
try:
jobid = int(jobid)
except ValueError:
jobid = int(jobid.strip().split('.')[0])
jobname = jobname.strip()
# since pbs can handle jobnames of 15 characters or less,
# don't use the raj hack.
if len(jobname) <= 15:
return
if self.socket is None:
import socket
self.socket = socket.socket()
# Connect to pbs.pool and send the jobid/jobname pair to port
# 24465 (Raj didn't realize that there are only 64k ports and
# setup inetd to point to port 90001)
self.socket.connect((self.host, self.port))
self.socket.send("%s %s\n" % (jobid, jobname))
namehack = NameHack()
rootdir = conf.rootdir
script = joinpath(rootdir, 'Base', 'job.py')
for job in joblist:
jobdir = JobDir(joinpath(rootdir, job.name))
if depend:
cptdir = JobDir(joinpath(rootdir, job.checkpoint.name))
path = str(cptdir)
if not isdir(path) or not isfile(joinpath(path, '.success')):
continue
cptjob = cptdir.readval('.batch_jobid')
if not onlyecho:
jobdir.create()
os.chdir(str(jobdir))
os.environ['PWD'] = str(jobdir)
print 'Job name: %s' % job.name
print 'Job directory: %s' % jobdir
qsub = batch.oarsub()
qsub.oarhost = 'poolfs.eecs.umich.edu'
#qsub.stdout = jobdir.file('jobout')
qsub.name = job.name
qsub.walltime = '50'
#qsub.join = True
#qsub.node_type = node_type
#qsub.env['ROOTDIR'] = conf.rootdir
#qsub.env['JOBNAME'] = job.name
#if depend:
# qsub.afterok = cptjob
#if queue:
# qsub.queue = queue
qsub.properties = "64bit = 'Yes' or 64bit = 'No'"
qsub.build(script)
if verbose:
print 'cwd: %s' % qsub.command
print 'PBS Command: %s' % qsub.command
if not onlyecho:
ec = qsub.do()
if ec == 0:
jobid = qsub.result
print 'OAR Jobid: %s' % jobid
#namehack.setname(jobid, job.name)
queued = date()
jobdir.echofile('.batch_jobid', jobid)
jobdir.echofile('.batch_jobname', job.name)
jobdir.echofile('.queued', queued)
jobdir.setstatus('queued on %s' % queued)
else:
print 'OAR Failed'
print
print

View file

@ -169,6 +169,22 @@ main(int argc, char *argv[])
}
}
if (COMPARE("readfile")) {
char buf[256*1024];
int offset = 0;
int len;
if (argc != 2)
usage();
while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
write(STDOUT_FILENO, buf, len);
offset += len;
}
return 0;
}
if (COMPARE("checkpoint")) {
switch (argc) {
case 4:
@ -186,6 +202,9 @@ main(int argc, char *argv[])
return 0;
}
if (COMPARE("loadsymbol")) {
m5_loadsymbol(arg1);
return 0;
if (COMPARE("readfile")) {
char buf[256*1024];
int offset = 0;

View file

@ -41,6 +41,7 @@
#define exit_old_func 0x20 // deprectated!
#define exit_func 0x21
#define initparam_func 0x30
#define loadsymbol_func 0x31
#define resetstats_func 0x40
#define dumpstats_func 0x41
#define dumprststats_func 0x42
@ -77,6 +78,7 @@ func:
#define IVLE(reg) INST(m5_op, reg, 0, ivle_func)
#define M5EXIT(reg) INST(m5_op, reg, 0, exit_func)
#define INITPARAM(reg) INST(m5_op, reg, 0, initparam_func)
#define LOADSYMBOL(reg) INST(m5_op, reg, 0, loadsymbol_func)
#define RESET_STATS(r1, r2) INST(m5_op, r1, r2, resetstats_func)
#define DUMP_STATS(r1, r2) INST(m5_op, r1, r2, dumpstats_func)
#define DUMPRST_STATS(r1, r2) INST(m5_op, r1, r2, dumprststats_func)
@ -146,6 +148,12 @@ LEAF(m5_initparam)
RET
END(m5_initparam)
.align 4
LEAF(m5_loadsymbol)
LOADSYMBOL(0)
RET
END(m5_loadsymbol)
.align 4
LEAF(m5_reset_stats)
RESET_STATS(16, 17)